Open Bug 1607980 Opened 5 years ago Updated 9 months ago

Implement sandboxing on FreeBSD with Capsicum

Categories

(Core :: Security: Process Sandboxing, enhancement, P5)

Desktop
FreeBSD
enhancement

Tracking

()

Tracking Status
firefox74 --- affected

People

(Reporter: val, Unassigned)

References

Details

Attachments

(1 file)

My latest work in progress… sandboxing content with Capsicum capability mode on FreeBSD.

The idea behind Capsicum is treating file descriptors as capabilities. Once a process enters capability mode, it's in a very tight sandbox that does not have any access whatsoever to "global namespaces" — no open, connect, nothing like that — you can only derive new file descriptors from the ones you have: openat (open below a directory if you have the directory opened), connectat and other *at calls, accept, recvmsg (IPC fd-passing), dup and so on. Descriptors can have additional irreversible restrictions imposed by cap_rights_limit, and these limits are inherited all the way (e.g. if a directory fd was limited to not having CAP_WRITE, you won't be able to write to anything you openat from that directory).

Most software was not written in this capability style unfortunately, so we have to LD_PRELOAD a library that overrides libc functions with ones that try to use pre-opened directory descriptors. One such library is https://github.com/musec/libpreopen (which has been partially reused in WASI libc!) — but it's overkill for our use in some ways (we don't impose sandboxing on unsuspecting programs so we don't need to serialize the info about opened fds to shared memory) and not enough in other ways (sysctl, fopen/opendir, symlink resolution, etc.) and it's all C and it's just better to own the code here, so I added a little mozcapsicum library.

This is a work in progress. It mostly works already, but it only supports Wayland for now. Forkserver (bug 1607103) works, actually I've only tested with it enabled. GPU accelerated WebGL content works (tested on Mesa RadeonSI). Audio works with PulseAudio. Various other things (X11, sndio, multi-GPU, nvidia GPU?) are not tested/supported yet. Some paths are hardcoded, etc.

Requires patch from bug 1550891.

Currently dealing with a very VERY VERY weird bug: SecurityInformation fails to deserialize in the HttpChannelChild! Disabled assertion for now, but this is terrible. Can anyone help me debug this?

do not commit yet, see bug for info

See Also: → 1550891
See Also: → 1607103

Currently dealing with a very VERY VERY weird bug: SecurityInformation fails to deserialize in the HttpChannelChild! Disabled assertion for now, but this is terrible. Can anyone help me debug this?

Do you have more specifics on the problem you're seeing?

Status: UNCONFIRMED → NEW
Ever confirmed: true
Priority: -- → P5

Oh, just had to do was to use a debug build:

[Child 77196, Main Thread] WARNING: 'NS_FAILED(rv)', file /usr/home/greg/src/hg.mozilla.org/mozilla-unified/toolkit/components/resistfingerprinting/nsRFPService.cpp, line 355

and that's getting the @mozilla.org/security/random-generator;1 service.

That's because NSS_NoDB_Init(nullptr) != SECSuccess when initializing NSS.

And NSS needs to dlopen by path (and in development everything is in its own dir like …/security/nss/lib/freebl/freebl_freebl3) and to open /dev/urandom (even though there's getentropy/getrandom). I have it working with some extra preloading now..

…yeah, that was also affecting WebCrypto by the way.


tested X11 (Xwayland), it does work. (glxtest failed but I'm pretty sure that's my weird setup; webgl.force-enabled showed that even WebGL works)

other things discovered by debug build:

MOZ_ASSERT_UNREACHABLE("PR_GetPhysicalMemorySize not implemented here") in image/SurfaceCache.cpp because it uses sysctl and my hook for that doesn't work right now. Changing it to sysconf (the Linux/Solaris code) which uses sysctlbyname makes it work easily. Probably would make sense to kill the sysctl section because I think all BSDs support sysconf for this.

js::GetNativeStackBaseImpl() sometimes fails MOZ_ASSERT(stackBase) but that doesn't seem to affect anything.

huh, if PulseAudio is not running yet, Firefox tries to start it from the content process (which is not possible when sandboxed of course). Well, I guess more like libpulse does that. Dang.

After a recent rebase, looks like it starts PulseAudio fine now, but NS_GRE_DIR broke o_0

// in a recent commit I see that Windows is preloading nss/softokn/freebl for the network process, hmm, I should try dlopen-before-cap_enter instead of shoving more things into LD_PRELOAD

media.cubeb.backend=alsa doesn't work here at least without env MOZ_CAPSICUM=1. Hiding ipc/glue/GeckoChildProcessHost.cpp changes behind PR_GetEnv() seems to help.

Severity: normal → S3

Val, did you abandon your work on the freebsd sandbox? Maybe you have at least some work to share?

(In reply to 6yearold from comment #7)

Val, did you abandon your work on the freebsd sandbox? Maybe you have at least some work to share?

Sort of, I've had a lot of time away from it; but I'm convinced that LD_PRELOAD trickery kinda sucks and we have to implement facilities in the OS to allow AT_FDCWD ("global" filesystem access as not-really-global) in the sandbox first. See https://reviews.freebsd.org/D38351

What do you think about "pledge" and "unveil" from OpenBSD? This should allow us to reuse OpenBSD sandbox implementation.

There is already an ongoing work on that: https://reviews.freebsd.org/D35116 and https://github.com/Math2/freebsd-pledge/

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: