summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorKarel Kočí <karel.koci@nic.cz>2020-07-02 12:49:56 +0200
committerPetr Štetiar <ynezz@true.cz>2020-07-11 15:01:29 +0200
commit3d9bd73e8c2d8a1f78effbe92dd2495bbd2552c4 (patch)
tree2284f7a464cee8d0067ac85bee7fd573f4798a27
parent51e9fb8151e8f2c16ac1400bf4d64147ee7e8f5a (diff)
utils: fix check_pid_path to work with deleted file as well
check_pid_patch is checking if process with given PID and executable path is running. If this code fails the rest of the code can be convinced that program is no longer running and possibly spawns new instance that can collide with already running one. This behavior was reproduced with hostapd. Symbolic link exe in process subdirectory in /proc points to original executable. The problem is that it reads as original path plus string ' (deleted)' if file is removed. The process is still running but original file is no longer available on files system. This behavior is triggered not only when file is removed (unlinked) but also when file is replaced. This happens clearly on package update. In general this happens any time all references (hard links) to file are removed from file system. This is not ultimate fix as exe link points to any last reference on file system with preference for original one. The problem is if there are multiple references and the original one is removed. This can be reproduced just by copying executable (hard linking) and unlinking the original one. In such case exe link would point to copy and not to original deleted one. Signed-off-by: Karel Kočí <karel.koci@nic.cz>
-rw-r--r--utils.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/utils.c b/utils.c
index ba26952..4f40b4b 100644
--- a/utils.c
+++ b/utils.c
@@ -176,6 +176,8 @@ crc32_file(FILE *fp)
bool check_pid_path(int pid, const char *exe)
{
+ const char deleted[] = " (deleted)";
+ const int deleted_len = strlen(deleted);
int proc_exe_len;
int exe_len = strlen(exe);
@@ -191,10 +193,13 @@ bool check_pid_path(int pid, const char *exe)
proc_exe_len = readlink(proc_exe, proc_exe_buf, exe_len);
#endif
- if (proc_exe_len != exe_len)
+ if (proc_exe_len == exe_len)
+ return !memcmp(exe, proc_exe_buf, exe_len);
+ else if (proc_exe_len == exe_len + deleted_len)
+ return !memcmp(exe, proc_exe_buf, exe_len) &&
+ !memcmp(exe + exe_len, deleted, deleted_len);
+ else
return false;
-
- return !memcmp(exe, proc_exe_buf, exe_len);
}
static const char * const uci_validate_name[__BLOBMSG_TYPE_LAST] = {