Skip to content

Recompute the owner of /proc/PID/{fd,fdinfo} and fd/N on every access. - #15426

Open
copybara-service[bot] wants to merge 1 commit into
masterfrom
test/cl994853358
Open

copybara-service[bot] wants to merge 1 commit into
masterfrom
test/cl994853358

Conversation

@copybara-service

@copybara-service copybara-service Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Recompute the owner of /proc/PID/{fd,fdinfo} and fd/N on every access.

The fd and fdinfo directories and the fd/N symlinks took their owner from the
task's credentials when the inode was created. /proc/PID entries are cached,
so a task that was looked up while root and then switched to another uid kept
a root-owned, mode 0500 /proc/PID/fd, and processes running as the new uid got
EACCES listing its fds. setpriv does exactly this (libcap-ng reads
/proc/self/status before setresuid), which breaks tools that map sockets to
processes through socket:[N] links (ss -p, lsof, fuser) when run as the
service user.

Linux recomputes the owner of /proc/PID entries on every revalidation
(fs/proc/base.c:pid_revalidate -> pid_update_inode -> task_dump_owner), and of
fd/N in fs/proc/fd.c:tid_fd_revalidate. The fd/N symlinks and the fdinfo
directory are now taskOwnedInodes like the rest of /proc/PID. The fd directory
keeps its same-thread-group permission exception and computes its owner the
same way.

Wrapping these inodes made them implement kernel.TaskOwnedInode, so
pidfd_send_signal and setns on them took the /proc/PID pidfd path and failed
with ESRCH. Files under /proc/PID are now rejected as on Linux:
pidfd_send_signal returns EBADF, and setns falls back to the nsfs check and
returns EINVAL. This also fixes the errno for files such as /proc/PID/status.

Tests: proc_test ProcPid.FdOwnerFollowsSetuid fails on runsc before this
change and passes on Linux. pidfd_test ProcPidFdinfoIsNotAPidfd,
ProcPidFdLinkIsNotAPidfd and ProcPidStatusIsNotAPidfd check the errnos.

@copybara-service copybara-service Bot added the exported Issue was exported automatically label Oct 7, 2026
@copybara-service
copybara-service Bot force-pushed the test/cl994853358 branch 3 times, most recently from d917ea4 to 1035690 Compare October 7, 2026 20:53
The fd and fdinfo directories and the fd/N symlinks took their owner from the
task's credentials when the inode was created. /proc/PID entries are cached,
so a task that was looked up while root and then switched to another uid kept
a root-owned, mode 0500 /proc/PID/fd, and processes running as the new uid got
EACCES listing its fds. setpriv does exactly this (libcap-ng reads
/proc/self/status before setresuid), which breaks tools that map sockets to
processes through socket:[N] links (ss -p, lsof, fuser) when run as the
service user.

Linux recomputes the owner of /proc/PID entries on every revalidation
(fs/proc/base.c:pid_revalidate -> pid_update_inode -> task_dump_owner), and of
fd/N in fs/proc/fd.c:tid_fd_revalidate. The fd/N symlinks and the fdinfo
directory are now taskOwnedInodes like the rest of /proc/PID. The fd directory
keeps its same-thread-group permission exception and computes its owner the
same way.

Wrapping these inodes made them implement kernel.TaskOwnedInode, so
pidfd_send_signal and setns on them took the /proc/PID pidfd path and failed
with ESRCH. Files under /proc/PID are now rejected as on Linux:
pidfd_send_signal returns EBADF, and setns falls back to the nsfs check and
returns EINVAL. This also fixes the errno for files such as /proc/PID/status.

Tests: proc_test ProcPid.FdOwnerFollowsSetuid fails on runsc before this
change and passes on Linux. pidfd_test ProcPidFdinfoIsNotAPidfd,
ProcPidFdLinkIsNotAPidfd and ProcPidStatusIsNotAPidfd check the errnos.
PiperOrigin-RevId: 994853358
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

exported Issue was exported automatically

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant