Re: [PATCH v9 4/5] proc: Skip the visibility check if subset=pid is used

Aleksa Sarai <[email protected]> Thu, 16 Apr 2026 22:46:50 +1000
Newsgroups dev.linux.lists.containers,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
--bv5tgnqdlabxgz4a
Content-Type: text/plain; protected-headers=v1; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
Subject: Re: [PATCH v9 4/5] proc: Skip the visibility check if subset=pid is
 used
MIME-Version: 1.0

On 2026-04-16, Aleksa Sarai <[email protected]> wrote:
> On 2026-04-13, Alexey Gladkov <[email protected]> wrote:
> > When procfs is mounted with the subset=3Dpid option, all system files a=
nd
> > directories from the root of the filesystem are not accessible in
> > userspace. Only dynamic information about processes is available, which
> > cannot be hidden with overmount.
> >=20
> > For this reason, checking for full visibility is not relevant if mounti=
ng
> > is performed with the subset=3Dpid option.
> >=20
> > Signed-off-by: Alexey Gladkov <[email protected]>
> > ---
>=20
> > -static bool mount_too_revealing(const struct super_block *sb, int *new=
_mnt_flags)
> > +static bool mount_too_revealing(struct fs_context *fc, int *new_mnt_fl=
ags)
> >  {
> >  	const unsigned long required_iflags =3D SB_I_NOEXEC | SB_I_NODEV;
> >  	struct mnt_namespace *ns =3D current->nsproxy->mnt_ns;
> > +	const struct super_block *sb =3D fc->root->d_sb;
> >  	unsigned long s_iflags;
> > =20
> >  	if (ns->user_ns =3D=3D &init_user_ns)
> > @@ -6388,7 +6387,7 @@ static bool mount_too_revealing(const struct supe=
r_block *sb, int *new_mnt_flags
> >  		return true;
> >  	}
> > =20
> > -	return !mnt_already_visible(ns, sb, new_mnt_flags);
> > +	return (!fc->skip_visibility && !mnt_already_visible(ns, sb, new_mnt_=
flags));
> >  }
>=20
> Unless I'm missing something (I haven't tested this locally yet, sorry),
> this will allow you to bypass mount_too_revealing() even for
> non-subset=3Dpid mounts because once you create a subset=3Dpid mount then=
 a
> regular procfs mount will see the subset=3Dpid mount and permit it.
>=20
> I think the solution is quite simple -- you can also skip super-blocks
> that have fc->skip_visibility set in mnt_already_visible().

I now see that check was present in v8 but I guess its importance wasn't
obvious. I guess this means we will need to reintroduce
SB_I_USERNS_ALLOW_REVEALING. :/

> Unfortunately, the fact that both subset=3Dpid and fully-loaded procfs
> look like the same type (procfs) to mnt_already_visible() is something
> people have already exploited in userspace. (The k8s workaround from a
> long time ago used subset=3Dpid from a dead pidns to stop the mount from
> being useful to an attacker while still bypassing mount_too_revealing().
> That being said, that workaround was removed a long time ago and I don't
> know how widespread this is.)
>=20
> I'd be happy to give it a shot but if it breaks userspace we might need
> a new mount option to work around it...

--=20
Aleksa Sarai
https://www.cyphar.com/

--bv5tgnqdlabxgz4a
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iJEEABYKADkWIQS2TklVsp+j1GPyqQYol/rSt+lEbwUCaeDaOhsUgAAAAAAEAA5t
YW51MiwyLjUrMS4xMiwyLDIACgkQKJf60rfpRG+yTQD/dOdJmE6eRydxRawQeXBM
jYb0iaA2T7Mu6WxQRMx8reYA/jHzQBeyi8J1/9e+dVKZQmoeZa0Lcmj48tCPUZ1V
4IwE
=7nDS
-----END PGP SIGNATURE-----

--bv5tgnqdlabxgz4a--