process-util: refactor APIs for reading /proc/self/xyz symlinks

The three functions for reading cwd, exe and root symlinks of processes
already share a common core: get_process_link_contents(). Let's refactor
that a bit, and move formatting of the /proc/self/ path into this helper
function instead of doing that in the caller, thus sharing more code.

While we are at it, make the return parameters optional, in case the
information if the links are readable is interesting, but the contents
is not. (This also means safe_getcwd() and readlinkat_malloc() are
updated to make the return parameter optional, as these are called by
the relevant three functions)
This commit is contained in:
Lennart Poettering
2022-04-01 15:22:27 +02:00
parent b8529cf376
commit aed3c5eca3
3 changed files with 22 additions and 35 deletions
+4 -2
View File
@@ -119,7 +119,6 @@ int readlinkat_malloc(int fd, const char *p, char **ret) {
size_t l = PATH_MAX;
assert(p);
assert(ret);
for (;;) {
_cleanup_free_ char *c = NULL;
@@ -135,7 +134,10 @@ int readlinkat_malloc(int fd, const char *p, char **ret) {
if ((size_t) n < l) {
c[n] = 0;
*ret = TAKE_PTR(c);
if (ret)
*ret = TAKE_PTR(c);
return 0;
}
+5 -5
View File
@@ -63,7 +63,7 @@ char *path_make_absolute(const char *p, const char *prefix) {
}
int safe_getcwd(char **ret) {
char *cwd;
_cleanup_free_ char *cwd = NULL;
cwd = get_current_dir_name();
if (!cwd)
@@ -71,12 +71,12 @@ int safe_getcwd(char **ret) {
/* Let's make sure the directory is really absolute, to protect us from the logic behind
* CVE-2018-1000001 */
if (cwd[0] != '/') {
free(cwd);
if (cwd[0] != '/')
return -ENOMEDIUM;
}
*ret = cwd;
if (ret)
*ret = TAKE_PTR(cwd);
return 0;
}
+13 -28
View File
@@ -472,37 +472,33 @@ int get_process_capeff(pid_t pid, char **ret) {
return r;
}
static int get_process_link_contents(const char *proc_file, char **ret) {
static int get_process_link_contents(pid_t pid, const char *proc_file, char **ret) {
const char *p;
int r;
assert(proc_file);
assert(ret);
r = readlink_malloc(proc_file, ret);
if (r == -ENOENT)
return -ESRCH;
if (r < 0)
return r;
p = procfs_file_alloca(pid, proc_file);
return 0;
r = readlink_malloc(p, ret);
return r == -ENOENT ? -ESRCH : r;
}
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, ret);
r = get_process_link_contents(pid, "exe", ret);
if (r < 0)
return r;
d = endswith(*ret, " (deleted)");
if (d)
*d = '\0';
if (ret) {
d = endswith(*ret, " (deleted)");
if (d)
*d = '\0';
}
return 0;
}
@@ -572,28 +568,17 @@ int get_process_gid(pid_t pid, gid_t *ret) {
}
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(ret);
p = procfs_file_alloca(pid, "cwd");
return get_process_link_contents(p, ret);
return get_process_link_contents(pid, "cwd", ret);
}
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, ret);
return get_process_link_contents(pid, "root", ret);
}
#define ENVIRONMENT_BLOCK_MAX (5U*1024U*1024U)