--- libinit.c +++ libinit.c 2011-04-06 13:21:49.212425737 +0000 @@ -349,18 +349,24 @@ static int find_mount(const char * path, { const size_t nlen = strlen(path); list_t *ptr; + int ret = 0; list_for_each(ptr, &mounts) { MNTINFO *m = list_entry(ptr, MNTINFO); if (nlen < m->nlen) continue; - if (m->nlen == 1) /* root fs is the last entry */ - return (m == s); + if (m->nlen == 1 && (m == s)) { /* root fs is the last entry */ + ret++; + break; + } if (strncmp(path, m->point, m->nlen)) continue; - return (m == s); + if (m == s) { + ret++; + break; + } } - return 0; + return ret; } extern inline char * handl_buf(char *restrict buf) @@ -669,6 +675,7 @@ int pidof (const char * inname, const ch boolean isscrpt = false; unsigned num = 0; pid_t pid; + uid_t uid; char *swapname = NULL; char *fullname = (char *)inname; char *realname = NULL; @@ -677,6 +684,7 @@ int pidof (const char * inname, const ch p_pid = getpid(); p_ppid = getppid(); + uid = getuid(); dir = openproc(); /* Open /proc and maybe do mount before */ p_pppid = getpppid(p_ppid); /* Requires existence of /proc */ @@ -773,6 +781,13 @@ int pidof (const char * inname, const ch if (prefix) { if ((rll = readlinkat(dfd, here(d->d_name, "exe"), entry, PATH_MAX)) < 0) { + if (uid && (errno == EACCES || errno == EPERM)) { + errno = 0; + if (fstatat(dfd, d->d_name, &pid_st, 0) < 0) + continue; + if (pid_st.st_uid == uid) + goto risky; + } if (errno != EPERM && errno != EACCES) goto risky; continue; @@ -809,6 +824,13 @@ int pidof (const char * inname, const ch if (!name) { if ((rll = readlinkat(dfd, here(d->d_name, "exe"), entry, PATH_MAX)) < 0) { + if (uid && (errno == EACCES || errno == EPERM)) { + errno = 0; + if (fstatat(dfd, d->d_name, &pid_st, 0) < 0) + continue; + if (pid_st.st_uid == uid) + goto risky; + } if (errno != EPERM && errno != EACCES) goto risky; continue; @@ -825,7 +847,6 @@ int pidof (const char * inname, const ch if (realname && strncmp(realname, name, PATH_MAX) == 0) found = true; - break; } @@ -942,12 +963,15 @@ int verify_pidfile (const char * pid_fil ssize_t cnt; boolean isscrpt = false; pid_t pid; + uid_t uid; char *swapname = NULL, *bufp; char *fullname = (char *)inname; char *realname = NULL; struct stat pid_st, full_st; char buf[BUFSIZ]; + uid = getuid(); + if (!ignore) { list_t *m, *n; list_for_each_safe(m, n, &remember) { @@ -1041,14 +1065,23 @@ int verify_pidfile (const char * pid_fil } errno = 0; - if (!(flags & (KTHREAD|KSHORT)) && !isscrpt && - (stat(proc(buf, "exe"), &pid_st) == 0)) { - + if (!(flags & (KTHREAD|KSHORT)) && !isscrpt) { char entry[PATH_MAX+1]; const char *name; boolean found; ssize_t rll; + if (stat(proc(buf, "exe"), &pid_st) < 0) { + if (uid && (errno == EACCES || errno == EPERM)) { + errno = 0; + if (stat(proc(buf, ""), &pid_st) < 0) + goto out; + if (pid_st.st_uid == uid) + goto risky; + } + goto out; + } + if (pid_st.st_dev != full_st.st_dev) goto out; @@ -1087,6 +1120,7 @@ int verify_pidfile (const char * pid_fil goto out; } +risky: if (errno && errno != ENOENT) { warn("Can not read %s: %s\n", procbuf, strerror(errno)); @@ -1162,8 +1196,11 @@ int check_pids (const char * inname, con const char *pid; struct stat pid_st, full_st; list_t *m, *n; + uid_t uid; int fp; + uid = getuid(); + if (!fullname) { warn("program or process name required\n"); return -1; @@ -1228,13 +1265,22 @@ int check_pids (const char * inname, con /* killproc and daemon/startproc should use the full path */ errno = 0; - if (!(flags & (KTHREAD|KSHORT)) && !isscrpt && - (stat(proc(pid, "exe"), &pid_st) == 0)) { - + if (!(flags & (KTHREAD|KSHORT)) && !isscrpt) { char entry[PATH_MAX+1]; const char *name; ssize_t rll; + if (stat(proc(pid, "exe"), &pid_st) < 0) { + if (uid && (errno == EACCES || errno == EPERM)) { + errno = 0; + if (stat(proc(pid, ""), &pid_st) < 0) + goto ignore; + if (pid_st.st_uid == uid) + goto risky; + } + goto ignore; + } + if (pid_st.st_dev != full_st.st_dev) goto ignore; /* Does not belong to rembered list */ @@ -1267,6 +1313,7 @@ int check_pids (const char * inname, con skip = true; /* No stat entry check needed */ } +risky: if (!(flags & (KTHREAD|KSHORT)) && isscrpt && (fp = open(proc(pid, "cmdline"), O_PROCMODE)) != -1) { --- libinit.h +++ libinit.h 2011-04-15 14:43:35.083926074 +0000 @@ -91,7 +91,7 @@ #define WRGSYNTAX 102 /* usage etc. */ #define NOPIDREAD 101 /* trouble */ -#define LSB_STATUS_PROOF ((errno == EPERM || errno == EACCES) ? LSB_NOPERM : NOPIDREAD ) +#define LSB_STATUS_PROOF ((errno == EPERM || errno == EACCES) ? LSB_NOPERM : LSB_STATUS_ISDEAD ) #define LSB_STATUS_PROOFX ((errno == ENOENT) ? (flags & KILL) ? LSB_NOENTR : 4 : LSB_STATUS_PROOF ) #define LOG_OPTIONS (LOG_ODELAY|LOG_CONS)