[HN Gopher] FreeBSD Capsicum vs. Linux Seccomp Process Sandboxing
___________________________________________________________________
FreeBSD Capsicum vs. Linux Seccomp Process Sandboxing
Author : vermaden
Score : 110 points
Date : 2026-03-09 12:52 UTC (10 hours ago)
(HTM) web link (vivianvoss.net)
(TXT) w3m dump (vivianvoss.net)
| PeterWhittaker wrote:
| Interesting article, but it compares apples to a fruit stand: The
| approach could be improved by comparing Capsicum to using seccomp
| in the same way.
|
| Sometime ago I wrote a library for a customer that did exactly
| that: Open a number of resources, e.g., stdin, stdout, stderr, a
| pipe or two, a socket or two, make the seccomp calls necessary to
| restrict the use of read/write/etc. to the associated file
| descriptors, then lock out all other system calls - which
| includes seccomp-related calls.
|
| Basically, the library took a very Capsicum-like approach of
| whitelisting specific actions then sealing itself against further
| changes.
|
| This is a LOT of work, of course, and the available APIs don't
| make it particularly easy or elegant, but it is definitely
| doable. I chose this approach because the docker whitelist
| approach was far too open ended and "uncurated", if you will, for
| the use-case we were targeting.
|
| In this particular case, I was aided by the fact the library was
| written to support the very specific use-case of filters running
| in containers using FIFOs for IPC, logging, and reporting: Every
| filter saw exactly the same interfaces to the world, so it was
| relatively easier to lock things down.
|
| Having said that, I wish Linux had a Capsicum-equivalent call,
| or, even better for the approach I took, a friendlier way to
| whitelist specific calls.
| thomashabets2 wrote:
| A problem with that approach is that libc can after an upgrade
| decide to start doing syscalls you were not expecting. Like the
| first time you call `printf()` it calls `newfstatat()`. Only
| the first time. Maybe in the future it'll call it more often
| than that, and then your binary breaks.
|
| I'm not sure what glibc's latest policy is on linking
| statically, but at least it used to be basically unsupported
| and bugs about it were ignored. But even if supported, you
| can't know if it under some configurations or runtime
| circumstances uses dlopen for something.
|
| Or maybe once you juggle more than X file descriptors some code
| switches from using `poll()` to using `select()` (or
| `epoll()`).
|
| My thoughts last time I looked at seccomp:
| https://blog.habets.se/2022/03/seccomp-unsafe-at-any-speed.h...
| chuckadams wrote:
| Now that Landlock actually is a thing, have you considered
| writing another followup? Given what I've seen of landlock, I
| expect it'll be spicy...
| WalterGR wrote:
| I took the bait.
|
| "The goal of Landlock is to enable restriction of ambient
| rights (e.g. global filesystem or network access) for a set
| of processes. Because Landlock is a stackable LSM [(Linux
| Security Model)], it makes it possible to create safe
| security sandboxes as new security layers in addition to
| the existing system-wide access-controls. ... Landlock
| empowers any process, including unprivileged ones, to
| securely restrict themselves."
|
| https://docs.kernel.org/userspace-api/landlock.html
| thomashabets2 wrote:
| I've actually found it pretty fine. It doesn't have full
| coverage, but they have a system of adding coverage (ABI
| versions), and it covers a lot of the important stuff.
|
| The one restriction I'm not sure about is that you can't
| say "~/ except ~/.gnupg". You have to actually enumerate
| everything you do want to allow. But maybe that's for the
| best. Both because it mandates rules not becoming too
| complex to reason about, and because that's a weird
| requirement in general. Like did you really mean to give
| access to ~/.gnupg.backup/? Probably not. Probably best to
| enumerate the allowlist.
|
| And if you really want to, I guess you can listdir() and
| compose the exhaustive list manually, after subtracting the
| "except X".
|
| I find seccomp unusable and not fit for purpose, but
| landlock closes many doors.
|
| Maybe you know better? I'd love to hear your take.
| chuckadams wrote:
| I definitely don't know better, and after taking a few
| more looks at landlock, I'm not even sure what my
| objections were, probably got it confused with something
| else entirely. Confusion and ignorance on my part I
| guess.
| Someone wrote:
| > A problem with that approach is that libc can after an
| upgrade decide to start doing syscalls you were not
| expecting.
|
| That would break capsicum, too, so I don't see how that's a
| problem when "comparing Capsicum to using seccomp in the same
| way".
| thomashabets2 wrote:
| That's the approach I meant by "that approach", the library
| the parent commenter was talking about writing for a
| customer. Compare this to Landlock or OpenBSDs
| pledge/unveil.
| staticassertion wrote:
| This is a problem but fwiw libc's should be falling back to
| old system calls. You can block clone3 today and see that
| your libc will fall back to clone.
| hrmtst93837 wrote:
| You can make seccomp mimic Capsicum by whitelisting syscalls
| and checking FD arguments with libseccomp, but that quickly
| becomes error prone once you factor in syscall variants and
| helper calls. Read and write take the FD as arg0 while pread
| and pwrite shift it, and sendfile, splice and io_uring change
| semantics, and ioctl or fcntl can defeat naive filters, so you
| wind up with a huge BPF program and still miss corner cases.
|
| Capsicum attaches rights to descriptors and gives kernel
| enforced primitives like cap_enter and cap_rights_limit, so
| delegation is explicit and easier to reason about. If you want
| Linux parity, use libseccomp to shrink the syscall surface,
| combine it with mount and user namespaces and Landlock for
| filesystem constraints, and design your app around FD based
| delegation instead of trying to encode every policy into BPF.
| jmclnx wrote:
| This site is a perfect example showing why people are complaining
| about grey text, to me it is unreadable. See:
|
| https://news.ycombinator.com/item?id=47268574
| szszrk wrote:
| I can't read it normally even on 300% zoom. Somehow even
| reading mode is broken, due to diagrams being rendered in
| browser - I did not expect that.
|
| But hey, it's a game!
| icedchai wrote:
| The font and color combination is terrible. It looks blurry
| to me, even at high zoom.
| szszrk wrote:
| Game in background doesn't help either.
|
| It reminds me the pinnacle of design - Microsoft
| Authenticator. On Android, out of the blue, it displays
| global overlay to select one of the 3 numbers to confirm
| login.
|
| The overlay is ... transparent.
| jajuuka wrote:
| The game happening at the same time is just distraction central
| too.
| littlestymaar wrote:
| You're not missing anything, the entire blog is AI slop.
| szszrk wrote:
| I'd love to hear this explained. Deeply.
|
| The UI is fun but unreadable, but content is solid. Explain
| how this is slop please.
| capnrefsmmat wrote:
| Several reasons:
|
| 1. The post mainly reiterates a single idea (Capsicum
| enumerates what the process can do, seccomp provides a
| configurable filter) in many different ways. There is not
| much actual depth, code samples notwithstanding. Nothing on
| why different designs were chosen, how easy each is to use,
| outcomes besides the Chrome example, etc.
|
| 2. There are a lot of AI writing tells, like staccato
| sentences, parallelism ("Same browser. Same threat model.
| Same problem."), pointless summary tables, "it's not X,
| it's Y" contradiction ("This is not a bug. It is the
| original Unix security model"), etc.
|
| 3. The author has roughly a blog post a day, all with
| similar style and on widely varied topics, and in the same
| writing style. Unless the author has deep expertise on a
| remarkably wide range of topics and spends all their time
| writing, these can't reflect deep insight or experience,
| but minimal editing of AI output.
|
| So yes, it's pretty sloppy.
| Bnjoroge wrote:
| It's pretty obvious. Lots of LLM signs. Short sentences
| that keep repeating the same idea. It's not x, it's this.
| In fact, the entire blog seems to be LLM-generated.
| Jolter wrote:
| Its not solid. It's overly long and repetitive.
| dddddaviddddd wrote:
| And without Javascript enabled, the page refreshes in a loop!
| thomashabets2 wrote:
| Yeah I'm not a fan of seccomp
| (https://blog.habets.se/2022/03/seccomp-unsafe-at-any-
| speed.h...).
|
| On Linux I understand that Landlock is the way to go.
| 0x457 wrote:
| Landlock right now doesn't offer a lot for things that aren't
| file system access. Other than that it's great, you can have
| different restrictions per-thread if you want to.
| thomashabets2 wrote:
| Yeah, but the file system is where I put most of my files.
| :-)
|
| Between file system, bind/connect, and sending signals, that
| covers most of it. Probably the biggest remaining risk is any
| unpatched bugs in the kernel itself.
|
| So one would need to first gain execution in the process, and
| then elevate that access inside the kernel, in a way that
| doesn't just grant you root but still Landlocked, and with a
| much smaller effective syscall attack surface. Like even if
| there's a kernel bug in ioctl on devs, landlock can turn that
| off too.
| littlestymaar wrote:
| I've seen AI written blog posts before, but this is one step
| above: the entire blog (~90 articles) have been AI generated over
| the past three months.
|
| I already find it very frustrating that most open source projects
| spawning on HN's front page are resume-boosting AI slop but if
| blogs start being the same the internet is definitely dead.
|
| Edit: it doesn't even looks like it's resume-boosting in this
| case, the "person" behind it doesn't even appear to exist. We can
| only speculate about the intent behind this.
| shirro wrote:
| It is getting more difficult to research now. Increasingly I
| just grab the source code locally and don't bother with the
| browser. Every search returns pages of wordy AI generated docs.
| At best they restate the code. At worse they read like badly
| written brochures. I am avoiding any project that doesn't have
| a long history. Large, feature packed projects that appeared
| out of nowhere on github with a single commit with no history
| or users are essentially stolen code that has been machine
| translated to obscure the original authors works.
|
| I hate becoming the old person shaking their fist at the sky
| but the AI bros have just gone too far. I don't know why there
| isn't a bigger political and social movement against them. I
| would sign up in an instant to see their companies and
| practices regulated out of existence.
| thedatamonger wrote:
| so .. if i'm getting this right, this is an article about
| security, but the author can't be bothered to configure https
| correctly?
| craftkiller wrote:
| What'd they get wrong? Firefox and curl aren't reporting any
| TLS errors for me.
| adiabatichottub wrote:
| One question I've always had about these capability systems is:
| why isn't there a way to set capabilities from the parent process
| when execing? Why trust a program to set its own capabilities? I
| know that having a process set capabilities on itself doesn't
| break existing tools, but it seems like if you really wanted a
| robust system it would make sense to have the parent process, the
| user's shell for example, set the capabilities on its children,
| and have those capabilities be inheritable so the child could
| spawn other processes with the same or fewer capabilities (if
| it's allowed to do that at all). Is there an existing system that
| works this way, in or outside of the UNIX family? Or maybe some
| research paper written on the subject? I'd love to know.
| toast0 wrote:
| I've only really messed with capsicum. You can certainly
| cap_enter between fork and exec, but depending on exactly what
| your target does, it's really not simple to do anything
| meaningful beyond the basic capsicum mode without changes to
| the program.
|
| The way capabilities usually work is you more or less turn off
| the usual do whatever you want syscalls, and have to do
| restricted things through FDs that have the capability to do
| them. So like, no more open any path, you have to use openat
| with a FD in your directory of interest. But that requires the
| program to understand how to use the capabilities and how to be
| passed them. It's not something that you can just impose.
|
| My understanding of SELinux, is it can be imposed on a program
| without the knowledge of the program, because it's more or less
| matching rules for syscalls... rather than giving a restricted
| FD to use with openat, you restrict the options for open.
| black_knight wrote:
| Answering without reading TFA here. But I am familiar with
| capsicum.
|
| But I am pretty sure you CAN get your capabilities from a
| patent process using capsicum, since they are just file
| descriptors.
| harporoeder wrote:
| This is essentially what containers are. Bubblewrap / Docker /
| Podman. I think the primary issue is very few applications on
| Desktop systems are actually designed with sandboxing in mind
| unlike say something on a phone.
| adiabatichottub wrote:
| I'm not terrible familiar with Linux container systems,
| cgroups and all that, but I have been down the rabbit-hole
| with FreeBSD's jails, and I definitely wouldn't call them a
| capabilities system. You can lock down the environment quite
| a bit, and limit or even virtualize the network stack, but
| you can't say, "Here process, have your standard IO streams
| and nothing more. Go forth and compute." The process isn't
| blind to it's environment. You're still in the same basic
| UNIX user security model. It's really somewhere between
| chroot and full virtualization.
| harporoeder wrote:
| A default container seccomp profile will let you do quite a
| few things but you can use a different profile some json
| and limit to just a few system calls if you want such as
| doing IO on open FDs without the ability to open them. I
| think the runtime opens the FDs before the child process
| starts and are inherited.
| g0xA52A2A wrote:
| You may be interested in OpenBSD's pledge[1][2][3].
|
| > Why trust a program to set its own capabilities?
|
| An example may be that a program starts needing a wide range of
| capabilties but can then ratchet down to a reduced set once
| running, aka "privdrop".
|
| > why isn't there a way to set capabilities from the parent
| process when execing?
|
| There have been replies on other systems so just to stick with
| pledge which provides the abiliy to set "execpromises" to do
| this.
|
| [1] https://man.openbsd.org/pledge
|
| [2] https://www.openbsd.org/papers/eurobsdcon2017-pledge.pdf
|
| [3]
| https://www.openbsd.org/papers/BeckPledgeUnveilBSDCan2018.pd...
| adiabatichottub wrote:
| I think you're talking about "execpromises"?[1] I'll have to
| study it a bit.
|
| [1] https://bsdb0y.github.io/posts/openbsd-intro-to-update-
| on-pl...
| brynet wrote:
| EDIT: Article seems to have been updated to remove mention of
| Chromium.
|
| This article contains a lot of errors, for example Chromium on
| FreeBSD does NOT use Capsicum, it never has. That was
| experimental and invasive work done 17 years ago that was NEVER
| committed to their official ports repository. In fact, not a
| single browser on FreeBSD uses Capsicum or any form of sandboxing
| _at all_.
|
| https://github.com/rwatson/chromium-capsicum
|
| https://www.freshports.org/www/chromium/
|
| https://cgit.freebsd.org/ports/log/www/chromium/Makefile?qt=...
|
| Contrast that with OpenBSD, where the Chromium port has used
| pledge(2) since January 2016, and unveil(2) since 2018. Both are
| enabled by default. Mozilla Firefox ports also use both pledge
| and unveil since 2018-2019, with refinements over the years.
|
| https://marc.info/?l=openbsd-ports-cvs&m=145211683609002&w=2
|
| https://marc.info/?l=openbsd-ports-cvs&m=153250162128188&w=2
|
| OpenBSD's fork of tcpdump has been privsep for ~22 years, and its
| packet parser runs with no privileges. It's pledged tightly
| "stdio" and has no network/filesystem access, and uses OpenBSD
| specific innovations like bpf descriptor locking (BIOCLOCK)
| missing from both FreeBSD/Linux tcpdump today (despite FreeBSD
| adding the ioctl in 2005).
|
| In the years since it was added, the reason Capsicum has only
| been applied to a handful of utilities is because it's a tree
| barren of decades worth of incremental work on privilege
| separation and security research.
| limagnolia wrote:
| I would like to see a comparison of capsicum and pledge/unveil.
| Is capsicum much more difficult to use? Is it inherently less
| secure?
| brynet wrote:
| It's very difficult to reason about, for instance compare the
| OpenSSH sshd sandbox implementations.
|
| https://github.com/openssh/openssh-
| portable/blob/master/sshd...
|
| https://github.com/openssh/openssh-
| portable/blob/master/sand...
|
| https://github.com/openssh/openssh-
| portable/blob/master/sand...
|
| https://github.com/openssh/openssh-
| portable/blob/master/sand...
|
| w/ Capsicum, beyond faffing around with some file
| descriptors, it's unclear what security cap_enter() adds:
|
| https://github.com/openssh/openssh-
| portable/blob/master/sand...
| brynet wrote:
| > EDIT: Article seems to have been updated to remove mention of
| Chromium.
|
| Archive: https://archive.ph/rLmTq
| ruslan wrote:
| Excuse me for being ignorant, is Seccomp what SELinux is based on
| ?
|
| Also, what is well-known piece of software that uses Capsicum on
| FreeBSD ? Can someone name a few ?
___________________________________________________________________
(page generated 2026-03-09 23:01 UTC)