1. 23
  1.  

  2. 4

    I personally find this API fairly frustrating. This call can have three different semantics, depending on the values and context in which you call it. This contributes to complexity.

    I notice that in the userspace diff, the “lock unveil” functionality is never used, even in cases where unveil is added to the pledge string. As far as I understand it, this means that if an attack obtained code execution, they’d simply be able to undo the unevil with unveil("/", "rwx"). That’s unintuitive and likely to be a regular source of programming errors.

    Grabbing some comments I made on IRC last night on how I’d persue this API:

    22:10:09 <Alex_Gaynor> If I was doing this API, I'd probably do `sandbox_context *sandbox_context_create(void)` and then a bunch of `sandbox_context_add_X(sandbox_context *, ...)` with appropriate signatures, and then a `sandbox_context_apply(sandbox_context *)` and basically a default `sandbox_context` had no permissions, and then you can add back whatever you want, and calling `sandbox_apply` a second time on a process killed the process or something
    22:10:34 <Alex_Gaynor> (Or maybe was allowed, as long as the permissions were a strict subset of what was already applied)
    22:12:33 <Alex_Gaynor> Oh, and they should add a platform-specific `posix_spawn_...` thing to take a `sandbox_context` so that it's applied right at `exec`, before any user code runs.
    22:13:23 <Alex_Gaynor> Basically the two properties I've found useful in sandboxing are: a) It should be extremely easy to see what capabilities your process has, you want them all in one place, and defaulted to "nothing" so basically the permissions are what you have written down, b) It should be extremely easy to draw a perimeter around what your process already does, and slowly wittle it down by basically deleteing "adds".
    
    1. 2

      I notice that in the userspace diff, the “lock unveil” functionality is never used, even in cases where unveil is added to the pledge string.

      I only saw two or three diffs where it isn’t clear if the unveil pledge is later revoked. All others that add unveil to pledge also have a pledge without unveil soon after the unveil calls. It’s possible the two or three cases also have it but it’s just not visible in the diff.

      So in these programs, that attack does not work unless you get your RCE during the initialization phase.

      Even if unveil was never locked, it can still protect against all-too-common path traversal style bugs (especially in web crapps) that leak data without RCE.

    2. 3

      I’m so happy to read about the progress on this, we need this on linux though! Who is interested in developing this?

      1. 4

        I’d assume that the answer you’d get if you ask a Linux kernel developer is “use SELinux or AppArmor”.

        But if we’re wishing for arbitrary things, then I’d also like for strlcpy, strlcat and the arc4random family to be an actual part of POSIX and subsequently adopted by glibc/Linux.

        1. 3

          Or Smack for those favoring simplicity. Looking at the link, I just found out it got big in automotive Linux, too.

        2. 3

          The closest equivalent on Linux are probably the systemd filesystem sandboxing options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ReadWritePaths=

          1. 2

            I think it’d be easier to make OpenBSD as good as Linux. I’m not sure what it’s missing, though. Momentum, I guess.

            1. 5

              Culture and priorities are different. Linux’s specifically targets what brings in mainstream and corporate audiences. OpenBSD explicitly rejects a lot of that to be simpler, more UNIX like, or quality/security. Lastly, there’s more attempts to sell Linux-based systems that generate revenue that can fund development.

          2. 2

            In general, I agree with the idea and setup of unveil() though I havn’t had much time to experiment with it yet. Something that irks me a bit though is that there doesn’t seem to be a way to hide a previously unveiled path - either that or I am greatly misreading the man page.

            The case I have in mind is that I have a set of namespaces (so paths) that are conditionally accessible (on path and rwx- mode) based on where the call originates from (function in user provided scripting interface) and these may need to route through third party libraries, thus I routinely want to mask/unmask path - so where’s reveil()? :-)

            1. 15

              The idea is you structure your program so it isn’t bouncing between privilege levels. It should not be possible to ever climb back out of a position of limited access. Sometimes this means using something like privilege separation where different processes work together, passing file descriptors, etc.

              1. 2

                I understand that and to the largest extent possible given other constraints I do privsep and juggle descriptors around, but in those cases I can typically pledge without rpath/wpath so the value of unveil there is rather limited.

                Think of trying to unveil-harden something like Wireshark as it has a similar pattern to what I’m describing - there is some ‘light’ privsep in the form of the Lua interpreter/JIT: when the process is in that execution context, few file operations should really be exposed, possibly some temp- store. The other execution context, so the “engine”, need to be able to load / save from a much wider set of paths. Sure it can be resectioned into better process privsep etc. but the amount of work gets substantial and would lead to the same situation as above, rpath/wpath likely won’t be needed.

                1. 2

                  I would just use something like capnproto across processes.

                  1. 1

                    Yeah, the microkernels like OKL4 used an IDL with tools like CAmkES to get components to work with each other. Far as Cap n Proto, I actually recommended that same thing to people wanting to build stuff on separation kernels after talking to its author, Kenton Varda. He was definitely well-read on capability-security research and projects. Inspires confidence. The other cool thing is you don’t give up performance to get security with Cap’ n Proto. I love it when that happens.