Use of pidfd_open in pidwait is racy
The pid can be killed and reused in between reading the procfs entry and the call to pidfd_open
. The only race-free way to do this seems to be specified here: https://lkml.org/lkml/2019/3/31/249
int pidfd = pidfd_open(pid, 0);
int pid = parse_fdinfo("/proc/self/fdinfo/<pidfd>");
int procpidfd = open("/proc/<pid>", ...);
/* Test if process still exists by sending signal 0 through our pidfd. */
int ret = pidfd_send_signal(pid, 0, NULL, PIDFD_SIGNAL_THREAD);
if (ret < 0 && errno == ESRCH) {
/* pid has been recycled and procpidfd refers to another process */
}
Parsing the entry in fdinfo
is not needed, but the basic method is similar:
- Open the procfs directory at
/proc/<pid>
- Open the pid with
pidfd_open
- Call
fstat
on the procfs fd - If the pidfd is valid but we get an error from the
fstat
, then fail and skip the pid, it has been recycled
This is dependent on !120 because that includes the relevant openat
bits.
Edited by zxzax