On Tue, Mar 04, 2025 at 06:34:56PM +0100, Oleg Nesterov wrote: > On 03/04, Christian Brauner wrote: > > > > + task = get_pid_task(pid, PIDTYPE_PID); > > + if (!task) { > > + if (!(mask & PIDFD_INFO_EXIT)) > > + return -ESRCH; > > + > > + if (!current_in_pidns(pid)) > > + return -ESRCH; > > Damn ;) could you explain the current_in_pidns() check to me ? > I am puzzled... So we currently restrict interactions with pidfd by pid namespace hierarchy. Meaning that we ensure that the pidfd is part of the caller's pid namespace hierarchy. So this check is similar to: pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns) { struct upid *upid; pid_t nr = 0; if (pid && ns->level <= pid->level) { upid = &pid->numbers[ns->level]; if (upid->ns == ns) nr = upid->nr; } return nr; } IOW, we verify that the caller's pid namespace can be found within the pid namespace hierarchy that the struct pid had a pid numbers allocated in. Only that by the time we perform this check the pid numbers have already been freed so we can't use that function directly. But the pid namespace hierarchy is still alive as that won't be released until the pidfd has put the reference on struct @pid. So we can use current_in_pidns(). Is that understandable?