]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
process-util: be more careful with pidfd_get_pid() special cases
authorLennart Poettering <lennart@poettering.net>
Fri, 14 Apr 2023 15:47:43 +0000 (17:47 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Mon, 17 Apr 2023 20:38:41 +0000 (21:38 +0100)
Let's be more careful with generating error codes for (expected) error
causes.

This does not introduce new error conditions, it just changes what we
return under specific cases, to make things nicely recognizable in each
case. Most importantly this detects if fdinfo reports a pid of "-1" for
pidfds with processes that are already reaped (and thus have no PID
anymore)

None of our current users care about these error codes, but let's get
this right for the future.

src/basic/process-util.c

index a9826d94d3be303ed896e7d39a3e49d42692ee68..7de7d80cd4aa33261e04653356b3df9baa1b04fc 100644 (file)
@@ -1472,6 +1472,15 @@ int pidfd_get_pid(int fd, pid_t *ret) {
         char *p;
         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
+         */
+
         if (fd < 0)
                 return -EBADF;
 
@@ -1479,7 +1488,7 @@ int pidfd_get_pid(int fd, pid_t *ret) {
 
         r = read_full_virtual_file(path, &fdinfo, NULL);
         if (r == -ENOENT) /* if fdinfo doesn't exist we assume the process does not exist */
-                return -ESRCH;
+                return proc_mounted() > 0 ? -EBADF : -ENOSYS;
         if (r < 0)
                 return r;
 
@@ -1490,6 +1499,11 @@ int pidfd_get_pid(int fd, pid_t *ret) {
         p += strspn(p, WHITESPACE);
         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);
 }