mirror of
https://github.com/sheumann/hush.git
synced 2025-01-03 00:31:16 +00:00
start_stop_daemon: fix bug where any program name was "matching"
processes for which readlink(/proc/N/exe) fails
This commit is contained in:
parent
7cdc54ff59
commit
b131b271a0
@ -26,7 +26,7 @@ struct pid_list {
|
|||||||
pid_t pid;
|
pid_t pid;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct pid_list *found = NULL;
|
static struct pid_list *found;
|
||||||
|
|
||||||
static inline void push(pid_t pid)
|
static inline void push(pid_t pid)
|
||||||
{
|
{
|
||||||
@ -42,12 +42,15 @@ static int pid_is_exec(pid_t pid, const char *name)
|
|||||||
{
|
{
|
||||||
char buf[sizeof("/proc//exe") + sizeof(int)*3];
|
char buf[sizeof("/proc//exe") + sizeof(int)*3];
|
||||||
char *execbuf;
|
char *execbuf;
|
||||||
|
int sz;
|
||||||
int equal;
|
int equal;
|
||||||
|
|
||||||
sprintf(buf, "/proc/%d/exe", pid);
|
sprintf(buf, "/proc/%d/exe", pid);
|
||||||
execbuf = xstrdup(name);
|
sz = strlen(name) + 1;
|
||||||
readlink(buf, execbuf, strlen(name)+1);
|
execbuf = xzalloc(sz);
|
||||||
|
readlink(buf, execbuf, sz);
|
||||||
|
|
||||||
|
/* if readlink fails, execbuf still contains "" */
|
||||||
equal = !strcmp(execbuf, name);
|
equal = !strcmp(execbuf, name);
|
||||||
if (ENABLE_FEATURE_CLEAN_UP)
|
if (ENABLE_FEATURE_CLEAN_UP)
|
||||||
free(execbuf);
|
free(execbuf);
|
||||||
@ -59,7 +62,7 @@ static int pid_is_user(int pid, int uid)
|
|||||||
struct stat sb;
|
struct stat sb;
|
||||||
char buf[sizeof("/proc/") + sizeof(int)*3];
|
char buf[sizeof("/proc/") + sizeof(int)*3];
|
||||||
|
|
||||||
sprintf(buf, "/proc/%d", pid);
|
sprintf(buf, "/proc/%u", pid);
|
||||||
if (stat(buf, &sb) != 0)
|
if (stat(buf, &sb) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
return (sb.st_uid == uid);
|
return (sb.st_uid == uid);
|
||||||
@ -67,25 +70,24 @@ static int pid_is_user(int pid, int uid)
|
|||||||
|
|
||||||
static int pid_is_cmd(pid_t pid, const char *name)
|
static int pid_is_cmd(pid_t pid, const char *name)
|
||||||
{
|
{
|
||||||
char buf[sizeof("/proc//stat") + sizeof(int)*3];
|
char fname[sizeof("/proc//stat") + sizeof(int)*3];
|
||||||
FILE *f;
|
char *buf;
|
||||||
int c;
|
int r = 0;
|
||||||
|
|
||||||
sprintf(buf, "/proc/%d/stat", pid);
|
sprintf(fname, "/proc/%u/stat", pid);
|
||||||
f = fopen(buf, "r");
|
buf = xmalloc_open_read_close(fname, NULL);
|
||||||
if (!f)
|
if (buf) {
|
||||||
return 0;
|
char *p = strchr(buf, '(');
|
||||||
while ((c = getc(f)) != EOF && c != '(')
|
if (p) {
|
||||||
;
|
char *pe = strrchr(++p, ')');
|
||||||
if (c != '(') {
|
if (pe) {
|
||||||
fclose(f);
|
*pe = '\0';
|
||||||
return 0;
|
r = !strcmp(p, name);
|
||||||
}
|
}
|
||||||
/* this hopefully handles command names containing ')' */
|
}
|
||||||
while ((c = getc(f)) != EOF && c == *name)
|
free(buf);
|
||||||
name++;
|
}
|
||||||
fclose(f);
|
return r;
|
||||||
return (c == ')' && *name == '\0');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -111,7 +113,7 @@ static void do_pidfile(void)
|
|||||||
|
|
||||||
f = fopen(pidfile, "r");
|
f = fopen(pidfile, "r");
|
||||||
if (f) {
|
if (f) {
|
||||||
if (fscanf(f, "%d", &pid) == 1)
|
if (fscanf(f, "%u", &pid) == 1)
|
||||||
check(pid);
|
check(pid);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
} else if (errno != ENOENT)
|
} else if (errno != ENOENT)
|
||||||
@ -133,7 +135,8 @@ static void do_procinit(void)
|
|||||||
|
|
||||||
foundany = 0;
|
foundany = 0;
|
||||||
while ((entry = readdir(procdir)) != NULL) {
|
while ((entry = readdir(procdir)) != NULL) {
|
||||||
if (sscanf(entry->d_name, "%d", &pid) != 1)
|
pid = bb_strtou(entry->d_name, NULL, 10);
|
||||||
|
if (errno)
|
||||||
continue;
|
continue;
|
||||||
foundany++;
|
foundany++;
|
||||||
check(pid);
|
check(pid);
|
||||||
@ -269,8 +272,11 @@ int start_stop_daemon_main(int argc, char **argv)
|
|||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
if (userspec && sscanf(userspec, "%d", &user_id) != 1)
|
if (userspec) {
|
||||||
|
user_id = bb_strtou(userspec, NULL, 10);
|
||||||
|
if (errno)
|
||||||
user_id = bb_xgetpwnam(userspec);
|
user_id = bb_xgetpwnam(userspec);
|
||||||
|
}
|
||||||
|
|
||||||
if (opt & SSD_CTX_STOP) {
|
if (opt & SSD_CTX_STOP) {
|
||||||
int i = do_stop();
|
int i = do_stop();
|
||||||
@ -301,7 +307,8 @@ int start_stop_daemon_main(int argc, char **argv)
|
|||||||
fclose(pidf);
|
fclose(pidf);
|
||||||
}
|
}
|
||||||
if (chuid) {
|
if (chuid) {
|
||||||
if (sscanf(chuid, "%d", &user_id) != 1)
|
user_id = bb_strtou(chuid, NULL, 10);
|
||||||
|
if (errno)
|
||||||
user_id = bb_xgetpwnam(chuid);
|
user_id = bb_xgetpwnam(chuid);
|
||||||
xsetuid(user_id);
|
xsetuid(user_id);
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,9 @@ void *xmalloc_open_read_close(const char *filename, size_t *sizep)
|
|||||||
char *buf;
|
char *buf;
|
||||||
size_t size = sizep ? *sizep : INT_MAX;
|
size_t size = sizep ? *sizep : INT_MAX;
|
||||||
int fd = xopen(filename, O_RDONLY);
|
int fd = xopen(filename, O_RDONLY);
|
||||||
off_t len = xlseek(fd, 0, SEEK_END);
|
/* /proc/N/stat files report len 0 here */
|
||||||
|
/* In order to make such files readable, we add small const */
|
||||||
|
off_t len = xlseek(fd, 0, SEEK_END) + 256;
|
||||||
xlseek(fd, 0, SEEK_SET);
|
xlseek(fd, 0, SEEK_SET);
|
||||||
|
|
||||||
if (len > size)
|
if (len > size)
|
||||||
@ -128,6 +130,7 @@ void *xmalloc_open_read_close(const char *filename, size_t *sizep)
|
|||||||
size = read_close(fd, buf, size);
|
size = read_close(fd, buf, size);
|
||||||
if ((ssize_t)size < 0)
|
if ((ssize_t)size < 0)
|
||||||
bb_perror_msg_and_die("'%s'", filename);
|
bb_perror_msg_and_die("'%s'", filename);
|
||||||
|
xrealloc(buf, size + 1);
|
||||||
buf[size] = '\0';
|
buf[size] = '\0';
|
||||||
if (sizep) *sizep = size;
|
if (sizep) *sizep = size;
|
||||||
return buf;
|
return buf;
|
||||||
|
Loading…
Reference in New Issue
Block a user