start-stop-daemon uses stat to match running binaries.
This is not good as the binary in question could be moved or deleted during an
upgrade.
This patch instead checks how the daemon was started and mirrors how Gentoo's
start-stop-daemon implementation works.
Thanks
Roy
diff -ur a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c
--- a/debianutils/start_stop_daemon.c 2008-04-30 11:23:22.000000000 +0100
+++ b/debianutils/start_stop_daemon.c 2008-04-30 11:37:45.000000000 +0100
@@ -54,22 +54,67 @@
static int pid_is_exec(pid_t pid, const char *name)
{
- char buf[sizeof("/proc//exe") + sizeof(int)*3];
- char *execbuf;
- int n;
-
- sprintf(buf, "/proc/%u/exe", pid);
- n = strlen(name) + 1;
- execbuf = xzalloc(n + 1);
- readlink(buf, execbuf, n);
- /* if readlink fails because link target is longer than strlen(name),
- * execbuf still contains "", and strcmp will return !0. */
- n = strcmp(execbuf, name);
- if (ENABLE_FEATURE_CLEAN_UP)
- free(execbuf);
- return !n; /* nonzero (true) if execbuf == name */
+ char cmdline[32];
+ char buffer[PATH_MAX];
+ char *p;
+ int fd = -1;
+ int r;
+
+ /* Check it's the right binary */
+ snprintf(cmdline, sizeof(cmdline), "/proc/%u/exe", pid);
+ memset(buffer, 0, sizeof(buffer));
+ if (readlink(cmdline, buffer, sizeof(buffer)) != -1) {
+ if (strcmp(buffer, name) == 0)
+ return 1;
+
+ /* We should cater for deleted binaries too */
+ if (strlen(buffer) > 10) {
+ p = buffer + (strlen(buffer) - 10);
+ if (strcmp(p, " (deleted)") == 0) {
+ *p = '\0';
+ if (strcmp(buffer, name) == 0)
+ return 1;
+ }
+ }
+ }
+
+ snprintf(cmdline, sizeof(cmdline), "/proc/%u/cmdline", pid);
+ if ((fd = open(cmdline, O_RDONLY)) >= 0) {
+ r = read(fd, buffer, sizeof(buffer));
+ close(fd);
+ if (r != -1) {
+ buffer[r] = '\0';
+ if (strcmp(buffer, name) == 0)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+static int pid_is_cmd(pid_t pid, const char *cmd)
+{
+ char buffer[32];
+ FILE *fp;
+ int c;
+ int retval = 0;
+
+ snprintf(buffer, sizeof(buffer), "/proc/%d/stat", pid);
+ if ((fp = fopen(buffer, "r"))) {
+ while ((c = getc(fp)) != EOF && c != '(')
+ ;
+ if (c == '(') {
+ while ((c = getc(fp)) != EOF && c == *cmd)
+ cmd++;
+ if (c == ')' && *cmd == '\0')
+ retval = 1;
+ }
+ fclose(fp);
+ }
+ return retval;
}
+
static int pid_is_user(int pid, int uid)
{
struct stat sb;
@@ -81,28 +126,6 @@
return (sb.st_uid == uid);
}
-static int pid_is_cmd(pid_t pid, const char *name)
-{
- char fname[sizeof("/proc//stat") + sizeof(int)*3];
- char *buf;
- int r = 0;
-
- sprintf(fname, "/proc/%u/stat", pid);
- buf = xmalloc_open_read_close(fname, NULL);
- if (buf) {
- char *p = strchr(buf, '(');
- if (p) {
- char *pe = strrchr(++p, ')');
- if (pe) {
- *pe = '\0';
- r = !strcmp(p, name);
- }
- }
- free(buf);
- }
- return r;
-}
-
static void check(int pid)
{
struct pid_list *p;
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox