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

From: Andy Lutomirski

Date: Mon Jul 27 2026 - 06:37:13 EST




> On Jul 27, 2026, at 10:59 AM, Christian Brauner <brauner@xxxxxxxxxx> wrote:
>
> On 2026-07-27 00:57 -0700, Andy Lutomirski wrote:
>>>> On Jul 27, 2026, at 9:43 AM, Andy Lutomirski <luto@xxxxxxxxxxxxxx> wrote:
>>>
>>> 
>>>>
>>>> goes along way to getting Capsicum's "capability mode".
>>>
>>> One thing I dislike about this is that it’s (approximately) a task mode. Why should an fd representing a capability represent one capability (a subtree) to one task but a different capability (dotdot) in a different task? Do we need to prevent unsharing a userns if this bit is set? Do we want 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.
>>
>> Sigh, I keep thinking and typing OFD, and that won’t magically make 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.
>
> 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.
>

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 restriction 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 possibly do with it that needs to respect that restriction? Each such operation either needs to respect the restriction or fail outright. fchdir really ought to work. fchroot probably should, too. We could just not allow clone/mount (at first?). All the /proc links either start at cwd, root, or a struct file, right?

There are things like overlayfs layers, but failing an attempt to use a restrictive reference to a path as an overlayfs layer doesn’t seem to terrible to me.

I think that, logically, we could create a struct path_restrictions and add it to struct file and two copies to fs_struct. And we wire it up into nameidata. And we carefully make every operation that doesn’t understand this fail if there are restrictions, which could be some new nameidata flag meaning “I understand path restrictions” where any attempt to resolve a path starting at root or cwd or a struct file with restrictions that doesn’t set that flag will fail immediately without even trying to resolve the path.

My intuition is that the implementation wouldn’t be so bad and that people could chip away at the unsupported bits that annoy them over time.

—Andy