Hacker News new | more | comments | ask | show | jobs | submit login
Capsicum (vexillium.org)
134 points by adamnemecek 3 months ago | hide | past | web | favorite | 32 comments



Capsicum is difficult to use, and has never been used to its full potential in FreeBSD.

OpenBSD's pledge(2) and unveil(2) by comparison are seeing far greater usage, covering somewhere between 85% to 90% of the base operating system. Patches for 3rd party software, and programming languages are also appearing upstream, as they also serve as helpful annotation for other mechanisms and encourage privilege separation.

https://man.openbsd.org/pledge

https://man.openbsd.org/unveil

https://gist.github.com/ligurio/f6114bd1df371047dd80ea9b8a55...


You are overestimating technology and underestimating organization.

OpenBSD is a tightly nit (at least philosophically) group with a single leader.

FreeBSD is a loose federation of large commercial users, academics and industrial researchers, and end users with a broad range of needs and a bureaucratic core team without any one leader.

Let's buy your comment and say Capsicum is harder to use. Let's hypothetically say it takes twice as long to implement in an application. The FreeBSD community could easily absorb that cost, but there is nobody with earned or assumed authority pointing people in the direction to achieve that high base coverage. As in the original article, the author is doing this in his spare time and there are only a couple other people that assist occasionally. On the other hand Theo has made it a point to achieve high coverage, and quickly, for OpenBSD's new APIs.

The sandboxing functionality is philosophically important to most of the OpenBSD organization, and only seen as important to a small subset of FreeBSD's heavy movers. So that is why you see much lower application coverage.


nit: it's knit not nit


The difference is that while Capsicum provides you with very solid, easy to reason about protection model. Meanwhile... can you still escape the pledge by reexecuting yourself?


I haven't tried to pledge any software, but I did try to capsicum a proxy daemon, which I wasn't able to do, because there isn't a reasonable way to limit everything, except for networking. I would have had to move socket creation into a different (unsandboxed) process and then pass the sockets around to the proxy worker processes. This is doable, but a lot of work and could impact performance, so I ended up not doing it; the process was already running as a statically linked binary non-root in a jail with no other executables, but it would have been nice to remove more things.


This weak argument from FreeBSD people is getting rather tiresome.

You can only call fork/exec if it's part of the pledge(2) promises, which you can later drop with subsequent calls to pledge. And with unveil(2) or even chroot(2) you can also place further restrictions on which binaries can be executed, and in which directories.

Systems like Capsicum would have you not be able to sandbox those programs at all. Users are left unprotected. So yes, if you pledge(2) a shell. It can call exec, but directly it can't call socket/connect(2), and the reduction of kernel attack surface is still significant. Software using privilege separation can safely leverage this.


Thing is, with pledge you never really know what the promises actually are, or if they make sense, in that you cannot work around them. With Capsicum (or any other capability system) you can.

The assumption that with Capsicum you wouldn’t be able to sandbox stuff is blatantly false. The proof is existing code - Chromium, Tor, or Irssi - that has been capsicumized, often much more easily than with seccmp (I’ve not seen that comparison with pledge(2) yet).

One advantage that pledge(2) certainly has is the community involvement. OpenBSD has applied pledge(2) in many places, while capsicum(4) was quite a bit slower until recently. This has nothing to do with technical differences, and more with the social aspects.


> Thing is, with pledge you never really know what the promises actually are, or if they make sense, in that you cannot work around them.

This makes no sense. Of course you know what the promises are, they're in the source code. You can also use ktrace/kdump(1) or even strings(1). The names of the promises are obvious and their intention is clear. There are subsets of POSIX.

> The assumption that with Capsicum you wouldn’t be able to sandbox stuff is blatantly false.

That is not what I said, I was specifically correcting your misinformed statement regarding pledge(2) and those programs that explicitly permit exec, like shells. Capsicum has no solution for this, and as such these programs cannot be sandboxed on FreeBSD.


> The names of the promises are obvious and their intention is clear. There are subsets of POSIX.

That's true, but not really the whole truth. Take "dns", for instance. It enables a number of system calls needed to perform DNS resolution. But as far as I understand, those system calls (sendto(2) for example) can then be used arbitrarily. So "dns" actually permits more than the name implies.

On the other hand, when a program is running in capability mode, we know exactly what is permitted and what isn't.

> Capsicum has no solution for this, and as such these programs cannot be sandboxed on FreeBSD.

... they can't be sandboxed on OpenBSD either. pledge("proc exec") doesn't give you a sandbox.


Hi, that is not true. The "dns" promise only allows sockets with the SOCK_DNS option, the kernel restricts access to only DNS type operations and port numbers (enough for libc to do DNS). The kernel tries to separate pledges as tightly as possible, with many checks:

    SOCK_DNS
        For domains AF_INET or AF_INET6, only allow connect(2), sendto(2), or sendmsg(2) to the DNS port (typically 53).
https://man.openbsd.org/socket


Ok, so that's tighter than what I said, but my point still stands.


What does it mean to sandbox a shell?


"Towards oblivious sandboxing with Capsicum" describes a capability-aware shell: https://www.engr.mun.ca/~anderson/publications/2017/towards-...


What the paper describes isn't really a shell; it's just a launcher for running capsicum-naive programs in the capsicum sandbox:

> In its current implementation, the program is hardly a shell at all: it has no interactive mode, only executing a single program per invocation.

I don't know how you could meaningfully sandbox a shell without losing some functionality intrinsic to it being a shell.


What's required for something to be a shell? IMO a minimal shell would have some command line editing and parser, the ability to launch applications, job control, scripting ability, and I/O redirection. These can all be done in the context of a Capsicum-sandboxed shell, where the applications that can be run, and files that can be read/written by the shell, are only those explicitly made available to the shell.


If the result of your sandboxed shell is that it can run any program in PATH, which is sort of the basic function of a shell, then what is the value of the sandbox? I'd say one core feature is the ability to use su or sudo to escalate privileges and install a new application, and then run that application. If you have some whitelist of PATH applications at _start, that's impossible. Meanwhile, you can run dd or cc or rm or chmod and do whatever you like. So I'm just not seeing the value of sandboxing a shell.

I think there's a lot of value in sandboxing more constrained applications, especially with untrusted inputs, like web browsers, individual commands, etc. But I don't buy that you can meaningfully reduce the privileges of a shell without losing the quintessential features of a shell.


> So yes, if you pledge(2) a shell. It can call exec, but directly it can't call socket/connect(2), and the reduction of kernel attack surface is still significant.

Why is that significant if I can fork and exec nc(1)?


because nc(1) is only pledged for fork and exec when you explicitly supply something for it to exec?, otherwise it takes codepaths that do not grant that pledge permission.

Having something be capcicumized (?) and exec capable seems to be mutually exclusive.


This isn't about nc's pledge call, this is about the thing that might call nc. A shell that is prevented from calling socket or connect, but can exec nc, is still able to establish a network connection.


> The difference is that while Capsicum provides you with very solid, ...

... That nothing uses. And even their flagship research example, Chrome, has never made it into the FreeBSD ports tree.

OpenBSD has pledge(2)/unveil(2) for Chrome.


Not true - Capsicum is used by a growing amount of software, from base system utilities (like uefisign(8)) or servers (like ctld(8)) to third party stuff, like Irssi. And yes, there are language bindings as well.

The problem with Chrome is not that it’s hard to capsicumize - it’s not, it has been done and documented - but rather that the upstream developers are extremely uncooperative wrt accepting patches.


Huh? FreeBSD has never included the Capsicum patches for chromium in ports.

Google not accepting this upstream is a separate issue, albeit regretful, OpenBSD maintains the pledge/unveil patches and users benefit from this work today, whereas FreeBSD users cannot run Capsicum-ised Chrome.

Capsicum patches are also considerably more intrusive, and their intention and protection is less clear.


It's too bad Capsicum was never merged into the Linux kernel[1]. It would have been nice to have one sandboxing API to use across the two operating systems, and the two projects could share the effort of sanboxing existing programs and libraries.

[1]: http://www.capsicum-linux.org/


All it needs is for someone to finish the port.


Which are the current options for capability-based security on Linux?


Looks like that website hasn't been updated in years. I wonder why?


Linux has its priorities somewhere else.


One other URL that might help understanding the "big picture" behind Capsicum is, and how it differs from most other sandboxing mechanisms, is this: https://en.wikipedia.org/wiki/Capability-based_security. (It's not _that_ good, though; someone(tm) should eventually write an article explaining Capsicum from that point of view, since it's a pretty fundamental difference.)


Aside: patch(1) from the example is a really good candidate for isolation. A few months ago we had this RCE: http://git.savannah.gnu.org/cgit/patch.git/commit/?id=123eaf...


I love this, it's like the unikernel of shell security.


Apparently the author decided to not only replace all occurrences of "its" with it's, but all occurrences of "it" as well.


The author is Polish and not a native English speaker, if that helps you understand the grammar.




Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: