[PATCH v6] linux: Add openat2 (BZ 31664)

Paul Eggert eggert@cs.ucla.edu
Thu Nov 20 03:08:10 GMT 2025


On 2025-11-18 15:54, Aleksa Sarai wrote:
 > For syscalls without AT_EMPTY_PATH, you can use /proc/self/fd/$n.

Only if /proc is mounted, unfortunately.

On 2025-11-18 21:48, Aleksa Sarai wrote:
> On 2025-11-18, Paul Eggert <eggert@cs.ucla.edu> wrote:
>> OK, but why is ".." special? A racing mount or rename can cause any file
>> name component to escape the "top-level" (dirfd argument) directory. Even
>> "." can escape, if the directory "." names is nearly-simultaneously moved to
>> be outside dirfd's tree.
> 
> We have a final path_is_under() check which will catch that in trivial
> cases (mainly intended to proactively find bugs), but the philosophy was
> that we wanted to make sure you couldn't walk into a path that was
> *always* outside the scope of the root.

No doubt I'm missing something, but it seems to me that the final 
path_is_under() check (assuming it's "atomic" enough) is necessary. 
Otherwise you might have a scenario like this:

   victim:
     mkdir d d/e v v/w
     # (The attacker's openat gains access to "e" here; then:)
     mv d/e v/e
     mv v/w v/e/w
     # (The attacker's openat gains access to "w" here.)

   Nearly-simultaneously, in another process:
     jailer:
       jailroot = openat (AT_FDCWD, "d", O_PATH|O_DIRECTORY);
     then attacker:
       w = openat (jailroot, "e/w", O_PATH|O_DIRECTORY);

In this case, if the attacker walks down the "e/w" path at just the 
right time, the attacker will gain access to w even though w was never 
at any time subsidiary to the jailroot directory d. The final 
path_is_under() check is needed to prevent this attack from succeeding.

 From the above, it appears that the RESOLVE_BENEATH and RESOLVE_IN_ROOT 
mechanisms make an important security assumption, namely:

* The victim never moves any file out of the jail.

(By "file" I mean any kind of file, including a directory.) Am I right 
about this being a security assumption? (Is this stuff documented anywhere?)

Because if we make this assumption, I don't see how ".." is a problem. 
The namei function can reject ".." if it is at the jailroot, and accept 
it otherwise. What am I missing?



More information about the Libc-alpha mailing list