Bug 269780 - O_RESOLVE_BENEATH succeeds on ".." on "/"
Summary: O_RESOLVE_BENEATH succeeds on ".." on "/"
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: Konstantin Belousov
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-02-23 13:34 UTC by Dan Gohman
Modified: 2024-01-20 21:41 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dan Gohman 2023-02-23 13:34:41 UTC
Thanks for adding the O_RESOLVE_BENEATH flag [0].

I do have one report of surprising behavior with it. It seems that opening ".." with a base fd referencing "/" succeeds. This is understandable, because ".." in the root directory refers to the root directory, and indeed it's not outside the base fd in that case.

However, use cases for O_RESOLVE_BENEATH would be better served by having an open of ".." with a base fd of the root directory fail. If one has path strings coming from an untrusted source, one wouldn't want the source to be able to tell where the base is in the overall filesystem namespace. If opening ".." at the top level succeeds, that reveals that the base directory is in fact the root directory.

For comparison, Linux's openat2's RESOLVE_BENEATH flag fails on ".." at the root.

[0]: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=248335
Comment 1 Konstantin Belousov freebsd_committer freebsd_triage 2023-02-23 13:47:53 UTC
What are the consequences of knowing that fd is root?
In other words, what could an adversary do knowing that, that she could not
do otherwise?

I do not want to introduce a special case in lookup() for this situation,
unless it is indeed a must.
Comment 2 Dan Gohman 2023-02-23 14:24:34 UTC
For example, if I have a network file server using O_RESOLVE_BENEATH to ensure that I'm only serving files within a certain directory, and the directory contains directories like "bin", "etc", and similar, attackers could tell whether I'm serving up my actual root directory or just some other directory that has root-like contents.

If it is my actual root directory, that might help them learn about the version or configuration of the system the server is running on. It may also reveal that the server is running FreeBSD, since the Linux with RESOLVE_BENEATH implementation and the portable-but-slow implementation I have both fail in this situation.
Comment 3 Konstantin Belousov freebsd_committer freebsd_triage 2023-02-23 15:00:44 UTC
The 'attacker' can try to fetch 'bin/ls' regardless of the behavior of /.. .
Comment 4 Dan Gohman 2023-02-23 15:10:56 UTC
If I'm not serving up my actual root directory, `bin/ls` might not be from the OS or architecture I'm running the server on.
Comment 5 Val Packett 2023-04-19 08:17:52 UTC
(In reply to Konstantin Belousov from comment #1)

It's not like the consequences are huge, but

- right now if there is a requirement to have consistent behavior in this obscure case across platforms, it's annoying to implement (every open call would need to waste a syscall probing whether the fd is the root like this, and falling back to a manual userspace implementation if that's the case)
- inside FreeBSD itself we might want the same consistency for implementing RESOLVE_BENEATH in Linuxulator?
Comment 6 Konstantin Belousov freebsd_committer freebsd_triage 2023-04-23 23:26:05 UTC
https://reviews.freebsd.org/D39773
Comment 7 commit-hook freebsd_committer freebsd_triage 2023-04-24 21:32:36 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=a718431c30a57226bc7c1a9181fc84bab00641a1

commit a718431c30a57226bc7c1a9181fc84bab00641a1
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2023-04-23 23:21:42 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-04-24 21:32:10 +0000

    lookup(): ensure that openat("/", "..", O_RESOLVE_BENEATH) fails

    PR:     269780
    Reported by:    Dan Gohman <dev@sunfishcode.online>
    Reviewed by:    emaste, markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D39773

 sys/kern/vfs_lookup.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)
Comment 8 commit-hook freebsd_committer freebsd_triage 2023-05-01 06:46:23 UTC
A commit in branch stable/13 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=16004e477d387d6a075597ec76f0dc82d02b60db

commit 16004e477d387d6a075597ec76f0dc82d02b60db
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2023-04-23 23:21:42 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-05-01 06:45:28 +0000

    lookup(): ensure that openat("/", "..", O_RESOLVE_BENEATH) fails

    PR:     269780

    (cherry picked from commit a718431c30a57226bc7c1a9181fc84bab00641a1)

 sys/kern/vfs_lookup.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)