Re: [PATCH RFC 4/7] fs: support FD_FAILFS_ROOT in fchroot()

Andy Lutomirski <[email protected]> Mon, 27 Jul 2026 12:23:04 +0200
Newsgroups org.kernel.vger.linux-api,org.kernel.vger.linux-doc,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>

> On Jul 27, 2026, at 10:59=E2=80=AFAM, Christian Brauner <[email protected]=
g> wrote:
>=20
> =EF=BB=BFOn 2026-07-27 00:57 -0700, Andy Lutomirski wrote:
>>>> On Jul 27, 2026, at 9:43=E2=80=AFAM, Andy Lutomirski <[email protected]=
et> wrote:
>>>=20
>>> =EF=BB=BF
>>>>=20
>>>> goes along way to getting Capsicum's "capability mode".
>>>=20
>>> One thing I dislike about this is that it=E2=80=99s (approximately) a ta=
sk mode. Why should an fd representing a capability represent one capability=
 (a subtree) to one task but a different capability (dotdot) in a different t=
ask?  Do we need to prevent unsharing a userns if this bit is set?   Do we w=
ant to have to worry about any task that could potentially SCM_RIGHTS and fd=
 to a task without that bit set? I prefer beneathness being an OFD property.=

>>=20
>> Sigh, I keep thinking and typing OFD, and that won=E2=80=99t magically ma=
ke it
>> be correct.  All these privilege restrictions applied to a file or
>> path reference need to follow every user-controllable reference around
>> correctly.  So if I fchdir or fchroot to a restricted OFD, my cwd or
>> root needs to preserve those restrictions, and reopening "/" or "." or
>> any other path (via root or cwd or openat etc) needs to respect the
>> restrictions as well.  Putting it in struct path may or may not be a
>> good idea.
>=20
> I think making struct path carry more meaning than it does right now
> will cause us endless amounts of subtle issues. I fear that change very
> very much. That will have such a fundamental ripple effect across _all_
> corners of the codebase that I'm very unwilling to be led down that
> road. And I think Al had traditionally similar reservations as me. One
> of the really thorny issues with the O_PATH upgrade masks was precisely
> the struct path modification.
>=20

The alternative (I think) is to enumerate all the places in the kernel that a=
 path (or file?) reference exists and would want to carry various restrictio=
n bits.

I can think of:

Resolution (nameidata?)

struct file

cwd

root

optionally, vfsmount

Is that it? If I open a directory with a no-dotdot restriction, what can I p=
ossibly do with it that needs to respect that restriction?  Each such operat=
ion either needs to respect the restriction or fail outright. fchdir really o=
ught to work. fchroot probably should, too.  We could just not allow clone/m=
ount (at first?).  All the /proc links either start at cwd, root, or a struc=
t file, right?

There are things like overlayfs layers, but failing an attempt to use a rest=
rictive reference to a path as an overlayfs layer doesn=E2=80=99t seem to te=
rrible to me.

I think that, logically, we could create a struct path_restrictions and add i=
t to struct file and two copies to fs_struct.  And we wire it up into nameid=
ata. And we carefully make every operation that doesn=E2=80=99t understand t=
his fail if there are restrictions, which could be some new nameidata flag m=
eaning =E2=80=9CI understand path restrictions=E2=80=9D where any attempt to=
 resolve a path starting at root or cwd or a struct file with restrictions t=
hat doesn=E2=80=99t set that flag will fail immediately without even trying t=
o resolve the path.

My intuition is that the implementation wouldn=E2=80=99t be so bad and that p=
eople could chip away at the unsupported bits that annoy them over time.

=E2=80=94Andy