[<prev] [next>] [day] [month] [year] [list]
Message-ID: <rta37trkqzuvoim5muoukxmkbxcamlydwn6zfpm65k5qxyxb7y@pcq6nj54z6hl>
Date: Wed, 30 Jul 2025 10:22:23 +0200
From: Nicolas Bouchinet <nicolas.bouchinet@....cyber.gouv.fr>
To: linux-kernel@...r.kernel.org, linux-fsdevel@...r.kernel.org,
Jann Horn <jannh@...gle.com>
Cc: Nicolas Bouchinet <nicolas.bouchinet@....gouv.fr>
Subject: Re: [PATCH] fs: hidepid: Fixes hidepid non dumpable behavior
Hi Jann,
While documenting "hidepid=" I encountered those clunky behavior, which
I think we should not have.
Let say we set the "hidepid=" option to "invisible", processes will be fully
invisible to other users than root and the user that reads the procfs entry.
The fact that root is able to see every processes is partialy due to the fact
that the "gid=" variable is set to "0" by default :
```C has_pid_permissions
[...]
if (in_group_p(fs_info->pid_gid))
return true;
[...]
```
This means that if a process GID is in the group defined by the "gid=" option,
an authorization is directly returned, and the `ptrace_may_access()` function
is never called.
Thus, if one sets the "gid=" option to "1000", if a process is in this group,
it will now bypass the `security_ptrace_access_check()` hook calls.
This comes with the side effect that now, root will go through the
`ptrace_may_access()` checks and thus, if I have a root process without the
cap_sys_ptrace in its effective set, it will not be able to see other processes
anymore.
```C __ptrace_may_access
[...]
if (ptrace_has_cap(tcred->user_ns, mode))
goto ok;
rcu_read_unlock();
return -EPERM;
[...]
```
The following behavior thus happens :
```bash
$ sudo capsh --user=root --drop=cap_sys_ptrace -- -c /bin/bash
# mount -o remount,hidepid=2 /proc
# getpcaps $$
=ep cap_sys_ptrace-ep
# ps aux
root 1 0.0 0.1 204724 1404 ? S 09:43 0:00 /usr/lib/python3.13/site-packages/virtme/guest/bin/virtme-ng-init
root 2 0.0 0.0 0 0 ? S 09:43 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 09:43 0:00 [pool_workqueue_release]
[...]
# mount -o remount,hidepid=2,gid=1000 /proc
# getpcaps $$
=ep cap_sys_ptrace-ep
# ps aux
root 621 0.0 0.2 8656 2556 pts/0 S 09:46 0:00 /bin/bash
root 641 0.0 0.4 9592 4012 pts/0 R+ 10:03 0:00 ps aux
root 642 0.0 0.2 6896 2452 pts/0 S+ 10:03 0:00 less
```
This also means that if a process accesses were controled by an LSM, lets say
with the `audit ptrace` option of AppArmor, they magically disappears for the
process in the group defined in the "gid=" hidepid option and those controls
are "transfered" to root, which was not controlled at first.
Also, note that with "hidepid=ptraceable", the "gid=" option is ignored
and `ptrace_may_access()` is always called.
Shouldn't we always check for the "gid=0" and also call the
`security_ptrace_access_check()` even if the group is set ?
Best regards,
Nicolas
Powered by blists - more mailing lists