Re: [PATCH v4] Add a "nosymfollow" mount option.
From: Ross Zwisler
Date: Fri Jan 31 2020 - 16:20:30 EST
On Fri, Jan 31, 2020 at 12:51:34PM +1100, Aleksa Sarai wrote:
> On 2020-01-30, Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote:
> > On Thu, Jan 30, 2020 at 05:27:50PM -0700, Ross Zwisler wrote:
> > > For mounts that have the new "nosymfollow" option, don't follow
> > > symlinks when resolving paths. The new option is similar in spirit to
> > > the existing "nodev", "noexec", and "nosuid" options. Various BSD
> > > variants have been supporting the "nosymfollow" mount option for a
> > > long time with equivalent implementations.
> > >
> > > Note that symlinks may still be created on file systems mounted with
> > > the "nosymfollow" option present. readlink() remains functional, so
> > > user space code that is aware of symlinks can still choose to follow
> > > them explicitly.
> > >
> > > Setting the "nosymfollow" mount option helps prevent privileged
> > > writers from modifying files unintentionally in case there is an
> > > unexpected link along the accessed path. The "nosymfollow" option is
> > > thus useful as a defensive measure for systems that need to deal with
> > > untrusted file systems in privileged contexts.
> >
> > The openat2 series was just merged yesterday which includes a
> > LOOKUP_NO_SYMLINKS option. Is this enough for your needs, or do you
> > need the mount option?
>
> I have discussed a theoretical "noxdev" mount option (which is
> effectively LOOKUP_NO_XDEV) with Howells (added to Cc) in the past, and
> the main argument for having a mount option is that you can apply the
> protection to older programs without having to rewrite them to use
> openat2(2).
Ah, yep, this is exactly what we're trying to achieve with the "nosymfollow"
mount option: protect existing programs from malicious filesystems without
having to modify those programs.
The types of attacks we are concerned about are pretty well summarized in this
LWN article from over a decade ago:
https://lwn.net/Articles/250468/
And searching around (I just Googled "symlink exploit") it's pretty easy to
find related security blogs and CVEs.
The noxdev mount option seems interesting, bug I don't fully understand yet
how it would work. With the openat2() syscall it's clear which things need to
be part of the same mount: the dfd (or CWD in the case of AT_FDCWD) and the
filename you're opening. How would this work for the noxdev mount option and
the legacy open(2) syscall, for example? Would you just always compare
'pathname' with the current working directory? Examine 'pathname' and make
sure that if any filesystems in that path have 'noxdev' set, you never
traverse out of them? Something else?
If noxdev would involve a pathname traversal to make sure you don't ever leave
mounts with noxdev set, I think this could potentially cover the use cases I'm
worried about. This would restrict symlink traversal to files within the same
filesystem, and would restrict traversal to both normal and bind mounts from
within the restricted filesystem, correct?
> However, the underlying argument for "noxdev" was that you could use it
> to constrain something like "tar -xf" inside a mountpoint (which could
> -- in principle -- be a bind-mount). I'm not so sure that "nosymfollow"
> has similar "obviously useful" applications (though I'd be happy to be
> proven wrong).
In ChromeOS we use the LSM referenced in my patch to provide a blanket
enforcement that symlinks aren't traversed at all on user-supplied
filesystems, which are considered untrusted. I'd essentially like to build on
the protections offered by LOOKUP_NO_SYMLINKS and extend that protection to
all accesses to user-supplied filesystems.
> If FreeBSD also has "nosymfollow", are there many applications where it
> is used over O_BENEATH (and how many would be serviced by
> LOOKUP_NO_SYMLINKS)?
Sorry, I don't have any good info on whether nosymfollow and O_BENEATH are
commonly used together in FreeBSD.