diff options
-rw-r--r-- | src/basic/meson.build | 1 | ||||
-rw-r--r-- | src/basic/pidfd-util.c | 66 | ||||
-rw-r--r-- | src/basic/pidfd-util.h | 13 | ||||
-rw-r--r-- | src/basic/pidref.c | 5 | ||||
-rw-r--r-- | src/basic/process-util.c | 53 | ||||
-rw-r--r-- | src/basic/process-util.h | 3 | ||||
-rw-r--r-- | src/libsystemd/sd-event/sd-event.c | 4 | ||||
-rw-r--r-- | src/libsystemd/sd-login/sd-login.c | 1 |
8 files changed, 83 insertions, 63 deletions
diff --git a/src/basic/meson.build b/src/basic/meson.build index e02f787c75..147040a193 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 0000000000..351107ab5c --- /dev/null +++ b/src/basic/pidfd-util.c @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include <unistd.h> + +#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 0000000000..3b149cab86 --- /dev/null +++ b/src/basic/pidfd-util.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include <stdint.h> +#if HAVE_PIDFD_OPEN +#include <sys/pidfd.h> +#endif +#include <sys/types.h> + +#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 5e4b3438c1..ecea98fe6d 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 <sys/pidfd.h> -#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 d02a122a35..ec4ea98c03 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 f1088afc1d..a59cdf22ac 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 7aea7d2581..c1f1747fd0 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 <sys/epoll.h> -#if HAVE_PIDFD_OPEN -#include <sys/pidfd.h> -#endif #include <sys/timerfd.h> #include <sys/wait.h> @@ -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 3aca593622..6c2387989b 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" |