diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-12-17 17:30:01 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-12-17 17:30:01 +0000 |
| commit | b131b271a0d89b1ff04fd721530f424d0a15f0b2 (patch) | |
| tree | 2f6450c7a7822e635c31acdfceaaec5f6c95d0de | |
| parent | 7cdc54ff59697fe42048b06a3b4ed956bb7f0b3f (diff) | |
| download | busybox-w32-b131b271a0d89b1ff04fd721530f424d0a15f0b2.tar.gz busybox-w32-b131b271a0d89b1ff04fd721530f424d0a15f0b2.tar.bz2 busybox-w32-b131b271a0d89b1ff04fd721530f424d0a15f0b2.zip | |
start_stop_daemon: fix bug where any program name was "matching"
processes for which readlink(/proc/N/exe) fails
| -rw-r--r-- | debianutils/start_stop_daemon.c | 63 | ||||
| -rw-r--r-- | libbb/read.c | 7 |
2 files changed, 40 insertions, 30 deletions
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index f52352995..399f9f5e1 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c | |||
| @@ -26,7 +26,7 @@ struct pid_list { | |||
| 26 | pid_t pid; | 26 | pid_t pid; |
| 27 | }; | 27 | }; |
| 28 | 28 | ||
| 29 | static struct pid_list *found = NULL; | 29 | static struct pid_list *found; |
| 30 | 30 | ||
| 31 | static inline void push(pid_t pid) | 31 | static inline void push(pid_t pid) |
| 32 | { | 32 | { |
| @@ -42,13 +42,16 @@ static int pid_is_exec(pid_t pid, const char *name) | |||
| 42 | { | 42 | { |
| 43 | char buf[sizeof("/proc//exe") + sizeof(int)*3]; | 43 | char buf[sizeof("/proc//exe") + sizeof(int)*3]; |
| 44 | char *execbuf; | 44 | char *execbuf; |
| 45 | int sz; | ||
| 45 | int equal; | 46 | int equal; |
| 46 | 47 | ||
| 47 | sprintf(buf, "/proc/%d/exe", pid); | 48 | sprintf(buf, "/proc/%d/exe", pid); |
| 48 | execbuf = xstrdup(name); | 49 | sz = strlen(name) + 1; |
| 49 | readlink(buf, execbuf, strlen(name)+1); | 50 | execbuf = xzalloc(sz); |
| 51 | readlink(buf, execbuf, sz); | ||
| 50 | 52 | ||
| 51 | equal = ! strcmp(execbuf, name); | 53 | /* if readlink fails, execbuf still contains "" */ |
| 54 | equal = !strcmp(execbuf, name); | ||
| 52 | if (ENABLE_FEATURE_CLEAN_UP) | 55 | if (ENABLE_FEATURE_CLEAN_UP) |
| 53 | free(execbuf); | 56 | free(execbuf); |
| 54 | return equal; | 57 | return equal; |
| @@ -59,7 +62,7 @@ static int pid_is_user(int pid, int uid) | |||
| 59 | struct stat sb; | 62 | struct stat sb; |
| 60 | char buf[sizeof("/proc/") + sizeof(int)*3]; | 63 | char buf[sizeof("/proc/") + sizeof(int)*3]; |
| 61 | 64 | ||
| 62 | sprintf(buf, "/proc/%d", pid); | 65 | sprintf(buf, "/proc/%u", pid); |
| 63 | if (stat(buf, &sb) != 0) | 66 | if (stat(buf, &sb) != 0) |
| 64 | return 0; | 67 | return 0; |
| 65 | return (sb.st_uid == uid); | 68 | return (sb.st_uid == uid); |
| @@ -67,25 +70,24 @@ static int pid_is_user(int pid, int uid) | |||
| 67 | 70 | ||
| 68 | static int pid_is_cmd(pid_t pid, const char *name) | 71 | static int pid_is_cmd(pid_t pid, const char *name) |
| 69 | { | 72 | { |
| 70 | char buf[sizeof("/proc//stat") + sizeof(int)*3]; | 73 | char fname[sizeof("/proc//stat") + sizeof(int)*3]; |
| 71 | FILE *f; | 74 | char *buf; |
| 72 | int c; | 75 | int r = 0; |
| 73 | 76 | ||
| 74 | sprintf(buf, "/proc/%d/stat", pid); | 77 | sprintf(fname, "/proc/%u/stat", pid); |
| 75 | f = fopen(buf, "r"); | 78 | buf = xmalloc_open_read_close(fname, NULL); |
| 76 | if (!f) | 79 | if (buf) { |
| 77 | return 0; | 80 | char *p = strchr(buf, '('); |
| 78 | while ((c = getc(f)) != EOF && c != '(') | 81 | if (p) { |
| 79 | ; | 82 | char *pe = strrchr(++p, ')'); |
| 80 | if (c != '(') { | 83 | if (pe) { |
| 81 | fclose(f); | 84 | *pe = '\0'; |
| 82 | return 0; | 85 | r = !strcmp(p, name); |
| 86 | } | ||
| 87 | } | ||
| 88 | free(buf); | ||
| 83 | } | 89 | } |
| 84 | /* this hopefully handles command names containing ')' */ | 90 | return r; |
| 85 | while ((c = getc(f)) != EOF && c == *name) | ||
| 86 | name++; | ||
| 87 | fclose(f); | ||
| 88 | return (c == ')' && *name == '\0'); | ||
| 89 | } | 91 | } |
| 90 | 92 | ||
| 91 | 93 | ||
| @@ -111,7 +113,7 @@ static void do_pidfile(void) | |||
| 111 | 113 | ||
| 112 | f = fopen(pidfile, "r"); | 114 | f = fopen(pidfile, "r"); |
| 113 | if (f) { | 115 | if (f) { |
| 114 | if (fscanf(f, "%d", &pid) == 1) | 116 | if (fscanf(f, "%u", &pid) == 1) |
| 115 | check(pid); | 117 | check(pid); |
| 116 | fclose(f); | 118 | fclose(f); |
| 117 | } else if (errno != ENOENT) | 119 | } else if (errno != ENOENT) |
| @@ -133,7 +135,8 @@ static void do_procinit(void) | |||
| 133 | 135 | ||
| 134 | foundany = 0; | 136 | foundany = 0; |
| 135 | while ((entry = readdir(procdir)) != NULL) { | 137 | while ((entry = readdir(procdir)) != NULL) { |
| 136 | if (sscanf(entry->d_name, "%d", &pid) != 1) | 138 | pid = bb_strtou(entry->d_name, NULL, 10); |
| 139 | if (errno) | ||
| 137 | continue; | 140 | continue; |
| 138 | foundany++; | 141 | foundany++; |
| 139 | check(pid); | 142 | check(pid); |
| @@ -269,8 +272,11 @@ int start_stop_daemon_main(int argc, char **argv) | |||
| 269 | argc -= optind; | 272 | argc -= optind; |
| 270 | argv += optind; | 273 | argv += optind; |
| 271 | 274 | ||
| 272 | if (userspec && sscanf(userspec, "%d", &user_id) != 1) | 275 | if (userspec) { |
| 273 | user_id = bb_xgetpwnam(userspec); | 276 | user_id = bb_strtou(userspec, NULL, 10); |
| 277 | if (errno) | ||
| 278 | user_id = bb_xgetpwnam(userspec); | ||
| 279 | } | ||
| 274 | 280 | ||
| 275 | if (opt & SSD_CTX_STOP) { | 281 | if (opt & SSD_CTX_STOP) { |
| 276 | int i = do_stop(); | 282 | int i = do_stop(); |
| @@ -301,7 +307,8 @@ int start_stop_daemon_main(int argc, char **argv) | |||
| 301 | fclose(pidf); | 307 | fclose(pidf); |
| 302 | } | 308 | } |
| 303 | if (chuid) { | 309 | if (chuid) { |
| 304 | if (sscanf(chuid, "%d", &user_id) != 1) | 310 | user_id = bb_strtou(chuid, NULL, 10); |
| 311 | if (errno) | ||
| 305 | user_id = bb_xgetpwnam(chuid); | 312 | user_id = bb_xgetpwnam(chuid); |
| 306 | xsetuid(user_id); | 313 | xsetuid(user_id); |
| 307 | } | 314 | } |
diff --git a/libbb/read.c b/libbb/read.c index b3648b4d7..50e0354ad 100644 --- a/libbb/read.c +++ b/libbb/read.c | |||
| @@ -118,16 +118,19 @@ void *xmalloc_open_read_close(const char *filename, size_t *sizep) | |||
| 118 | char *buf; | 118 | char *buf; |
| 119 | size_t size = sizep ? *sizep : INT_MAX; | 119 | size_t size = sizep ? *sizep : INT_MAX; |
| 120 | int fd = xopen(filename, O_RDONLY); | 120 | int fd = xopen(filename, O_RDONLY); |
| 121 | off_t len = xlseek(fd, 0, SEEK_END); | 121 | /* /proc/N/stat files report len 0 here */ |
| 122 | /* In order to make such files readable, we add small const */ | ||
| 123 | off_t len = xlseek(fd, 0, SEEK_END) + 256; | ||
| 122 | xlseek(fd, 0, SEEK_SET); | 124 | xlseek(fd, 0, SEEK_SET); |
| 123 | 125 | ||
| 124 | if (len > size) | 126 | if (len > size) |
| 125 | bb_error_msg_and_die("file '%s' is too big", filename); | 127 | bb_error_msg_and_die("file '%s' is too big", filename); |
| 126 | size = len; | 128 | size = len; |
| 127 | buf = xmalloc(size+1); | 129 | buf = xmalloc(size + 1); |
| 128 | size = read_close(fd, buf, size); | 130 | size = read_close(fd, buf, size); |
| 129 | if ((ssize_t)size < 0) | 131 | if ((ssize_t)size < 0) |
| 130 | bb_perror_msg_and_die("'%s'", filename); | 132 | bb_perror_msg_and_die("'%s'", filename); |
| 133 | xrealloc(buf, size + 1); | ||
| 131 | buf[size] = '\0'; | 134 | buf[size] = '\0'; |
| 132 | if (sizep) *sizep = size; | 135 | if (sizep) *sizep = size; |
| 133 | return buf; | 136 | return buf; |
