mirror of
https://github.com/sheumann/hush.git
synced 2024-12-21 23:29:34 +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;
|
||||
};
|
||||
|
||||
static struct pid_list *found = NULL;
|
||||
static struct pid_list *found;
|
||||
|
||||
static inline void push(pid_t pid)
|
||||
{
|
||||
@ -42,13 +42,16 @@ static int pid_is_exec(pid_t pid, const char *name)
|
||||
{
|
||||
char buf[sizeof("/proc//exe") + sizeof(int)*3];
|
||||
char *execbuf;
|
||||
int sz;
|
||||
int equal;
|
||||
|
||||
sprintf(buf, "/proc/%d/exe", pid);
|
||||
execbuf = xstrdup(name);
|
||||
readlink(buf, execbuf, strlen(name)+1);
|
||||
sz = strlen(name) + 1;
|
||||
execbuf = xzalloc(sz);
|
||||
readlink(buf, execbuf, sz);
|
||||
|
||||
equal = ! strcmp(execbuf, name);
|
||||
/* if readlink fails, execbuf still contains "" */
|
||||
equal = !strcmp(execbuf, name);
|
||||
if (ENABLE_FEATURE_CLEAN_UP)
|
||||
free(execbuf);
|
||||
return equal;
|
||||
@ -59,7 +62,7 @@ static int pid_is_user(int pid, int uid)
|
||||
struct stat sb;
|
||||
char buf[sizeof("/proc/") + sizeof(int)*3];
|
||||
|
||||
sprintf(buf, "/proc/%d", pid);
|
||||
sprintf(buf, "/proc/%u", pid);
|
||||
if (stat(buf, &sb) != 0)
|
||||
return 0;
|
||||
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)
|
||||
{
|
||||
char buf[sizeof("/proc//stat") + sizeof(int)*3];
|
||||
FILE *f;
|
||||
int c;
|
||||
char fname[sizeof("/proc//stat") + sizeof(int)*3];
|
||||
char *buf;
|
||||
int r = 0;
|
||||
|
||||
sprintf(buf, "/proc/%d/stat", pid);
|
||||
f = fopen(buf, "r");
|
||||
if (!f)
|
||||
return 0;
|
||||
while ((c = getc(f)) != EOF && c != '(')
|
||||
;
|
||||
if (c != '(') {
|
||||
fclose(f);
|
||||
return 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);
|
||||
}
|
||||
/* this hopefully handles command names containing ')' */
|
||||
while ((c = getc(f)) != EOF && c == *name)
|
||||
name++;
|
||||
fclose(f);
|
||||
return (c == ')' && *name == '\0');
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@ -111,7 +113,7 @@ static void do_pidfile(void)
|
||||
|
||||
f = fopen(pidfile, "r");
|
||||
if (f) {
|
||||
if (fscanf(f, "%d", &pid) == 1)
|
||||
if (fscanf(f, "%u", &pid) == 1)
|
||||
check(pid);
|
||||
fclose(f);
|
||||
} else if (errno != ENOENT)
|
||||
@ -133,7 +135,8 @@ static void do_procinit(void)
|
||||
|
||||
foundany = 0;
|
||||
while ((entry = readdir(procdir)) != NULL) {
|
||||
if (sscanf(entry->d_name, "%d", &pid) != 1)
|
||||
pid = bb_strtou(entry->d_name, NULL, 10);
|
||||
if (errno)
|
||||
continue;
|
||||
foundany++;
|
||||
check(pid);
|
||||
@ -269,8 +272,11 @@ int start_stop_daemon_main(int argc, char **argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (userspec && sscanf(userspec, "%d", &user_id) != 1)
|
||||
user_id = bb_xgetpwnam(userspec);
|
||||
if (userspec) {
|
||||
user_id = bb_strtou(userspec, NULL, 10);
|
||||
if (errno)
|
||||
user_id = bb_xgetpwnam(userspec);
|
||||
}
|
||||
|
||||
if (opt & SSD_CTX_STOP) {
|
||||
int i = do_stop();
|
||||
@ -301,7 +307,8 @@ int start_stop_daemon_main(int argc, char **argv)
|
||||
fclose(pidf);
|
||||
}
|
||||
if (chuid) {
|
||||
if (sscanf(chuid, "%d", &user_id) != 1)
|
||||
user_id = bb_strtou(chuid, NULL, 10);
|
||||
if (errno)
|
||||
user_id = bb_xgetpwnam(chuid);
|
||||
xsetuid(user_id);
|
||||
}
|
||||
|
@ -118,16 +118,19 @@ void *xmalloc_open_read_close(const char *filename, size_t *sizep)
|
||||
char *buf;
|
||||
size_t size = sizep ? *sizep : INT_MAX;
|
||||
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);
|
||||
|
||||
if (len > size)
|
||||
bb_error_msg_and_die("file '%s' is too big", filename);
|
||||
size = len;
|
||||
buf = xmalloc(size+1);
|
||||
buf = xmalloc(size + 1);
|
||||
size = read_close(fd, buf, size);
|
||||
if ((ssize_t)size < 0)
|
||||
bb_perror_msg_and_die("'%s'", filename);
|
||||
xrealloc(buf, size + 1);
|
||||
buf[size] = '\0';
|
||||
if (sizep) *sizep = size;
|
||||
return buf;
|
||||
|
Loading…
Reference in New Issue
Block a user