Re: [PATCH] pidfd: hold exec_update_lock around namespace ioctl
Jann Horn <[email protected]> Mon, 3 Aug 2026 15:44:21 +0200
| Newsgroups | org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kernel.vger.stable |
|---|---|
| Message-ID | <CAG48ez2YssN-F9DHHskmiWORTnaBPUUyixqufD-L5VkW96Uv4Q@mail.gmail.com> |
On Fri, Jul 31, 2026 at 4:50=E2=80=AFPM Chen Linxuan via B4 Relay <[email protected]> wrote: > The PIDFD_GET_*_NAMESPACE ioctls in pidfd_ioctl() perform a filesystem > credentials ptrace access check before handing out a namespace file > descriptor. The accompanying comment states that the code "mirrors nsfs > behavior", but, unlike the corresponding procfs paths, it does so without > holding the target task's exec_update_lock. > > proc_ns_get_link() and proc_ns_readlink() both take exec_update_lock for > reading around the ptrace check and the namespace lookup, so that the > credentials used for the access decision match those of the task when its > namespace is read. Without it, a caller can pass the check against the > target's old credentials and then read the namespace after the target has > execve()'d a setuid binary and committed new credentials -- accessing > namespace information it should have been denied. > > Hold exec_update_lock for reading around the ptrace check and the > namespace lookup so that pidfd truly mirrors nsfs behavior, as the commen= t > already claims. open_namespace() itself runs outside the lock: once a > namespace reference is obtained it carries its own refcount and is opened > with the caller's own credentials, so a concurrent execve() on the target > can no longer affect the outcome. I think this makes sense. Given that the rest of this function is written with scope-based cleanup (https://docs.kernel.org/core-api/cleanup.html), I wonder if this patch would look cleaner if it also used scope-based cleanup... that documentation also says: "Lastly, given that the benefit of cleanup helpers is removal of =E2=80=9Cgoto=E2=80=9D, and that the =E2=80=9Cgoto=E2=80=9D statement can j= ump between scopes, the expectation is that usage of =E2=80=9Cgoto=E2=80=9D and cleanup helpers is = never mixed in the same function." But we probably shouldn't be holding the exec_update_lock across the open_namespace() call... so I guess this will require either refactoring this function into two, or indenting most of the function body, or some explicit "drop this guard" operation. @Christian, do you have an opinion on this?