Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Feb 2022 09:13:07 +0000
From:      David Chisnall <theraven@FreeBSD.org>
To:        Matthias Apitz <guru@unixarea.de>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: how to restrict file access below some top directory
Message-ID:  <7DAD732E-BCE7-4D3A-B259-418FFA70BBC1@FreeBSD.org>
In-Reply-To: <YgTL9tf0EaX3%2BD3Q@pureos>
References:  <YgTL9tf0EaX3%2BD3Q@pureos>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi,

> On 10 Feb 2022, at 08:25, Matthias Apitz <guru@unixarea.de> wrote:
>=20
> I want restrict in a C- or Perl-written application the file access to
> only files below some top directory, say
>=20
> 	/var/spool/dir/
>=20
> and not allowing, for example, access to =
/var/spool/dir/../../../etc/passwd
> Ofc, this could be done easy with chroot(2), but this would require =
root
> permision. Any other ideas?

There are (at least?) four ways of doing this with FreeBSD:

You can use chroot.  This provides a simple redefinition of the root of =
the filesystem.  All dependencies (shared libraries and so on) must be =
below the new root.  You can use nullfs mounts to set up this hierarchy =
to include read-only views of existing things (such as /lib, /usr/lib).  =
Note that chroot doesn=E2=80=99t restrict anything other than the =
filesystem namespace.  SysV IPC, sockets, and so on are unrestricted.  =
Note that you must be root to enter a chroot, but root can fairly easily =
escape from the chroot, so you need to setuid after entering it.



You can use a jail:

https://docs.freebsd.org/en/books/handbook/jails/

This has the same set of requirements as a chroot (the process can=E2=80=99=
t access anything outside of the new root, so the new root must have all =
support files needed) but gives you a much more complete environment.  =
You can restrict access to the network and other IPC namespaces to the =
jail and you can also have multiple user accounts inside.  Root in a =
jail is not the same as root outside and (modulo kernel bugs), root in =
the jail can=E2=80=99t escape, so it=E2=80=99s safe to run things as =
root in the jail.



You can write a MAC policy that restricts access to the hierarchy:=20

https://docs.freebsd.org/en/books/handbook/mac/

This has the advantage that it=E2=80=99s non-invasive and makes it =
possible to poke holes in the restriction for things like shared =
libraries but writing the policy can be complex.  The BSD Extended MAC =
policy provides firewall-like rules that let you constrain a user to a =
subset of the filesystem, which is probably the simplest way of writing =
this kind of policy.

https://www.freebsd.org/cgi/man.cgi?query=3Dmac_bsdextended



You can use Capsicum:

https://www.freebsd.org/cgi/man.cgi?query=3Dcapsicum

This requires source-code modification.  Once you call `cap_enter`, you =
have no access to any global namespace (filesystem, IPC, network, and so =
on) but if you=E2=80=99ve opened /var/spool/dir then you can use =
`openat` to open files below that location in the filesystem namespace.  =
You can also apply fine-grained restrictions to file descriptors (for =
example, granting read-only access to certain directories or append-only =
access to certain files).  We=E2=80=99re using this in Verona with a =
lightweight RPC mechanism to invoke untrusted shared libraries and proxy =
any calls to access things in the global that they need (open, connect, =
bind) to the parent process, which can enforce policy.

David




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?7DAD732E-BCE7-4D3A-B259-418FFA70BBC1>