From: Mike Yuan Date: Tue, 19 Nov 2024 19:03:55 +0000 (+0100) Subject: process-util: extract pidfd-related funcs into pidfd-util.[ch] X-Git-Tag: v258-rc1~1704^2~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b234026d09a1ec3bd548efe6185c7c1de4498a96;p=thirdparty%2Fsystemd.git process-util: extract pidfd-related funcs into pidfd-util.[ch] --- diff --git a/src/basic/meson.build b/src/basic/meson.build index e02f787c75e..147040a193e 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -72,6 +72,7 @@ basic_sources = files( 'parse-util.c', 'path-util.c', 'percent-util.c', + 'pidfd-util.c', 'pidref.c', 'prioq.c', 'proc-cmdline.c', diff --git a/src/basic/pidfd-util.c b/src/basic/pidfd-util.c new file mode 100644 index 00000000000..351107ab5c1 --- /dev/null +++ b/src/basic/pidfd-util.c @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include + +#include "errno-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "macro.h" +#include "memory-util.h" +#include "parse-util.h" +#include "path-util.h" +#include "pidfd-util.h" +#include "string-util.h" + +int pidfd_get_pid(int fd, pid_t *ret) { + char path[STRLEN("/proc/self/fdinfo/") + DECIMAL_STR_MAX(int)]; + _cleanup_free_ char *fdinfo = NULL; + int r; + + /* Converts a pidfd into a pid. Well known errors: + * + * -EBADF → fd invalid + * -ENOSYS → /proc/ not mounted + * -ENOTTY → fd valid, but not a pidfd + * -EREMOTE → fd valid, but pid is in another namespace we cannot translate to the local one + * -ESRCH → fd valid, but process is already reaped + */ + + assert(fd >= 0); + + xsprintf(path, "/proc/self/fdinfo/%i", fd); + + r = read_full_virtual_file(path, &fdinfo, NULL); + if (r == -ENOENT) + return proc_fd_enoent_errno(); + if (r < 0) + return r; + + char *p = find_line_startswith(fdinfo, "Pid:"); + if (!p) + return -ENOTTY; /* not a pidfd? */ + + p = skip_leading_chars(p, /* bad = */ NULL); + p[strcspn(p, WHITESPACE)] = 0; + + if (streq(p, "0")) + return -EREMOTE; /* PID is in foreign PID namespace? */ + if (streq(p, "-1")) + return -ESRCH; /* refers to reaped process? */ + + return parse_pid(p, ret); +} + +int pidfd_verify_pid(int pidfd, pid_t pid) { + pid_t current_pid; + int r; + + assert(pidfd >= 0); + assert(pid > 0); + + r = pidfd_get_pid(pidfd, ¤t_pid); + if (r < 0) + return r; + + return current_pid != pid ? -ESRCH : 0; +} diff --git a/src/basic/pidfd-util.h b/src/basic/pidfd-util.h new file mode 100644 index 00000000000..3b149cab862 --- /dev/null +++ b/src/basic/pidfd-util.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#if HAVE_PIDFD_OPEN +#include +#endif +#include + +#include "missing_syscall.h" + +int pidfd_get_pid(int fd, pid_t *ret); +int pidfd_verify_pid(int pidfd, pid_t pid); diff --git a/src/basic/pidref.c b/src/basic/pidref.c index 5e4b3438c1b..ecea98fe6d9 100644 --- a/src/basic/pidref.c +++ b/src/basic/pidref.c @@ -1,15 +1,12 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#if HAVE_PIDFD_OPEN -#include -#endif - #include "errno-util.h" #include "fd-util.h" #include "missing_magic.h" #include "missing_syscall.h" #include "missing_wait.h" #include "parse-util.h" +#include "pidfd-util.h" #include "pidref.h" #include "process-util.h" #include "signal-util.h" diff --git a/src/basic/process-util.c b/src/basic/process-util.c index d02a122a354..ec4ea98c036 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -1859,59 +1859,6 @@ int get_oom_score_adjust(int *ret) { return 0; } -int pidfd_get_pid(int fd, pid_t *ret) { - char path[STRLEN("/proc/self/fdinfo/") + DECIMAL_STR_MAX(int)]; - _cleanup_free_ char *fdinfo = NULL; - int r; - - /* Converts a pidfd into a pid. Well known errors: - * - * -EBADF → fd invalid - * -ENOSYS → /proc/ not mounted - * -ENOTTY → fd valid, but not a pidfd - * -EREMOTE → fd valid, but pid is in another namespace we cannot translate to the local one - * -ESRCH → fd valid, but process is already reaped - */ - - assert(fd >= 0); - - xsprintf(path, "/proc/self/fdinfo/%i", fd); - - r = read_full_virtual_file(path, &fdinfo, NULL); - if (r == -ENOENT) - return proc_fd_enoent_errno(); - if (r < 0) - return r; - - char *p = find_line_startswith(fdinfo, "Pid:"); - if (!p) - return -ENOTTY; /* not a pidfd? */ - - p = skip_leading_chars(p, /* bad = */ NULL); - p[strcspn(p, WHITESPACE)] = 0; - - if (streq(p, "0")) - return -EREMOTE; /* PID is in foreign PID namespace? */ - if (streq(p, "-1")) - return -ESRCH; /* refers to reaped process? */ - - return parse_pid(p, ret); -} - -int pidfd_verify_pid(int pidfd, pid_t pid) { - pid_t current_pid; - int r; - - assert(pidfd >= 0); - assert(pid > 0); - - r = pidfd_get_pid(pidfd, ¤t_pid); - if (r < 0) - return r; - - return current_pid != pid ? -ESRCH : 0; -} - static int rlimit_to_nice(rlim_t limit) { if (limit <= 1) return PRIO_MAX-1; /* i.e. 19 */ diff --git a/src/basic/process-util.h b/src/basic/process-util.h index f1088afc1db..a59cdf22acb 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -250,9 +250,6 @@ assert_cc(TASKS_MAX <= (unsigned long) PID_T_MAX); /* Like TAKE_PTR() but for pid_t, resetting them to 0 */ #define TAKE_PID(pid) TAKE_GENERIC(pid, pid_t, 0) -int pidfd_get_pid(int fd, pid_t *ret); -int pidfd_verify_pid(int pidfd, pid_t pid); - int setpriority_closest(int priority); _noreturn_ void freeze(void); diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index 7aea7d25813..c1f1747fd06 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -1,9 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include -#if HAVE_PIDFD_OPEN -#include -#endif #include #include @@ -31,6 +28,7 @@ #include "origin-id.h" #include "path-util.h" #include "prioq.h" +#include "pidfd-util.h" #include "process-util.h" #include "psi-util.h" #include "set.h" diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index 3aca5936229..6c2387989b6 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -22,6 +22,7 @@ #include "macro.h" #include "parse-util.h" #include "path-util.h" +#include "pidfd-util.h" #include "process-util.h" #include "socket-util.h" #include "stdio-util.h"