aboutsummaryrefslogtreecommitdiff
path: root/debianutils
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-12-17 17:30:01 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-12-17 17:30:01 +0000
commitb131b271a0d89b1ff04fd721530f424d0a15f0b2 (patch)
tree2f6450c7a7822e635c31acdfceaaec5f6c95d0de /debianutils
parent7cdc54ff59697fe42048b06a3b4ed956bb7f0b3f (diff)
downloadbusybox-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
Diffstat (limited to 'debianutils')
-rw-r--r--debianutils/start_stop_daemon.c63
1 files changed, 35 insertions, 28 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
29static struct pid_list *found = NULL; 29static struct pid_list *found;
30 30
31static inline void push(pid_t pid) 31static 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
68static int pid_is_cmd(pid_t pid, const char *name) 71static 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 }