1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-30 14:55:37 +03:00

Merge pull request #21196 from yuwata/process-util-nulstr

process-util: handle double NUL as the end of command line
This commit is contained in:
Yu Watanabe 2021-12-07 08:29:34 +09:00 committed by GitHub
commit a0af85e02c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 47 deletions

View File

@ -181,13 +181,13 @@ static int get_process_cmdline_nulstr(
return r;
}
int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **line) {
int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret) {
_cleanup_free_ char *t = NULL;
size_t k;
char *ans;
assert(line);
assert(pid >= 0);
assert(ret);
/* Retrieve and format a commandline. See above for discussion of retrieval options.
*
@ -214,11 +214,17 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags
assert(!(flags & PROCESS_CMDLINE_USE_LOCALE));
_cleanup_strv_free_ char **args = NULL;
char **p;
args = strv_parse_nulstr(t, k);
if (!args)
return -ENOMEM;
/* Drop trailing empty strings. See issue #21186. */
STRV_FOREACH_BACKWARDS(p, args)
if (isempty(*p))
*p = mfree(*p);
ans = quote_command_line(args, shflags);
if (!ans)
return -ENOMEM;
@ -240,7 +246,7 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags
ans = str_realloc(ans);
}
*line = ans;
*ret = ans;
return 0;
}
@ -447,29 +453,29 @@ int is_kernel_thread(pid_t pid) {
return !!(flags & PF_KTHREAD);
}
int get_process_capeff(pid_t pid, char **capeff) {
int get_process_capeff(pid_t pid, char **ret) {
const char *p;
int r;
assert(capeff);
assert(pid >= 0);
assert(ret);
p = procfs_file_alloca(pid, "status");
r = get_proc_field(p, "CapEff", WHITESPACE, capeff);
r = get_proc_field(p, "CapEff", WHITESPACE, ret);
if (r == -ENOENT)
return -ESRCH;
return r;
}
static int get_process_link_contents(const char *proc_file, char **name) {
static int get_process_link_contents(const char *proc_file, char **ret) {
int r;
assert(proc_file);
assert(name);
assert(ret);
r = readlink_malloc(proc_file, name);
r = readlink_malloc(proc_file, ret);
if (r == -ENOENT)
return -ESRCH;
if (r < 0)
@ -478,32 +484,33 @@ static int get_process_link_contents(const char *proc_file, char **name) {
return 0;
}
int get_process_exe(pid_t pid, char **name) {
int get_process_exe(pid_t pid, char **ret) {
const char *p;
char *d;
int r;
assert(pid >= 0);
assert(ret);
p = procfs_file_alloca(pid, "exe");
r = get_process_link_contents(p, name);
r = get_process_link_contents(p, ret);
if (r < 0)
return r;
d = endswith(*name, " (deleted)");
d = endswith(*ret, " (deleted)");
if (d)
*d = '\0';
return 0;
}
static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
static int get_process_id(pid_t pid, const char *field, uid_t *ret) {
_cleanup_fclose_ FILE *f = NULL;
const char *p;
int r;
assert(field);
assert(uid);
assert(ret);
if (pid < 0)
return -EINVAL;
@ -533,60 +540,62 @@ static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
l[strcspn(l, WHITESPACE)] = 0;
return parse_uid(l, uid);
return parse_uid(l, ret);
}
}
return -EIO;
}
int get_process_uid(pid_t pid, uid_t *uid) {
int get_process_uid(pid_t pid, uid_t *ret) {
if (pid == 0 || pid == getpid_cached()) {
*uid = getuid();
*ret = getuid();
return 0;
}
return get_process_id(pid, "Uid:", uid);
return get_process_id(pid, "Uid:", ret);
}
int get_process_gid(pid_t pid, gid_t *gid) {
int get_process_gid(pid_t pid, gid_t *ret) {
if (pid == 0 || pid == getpid_cached()) {
*gid = getgid();
*ret = getgid();
return 0;
}
assert_cc(sizeof(uid_t) == sizeof(gid_t));
return get_process_id(pid, "Gid:", gid);
return get_process_id(pid, "Gid:", ret);
}
int get_process_cwd(pid_t pid, char **cwd) {
int get_process_cwd(pid_t pid, char **ret) {
const char *p;
assert(pid >= 0);
assert(ret);
if (pid == 0 || pid == getpid_cached())
return safe_getcwd(cwd);
return safe_getcwd(ret);
p = procfs_file_alloca(pid, "cwd");
return get_process_link_contents(p, cwd);
return get_process_link_contents(p, ret);
}
int get_process_root(pid_t pid, char **root) {
int get_process_root(pid_t pid, char **ret) {
const char *p;
assert(pid >= 0);
assert(ret);
p = procfs_file_alloca(pid, "root");
return get_process_link_contents(p, root);
return get_process_link_contents(p, ret);
}
#define ENVIRONMENT_BLOCK_MAX (5U*1024U*1024U)
int get_process_environ(pid_t pid, char **env) {
int get_process_environ(pid_t pid, char **ret) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *outcome = NULL;
size_t sz = 0;
@ -594,7 +603,7 @@ int get_process_environ(pid_t pid, char **env) {
int r;
assert(pid >= 0);
assert(env);
assert(ret);
p = procfs_file_alloca(pid, "environ");
@ -626,7 +635,7 @@ int get_process_environ(pid_t pid, char **env) {
}
outcome[sz] = '\0';
*env = TAKE_PTR(outcome);
*ret = TAKE_PTR(outcome);
return 0;
}
@ -685,13 +694,13 @@ int get_process_ppid(pid_t pid, pid_t *ret) {
return 0;
}
int get_process_umask(pid_t pid, mode_t *umask) {
int get_process_umask(pid_t pid, mode_t *ret) {
_cleanup_free_ char *m = NULL;
const char *p;
int r;
assert(umask);
assert(pid >= 0);
assert(ret);
p = procfs_file_alloca(pid, "status");
@ -699,7 +708,7 @@ int get_process_umask(pid_t pid, mode_t *umask) {
if (r == -ENOENT)
return -ESRCH;
return parse_mode(m, umask);
return parse_mode(m, ret);
}
int wait_for_terminate(pid_t pid, siginfo_t *status) {

View File

@ -38,17 +38,17 @@ typedef enum ProcessCmdlineFlags {
PROCESS_CMDLINE_QUOTE_POSIX = 1 << 3,
} ProcessCmdlineFlags;
int get_process_comm(pid_t pid, char **name);
int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **line);
int get_process_exe(pid_t pid, char **name);
int get_process_uid(pid_t pid, uid_t *uid);
int get_process_gid(pid_t pid, gid_t *gid);
int get_process_capeff(pid_t pid, char **capeff);
int get_process_cwd(pid_t pid, char **cwd);
int get_process_root(pid_t pid, char **root);
int get_process_environ(pid_t pid, char **environ);
int get_process_ppid(pid_t pid, pid_t *ppid);
int get_process_umask(pid_t pid, mode_t *umask);
int get_process_comm(pid_t pid, char **ret);
int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret);
int get_process_exe(pid_t pid, char **ret);
int get_process_uid(pid_t pid, uid_t *ret);
int get_process_gid(pid_t pid, gid_t *ret);
int get_process_capeff(pid_t pid, char **ret);
int get_process_cwd(pid_t pid, char **ret);
int get_process_root(pid_t pid, char **ret);
int get_process_environ(pid_t pid, char **ret);
int get_process_ppid(pid_t pid, pid_t *ret);
int get_process_umask(pid_t pid, mode_t *ret);
int wait_for_terminate(pid_t pid, siginfo_t *status);

View File

@ -484,8 +484,8 @@ TEST(get_process_cmdline_harder) {
/* Test with multiple arguments that do require quoting */
#define CMDLINE1 "foo\0'bar'\0\"bar$\"\0x y z\0!``\0"
#define EXPECT1 "foo \"'bar'\" \"\\\"bar\\$\\\"\" \"x y z\" \"!\\`\\`\" \"\""
#define EXPECT1p "foo $'\\'bar\\'' $'\"bar$\"' $'x y z' $'!``' \"\""
#define EXPECT1 "foo \"'bar'\" \"\\\"bar\\$\\\"\" \"x y z\" \"!\\`\\`\""
#define EXPECT1p "foo $'\\'bar\\'' $'\"bar$\"' $'x y z' $'!``'"
assert_se(lseek(fd, SEEK_SET, 0) == 0);
assert_se(write(fd, CMDLINE1, sizeof CMDLINE1) == sizeof CMDLINE1);
assert_se(ftruncate(fd, sizeof CMDLINE1) == 0);
@ -503,8 +503,8 @@ TEST(get_process_cmdline_harder) {
line = mfree(line);
#define CMDLINE2 "foo\0\1\2\3\0\0"
#define EXPECT2 "foo \"\\001\\002\\003\" \"\" \"\""
#define EXPECT2p "foo $'\\001\\002\\003' \"\" \"\""
#define EXPECT2 "foo \"\\001\\002\\003\""
#define EXPECT2p "foo $'\\001\\002\\003'"
assert_se(lseek(fd, SEEK_SET, 0) == 0);
assert_se(write(fd, CMDLINE2, sizeof CMDLINE2) == sizeof CMDLINE2);
assert_se(ftruncate(fd, sizeof CMDLINE2) == 0);