[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