From: Luca Boccassi Date: Fri, 20 Jan 2023 12:13:22 +0000 (+0000) Subject: process-util: add helper to verify a pid via its pidfd X-Git-Tag: v253-rc1~54^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f840c7d58dcd39fa98a887c50a9be5c35dbb599f;p=thirdparty%2Fsystemd.git process-util: add helper to verify a pid via its pidfd --- diff --git a/src/basic/process-util.c b/src/basic/process-util.c index fa00c962ab5..70aa15f0600 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -1456,6 +1456,20 @@ int pidfd_get_pid(int fd, pid_t *ret) { 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 8a981cd7301..6ceb8ebf7d7 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -190,6 +190,7 @@ assert_cc(TASKS_MAX <= (unsigned long) PID_T_MAX); }) int pidfd_get_pid(int fd, pid_t *ret); +int pidfd_verify_pid(int pidfd, pid_t pid); int setpriority_closest(int priority); diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index e4a4b69541c..53121fa1a6b 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -658,7 +658,7 @@ static int method_get_unit_by_pidfd(sd_bus_message *message, void *userdata, sd_ Manager *m = ASSERT_PTR(userdata); _cleanup_free_ char *path = NULL; int r, pidfd; - pid_t pid_early, pid_late; + pid_t pid; Unit *u; assert(message); @@ -667,13 +667,13 @@ static int method_get_unit_by_pidfd(sd_bus_message *message, void *userdata, sd_ if (r < 0) return r; - r = pidfd_get_pid(pidfd, &pid_early); + r = pidfd_get_pid(pidfd, &pid); if (r < 0) return sd_bus_error_set_errnof(error, r, "Failed to get PID from PIDFD: %m"); - u = manager_get_unit_by_pid(m, pid_early); + u = manager_get_unit_by_pid(m, pid); if (!u) - return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pid_early); + return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pid); r = mac_selinux_unit_access_check(u, message, "status", error); if (r < 0) @@ -697,15 +697,14 @@ static int method_get_unit_by_pidfd(sd_bus_message *message, void *userdata, sd_ /* Double-check that the process is still alive and that the PID did not change before returning the * answer. */ - r = pidfd_get_pid(pidfd, &pid_late); - if (r < 0) - return sd_bus_error_set_errnof(error, r, "Failed to get PID from PIDFD: %m"); - if (pid_early != pid_late) + r = pidfd_verify_pid(pidfd, pid); + if (r == -ESRCH) return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, - "The PIDFD's PID "PID_FMT" changed to "PID_FMT" during the lookup operation.", - pid_early, - pid_late); + "The PIDFD's PID "PID_FMT" changed during the lookup operation.", + pid); + if (r < 0) + return sd_bus_error_set_errnof(error, r, "Failed to get PID from PIDFD: %m"); return sd_bus_send(NULL, reply, NULL); }