From 38cdd08b22565f861ae6dd83b02bc6b189ba2ef5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 14 Apr 2023 17:47:43 +0200 Subject: [PATCH] process-util: be more careful with pidfd_get_pid() special cases 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 | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/basic/process-util.c b/src/basic/process-util.c index a9826d94d3b..7de7d80cd4a 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -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); }