On 2024-03-19 16:53, Pádraig Brady wrote:
> but would appreciate a quick review of the fts_level usage in the second 
> patch.
> 
> thanks,
> Pádraig

In utilities that perform tree walks, there may be reasons why
not following links is a useful option, but it can't be relied on
for security.

Suppose Alice wants to traverse path /a/b/c where malicious Mallory is in
control of component b.

If Alice checks whether b is a symlink and refuses to follow it, she
suffers from a TOCtoTOU race. The b component can be a directory at the time
Alice checks, but just before Alice subsequently traverses it, Mallory
swaps it for a symlink.

(Sure, not following symlinks will defend against a passive attack,
whereby a user just plants a malicious symlink in a directory they
control and then waits.)

To do this correctly, we need a path-resolution function that carefully
avoids following any insecure/untrusted path component. (This could be
built into a secure version of nftw, as an optional behavior; nftw
itself should have a flag to not follow unsafe links, implemented with
the utmost security.) For this, open openat() with O_NOFOLLOW | O_PATH
can be used to go from component to component.

Nearly two years ago, I experimented with a solution that doesn't use
openat, but only classic POSIX calls, which I call safepath:

https://www.kylheku.com/cgit/safepath/

The basic idea is that we can traverse the path left to right, and
perform a security check at each step: "does a user other than me
control this directory, such that the next path component could go
anywhere at any time?" If the answer is no, the resolution can proceed
to the next component. Under this view, symlinks can be safe. E.g.
root can follow a symlink that only root can modify.


Reply via email to