aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2006-12-17 17:30:01 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2006-12-17 17:30:01 +0000
commita995f86684384786b0fd45d13e413bcdfbf5d4c2 (patch)
tree2f6450c7a7822e635c31acdfceaaec5f6c95d0de
parent7dab4dcd89e794d385133f721d825f845f7d30c6 (diff)
downloadbusybox-w32-a995f86684384786b0fd45d13e413bcdfbf5d4c2.tar.gz
busybox-w32-a995f86684384786b0fd45d13e413bcdfbf5d4c2.tar.bz2
busybox-w32-a995f86684384786b0fd45d13e413bcdfbf5d4c2.zip
start_stop_daemon: fix bug where any program name was "matching"
processes for which readlink(/proc/N/exe) fails git-svn-id: svn://busybox.net/trunk/busybox@16982 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--debianutils/start_stop_daemon.c63
-rw-r--r--libbb/read.c7
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
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 }
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;