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.
+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);
}
static void pidref_hash_func(const PidRef *pidref, struct siphash *state) {
siphash24_compress(&pidref->pid, sizeof(pidref->pid), state);
}
int pidref_kill_and_sigcont(PidRef *pidref, int sig);
int pidref_sigqueue(PidRef *pidfref, int sig, int value);
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 */
#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 */