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

Aleksa Sarai <[email protected]> Thu, 16 Apr 2026 22:30:51 +1000
Newsgroups dev.linux.lists.containers,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
--g4e6jdjfuqjlg5v6
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-13, Alexey Gladkov <[email protected]> wrote:
> When procfs is mounted with the subset=3Dpid option, all system files and
> 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 mounting
> is performed with the subset=3Dpid option.
>=20
> Signed-off-by: Alexey Gladkov <[email protected]>
> ---

> -static bool mount_too_revealing(const struct super_block *sb, int *new_m=
nt_flags)
> +static bool mount_too_revealing(struct fs_context *fc, int *new_mnt_flag=
s)
>  {
>  	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 super_=
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_fl=
ags));
>  }

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.

I think the solution is quite simple -- you can also skip super-blocks
that have fc->skip_visibility set in mnt_already_visible().

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.)

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/

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

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

iJEEABYKADkWIQS2TklVsp+j1GPyqQYol/rSt+lEbwUCaeDWexsUgAAAAAAEAA5t
YW51MiwyLjUrMS4xMiwyLDIACgkQKJf60rfpRG90iAEA93c0gDehfxRlp75MhzTM
v/MZsJzl3wFZ1PJGDwxu/F8A/2zAckjBOq/ekPcAbQB8/FQ10aToBdRsPiKD3Q7R
MFMA
=365J
-----END PGP SIGNATURE-----

--g4e6jdjfuqjlg5v6--