]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
process-util: add helper to verify a pid via its pidfd
authorLuca Boccassi <bluca@debian.org>
Fri, 20 Jan 2023 12:13:22 +0000 (12:13 +0000)
committerLuca Boccassi <bluca@debian.org>
Fri, 20 Jan 2023 12:18:05 +0000 (12:18 +0000)
src/basic/process-util.c
src/basic/process-util.h
src/core/dbus-manager.c

index fa00c962ab55c7434199ff7cf358288528c5b9a3..70aa15f0600695d9878732cfd87086a733da320e 100644 (file)
@@ -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, &current_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 */
index 8a981cd7301cbd6c5e4244070ba7efb5d90cebc4..6ceb8ebf7d70f4331a72c0f3608fb442c7ec6b11 100644 (file)
@@ -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);
 
index e4a4b69541c0181e46f79ed77d2770e503568c34..53121fa1a6bd89fe92384dcc077205f122607bc3 100644 (file)
@@ -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);
 }