From: Lennart Poettering Date: Tue, 19 Sep 2023 14:22:29 +0000 (+0200) Subject: pidref: add pidref_verify() helper X-Git-Tag: v255-rc1~387^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ec8dc8353087a790aa4b8dc2c6aa565d0af418e2;p=thirdparty%2Fsystemd.git pidref: add pidref_verify() helper This new helper can be used after reading process info from procfs, to verify that the data that was just read actually matches the pidfd, and does not belong to some new process that just reused the numeric PID of the process we originally pinned. --- diff --git a/src/basic/pidref.c b/src/basic/pidref.c index 02d6832bd08..a9fbbf2c906 100644 --- a/src/basic/pidref.c +++ b/src/basic/pidref.c @@ -240,6 +240,26 @@ int pidref_sigqueue(PidRef *pidref, int sig, int value) { return -ESRCH; } +int pidref_verify(PidRef *pidref) { + int r; + + /* This is a helper that is supposed to be called after reading information from procfs via a + * PidRef. It ensures that the PID we track still matches the PIDFD we pin. If this value differs + * after a procfs read, we might have read the data from a recycled PID. */ + + if (!pidref_is_set(pidref)) + return -ESRCH; + + if (pidref->fd < 0) + return 0; /* If we don't have a pidfd we cannot validate it, hence we assume it's all OK → return 0 */ + + r = pidfd_verify_pid(pidref->fd, pidref->pid); + if (r < 0) + return r; + + return 1; /* We have a pidfd and it still points to the PID we have, hence all is *really* OK → return 1 */ +} + static void pidref_hash_func(const PidRef *pidref, struct siphash *state) { siphash24_compress(&pidref->pid, sizeof(pidref->pid), state); } diff --git a/src/basic/pidref.h b/src/basic/pidref.h index 835bafc96e4..89f43157bac 100644 --- a/src/basic/pidref.h +++ b/src/basic/pidref.h @@ -51,6 +51,8 @@ int pidref_kill(PidRef *pidref, int sig); int pidref_kill_and_sigcont(PidRef *pidref, int sig); int pidref_sigqueue(PidRef *pidfref, int sig, int value); +int pidref_verify(PidRef *pidref); + #define TAKE_PIDREF(p) TAKE_GENERIC((p), PidRef, PIDREF_NULL) extern const struct hash_ops pidref_hash_ops; /* Has destructor call for pidref_free(), i.e. expects heap allocated PidRef as keys */