[HN Gopher] Show HN: Porting OpenBSD Pledge() to Linux
       ___________________________________________________________________
        
       Show HN: Porting OpenBSD Pledge() to Linux
        
       Author : jart
       Score  : 404 points
       Date   : 2022-07-14 14:52 UTC (8 hours ago)
        
 (HTM) web link (justine.lol)
 (TXT) w3m dump (justine.lol)
        
       | jamal-kumar wrote:
       | Thanks Justine, you're doing the Lord's work here.
       | 
       | One of the best introductions I've seen to pledge() is Kristaps
       | Dzonson's writeup on it that you can find here [1]. The whole
       | website in general is furthermore a guide on how to write webapps
       | in C, which may sound like a crazy idea to some people who have
       | written it off as everything from an elaborate joke to a security
       | nightmare that nobody should ever consider doing [2], but for
       | people like me who end up having to write that kind of code in
       | constrained execution environments it's been extremely
       | enlightening and I really appreciate knowing how to do it more
       | securely. If pledge is something I can access in Linux it really
       | helps me out for things in the future going forward, I hope to
       | create some cool things with it!
       | 
       | [1] https://learnbchs.org/pledge.html
       | 
       | [2] https://learnbchs.org/
        
         | jart wrote:
         | Awesome blog post! Writing web apps in C? That doesn't sound
         | crazy to me. If someone told me they were doing that, then I'd
         | just assume they're trying to compete with Google Search for
         | the title of the world's lowest-latency high-performance
         | scalable website. If pledge() makes you feel less guilty about
         | going for the gold, then I'd say that's a good thing. You might
         | also be interested in Cosmopolitan Libc's ASAN and UBSAN
         | support. It does things like print memory diagrams with
         | backtraces with malloc origin tracing if you do something like
         | overrun a buffer or use a piece of memory after it's freed.
         | ASAN has been one of the most important tools that Google used
         | to find security issues in Chrome. So I put a lot of work into
         | implementing greenfield support for it in Cosmo. In fact, ASAN
         | is so important, that even languages like Rust need to use it,
         | since it makes the unsafe keyword safe! So please try Cosmo's
         | implementation and let me know what you think. I believe Cosmo
         | has the highest quality ASAN implementation that's available to
         | the open source community.
        
           | jamal-kumar wrote:
           | Yeah it's pretty much your best option (C or C++) when
           | writing web apps for things like routers or for game consoles
           | for example, which is the kind of use case I'm talking about.
           | Your work here makes doing that so much easier and safer,
           | which is really important considering how many routers are
           | being exploited to be malicious these days.
           | 
           | It might take a little while to catch on in those use cases
           | but I've been waiting for someone to nail the implementation
           | for a while. It's hardly a surprise that you of all people
           | got it down, I've been admiring your work for quite some
           | time.
           | 
           | So how about those blog posts in Mayan Hieroglyphics?
        
         | dang wrote:
         | [1] was discussed here:
         | 
         |  _Why pledge(2) or, how I learned to love web application
         | sandboxing_ - https://news.ycombinator.com/item?id=13037442 -
         | Nov 2016 (73 comments)
        
       | liuliu wrote:
       | Great work! Should we reverse "exec" and "execnative" because the
       | first is more APE oriented (maybe "execape"?)? Just thinking from
       | the perspective of adopting to more Linux use cases.
        
         | jart wrote:
         | The pledge.com command always enables execnative because it
         | needs to be able to call execve() after pledge() is called.
         | It's one of the weaknesses of using pledge() as a command
         | runner rather than as a C API library. In terms of the C API,
         | that's up for debate. Because our implementation of that is
         | primarily intended to cater to Cosmopolitan Libc's way of doing
         | things, where APE is the preferred binary format. It wouldn't
         | feel right to call it exec if it can't execute our own
         | binaries! However we still do the responsible thing by
         | providing a way to opt-out into only supporting the native elf
         | format.
        
       | ingenieroariel wrote:
       | It was mentioned in the discord that instead of doing `curl
       | something | sh` you could do `curl something | ./pledge.com sh`
       | that looks like an interesting way to see what all those install
       | scripts really want to get access to
        
       | thomashabets2 wrote:
       | I don't think Linux will get pledge() for a long time, and this
       | definitely won't do it in the general case either.
       | 
       | More specific critique of seccomp here:
       | https://blog.habets.se/2022/03/seccomp-unsafe-at-any-speed.h...
        
       | MrWiffles wrote:
       | Well done, Justine! This is absolutely fracking BRILLIANT. Thank
       | you for this, especially a useable CLI utility! I'm going to have
       | a lot of fun unmasking bastards with this thing :-)
        
       | holsta wrote:
       | Oh god yes please. If pledge() makes it into the mainline kernel,
       | we OpenBSD-type people seem less weird when submitting patches
       | for some syscall "nobody uses".
       | 
       | Many OpenBSD ports contain pledge() support. Steal all you can.
       | OpenBSD does "hoisting" in many userland programs, meaning all
       | the open calls and such take place at the very start but isn't
       | actually parsed until after we have locked ourselves in with
       | pledge() and unveil(). I hope this also means many non-base
       | programs are redesigned in this manner.
        
         | dbtc wrote:
         | I love this [philosophy,mindset,culture].
        
         | knorker wrote:
         | I too would love pledge() in Linux. But as I pretty much
         | implied in this comment thread
         | (https://news.ycombinator.com/item?id=32097649) the project
         | here won't get us there, and it does need to be part of the
         | kernel.
         | 
         | Of course the problem is that it needs some cooperation between
         | libc and the kernel. That's why it's easier for OpenBSD to
         | provide it.
        
           | jart wrote:
           | > Of course the problem is that it needs some cooperation
           | between libc and the kernel.
           | 
           | You may have missed that our new pledge() impl is hosted in
           | the Cosmopolitan Libc repository. So we've got cooperation.
           | Therefore it'd help to clarify when you say this project
           | won't get us there, that you're only speaking for glibc.
           | pledge.com works fine with everything else like Musl and
           | Cosmo Libc. It even works with glibc most of the time. One
           | can't reasonably expect cosmo to need to support glibc before
           | being able to support itself. We've learned today that folks
           | want this. So the Glibc dev team should be doing more to help
           | us. What I fear is that they're focused on different things.
        
       | j-bos wrote:
       | Does anyone have a good primer on pledge, how it works, syntax,
       | etc?
        
         | frays wrote:
         | https://learnbchs.org/pledge.html
        
       | post-factum wrote:
       | For the niceness part, I wrote a small helper [1] quite some time
       | ago, and it really is handy in some situations.
       | 
       | [1] https://codeberg.org/post-factum/litter
        
       | mike_hock wrote:
       | Isn't the rant about chroot kind of addressed by filesystem
       | namespaces in Linux?
        
         | thomashabets2 wrote:
         | pledge() is not chroot-like. unveil() is, kinda. But pledge()
         | is much cooler.
        
       | fullstop wrote:
       | This seems (somewhat) similar to unshare. [1] [2]
       | 
       | 1.
       | https://manpages.ubuntu.com/manpages/jammy/man1/unshare.1.ht...
       | 
       | 2.
       | https://manpages.ubuntu.com/manpages/jammy/en/man2/unshare.2...
        
         | btdmaster wrote:
         | It seems you can disable[0] networking with `unshare --map-
         | root-user --net`.
         | 
         | [0] I don't think it's meant to disable it, I just know too
         | little about namespaces to appreciate how you would unshare a
         | new network namespace and have it keep working.
        
       | gigatexal wrote:
       | It's stuff like this that really, really entice me to give
       | openbsd as a daily driver a shot.
        
         | smm11 wrote:
         | You could be user 7001.
        
           | gigatexal wrote:
           | i am now user 7001. :-)
           | 
           | spun up a vm and am googling a lot
        
       | bowsamic wrote:
       | I was introduced to pledge via SerenityOS and it really is
       | amazing
        
         | sph wrote:
         | And here's Andreas porting Justine's pledge utility to
         | SerenityOS after having seen this very post:
         | https://youtu.be/T6YkQF6ohoA
        
       | roryrjb wrote:
       | Very nice! I'm a fan of OpenBSD and pledge(). I've had some
       | success on Linux with libseccomp[0] which means you don't have to
       | deal with BPF directly, but pledge() is obviously much much
       | easier.
       | 
       | 0. https://github.com/seccomp/libseccomp
        
       | knorker wrote:
       | Having tried this myself i don't believe in this implementation.
       | The list of syscalls is not only dynamic across kernel versions,
       | but even different between architectures.
       | 
       | You REALLY need a committed team to maintain this, and likely
       | ability to fix in a /etc/pledge.conf or something, as syscalls
       | are added and changed.
       | 
       | The hard part is not what jart did, but to keep it working.
        
         | jart wrote:
         | The Cosmopolitan Libc project has a very modest scope that
         | isn't nearly as big as you suppose. We only support x86-64.
         | We're not trying or claiming to be the ones who will carry the
         | pledge() burden for the whole Linux world like glibc and Musl
         | too, even though (so far) our implementation seems to do a
         | reasonable job at that.
         | 
         | As for the moving target of the Linux system call ABI, we
         | mostly use a whitelist model so I don't see why it should
         | matter. Unless your concern is that we keep up with the latest
         | new features. My humble opinion is there's very few system
         | calls Linux has introduced in the last ten years that I
         | personally care about using. Other people might care about
         | things like io_uring and statx() but I tend to stick with the
         | classic calls.
         | 
         | Keep in mind, Cosmopolitan Libc binaries are designed to run on
         | six operating systems. I'm probably the only person on earth
         | who's written a libc for that many platforms. Here's what I
         | learned. If you look at
         | https://github.com/jart/cosmopolitan/blob/master/libc/sysv/s...
         | you can see that there's a point in history where consensus
         | between systems drops off. It probably happened sometime around
         | the year 2000, and since then Linux has mostly just gone its
         | own way as far as UNIX systems are concerned. There's only been
         | a select few system calls introduced in the last twenty years
         | that every single system was quick to adopt, e.g. getrandom(),
         | pipe2(), openat(), fstatat(), etc.
         | 
         | So I really don't think it's as complex as folks here are
         | making it out to be. It's simply a question of focus. We aren't
         | solving every problem. But the few things we are doing, we do
         | very well.
        
           | knorker wrote:
           | I'll admit to not knowing this context around it, but I guess
           | yes if you only support binaries linked against your own libc
           | (and only dynamically), and only on one architecture, then it
           | should work.
           | 
           | But as you say, it's quite limiting for userspace trying to
           | use things that maybe your libc is not aware of.
           | 
           | Compare how OpenBSD is actually disallowing syscalls outside
           | of their libc. That's the level of control that's needed both
           | for it to work, and I don't think Linux lets you do that.
           | 
           | My point is: No, this does not "port pledge() to Linux". I'm
           | sure you agree that it has many many asteriskses, to the
           | point that the title built up a hope it can't live up to.
           | 
           | I wish it did, but I don't see it.
           | 
           | > We aren't solving every problem.
           | 
           | It's a good effort. But the problem isn't the narrow scope.
           | The problem is "Porting OpenBSD pledge() to Linux", which I
           | don't think is an accurate description of what this does.
        
             | jart wrote:
             | > Compare how OpenBSD is actually disallowing syscalls
             | outside of their libc.
             | 
             | And Cosmopolitan Libc actually disallows syscalls to the
             | OpenBSD Libc whilst running on OpenBSD. If this surprises
             | you then you've misunderstood the intent behind msyscall(),
             | which Cosmopolitan's pledge() implements on Linux too. See
             | the "Syscall Origin Verification" section of the blog post
             | https://justine.lol/pledge/#msyscall The basic idea is you
             | can choose whatever set of system call wrappers you want,
             | put them into one memory location, and then the kernel will
             | check the RIP register to make sure that SYSCALL is only
             | being used from those addresses. Their choice to start
             | doing this is kind of funny because it turns C libraries
             | into a game of Highlander. There can be only one.
        
       | oynqr wrote:
       | Damn, I was looking for pledge on Linux not too long ago, but I
       | think I might go with cloudflare's sandbox or bwrap instead.
        
       | [deleted]
        
       | the8472 wrote:
       | _> Pledging causes most system calls to become unavailable. Your
       | system call policy is enforced by the kernel, which means it can
       | propagate across execve() if permitted._
       | 
       | My understanding is that promises aren't inherited across execve.
       | So that's an incompatibility with openbsd's pledge. And a pretty
       | important one imo because it makes it more difficult to factor
       | out privileged subprocesses (e.g. one doing network things, the
       | other accessing filesystems).
       | 
       |  _> File system access is a blind spot. OpenBSD solves this with
       | another famous system call called unveil()_
       | 
       | That could probably be approximated with user + mount namespaces,
       | a tmpfs and bind mounts. Basically what containers do. But that
       | might suffer from the same process inheritance problems if unveil
       | is BSD-specific, the manpage is unclear about unveil's exec
       | behavior.
        
       | [deleted]
        
       | gnoack wrote:
       | > There's been a few devs in the past who've tried this. I'm not
       | going to name names, because most of these projects were never
       | completed.
       | 
       | Oh, I'll just name myself (see code link below), I'm not ashamed
       | that this didn't complete.
       | 
       | There are more fundamental reasons why these projects don't
       | complete, and they apply to the project linked above as well:
       | 
       | - Maintaining lists of allowed syscalls across kernel versions
       | and architectures is unreasonable to do, and it's a moving
       | target. An allowlist-based approach might break when doing a
       | kernel or glibc upgrade, which breaks the API backwards
       | compatibility that the kernel otherwise guarantees. - Core parts
       | of glibc are doing initialization work on demand, which
       | complicates matters (should ideally be done before enabling the
       | sandbox, but this is not generally possible) - Some pledge()
       | promises can't be mapped correctly; examples: - the "dns" promise
       | in cosmopolitan/pledge.c just permits all outgoing UDP
       | connections, which is more than what OpenBSD permits, IIRC - the
       | "exec" promise cannot elevate privileges again, as it does in
       | OpenBSD - glibc name lookups as they are used for DNS are loading
       | shared libraries on first use (libnss), and it's impossible to
       | tell in advance what these will do unless you control the
       | execution environment - The pledge API itself is a moving target
       | as well (compare https://man.openbsd.org/OpenBSD-6.0/pledge.2 and
       | https://man.openbsd.org/OpenBSD-7.1/pledge.2) - In OpenBSD,
       | pledge was always path-aware, until they moved that part into the
       | unveil() call. This is not possible on Linux with seccomp-bpf.
       | (Well, yes yes, with signals that do syscall trampolines and very
       | very tight control over the runtime environment, or with sidecar
       | processes to do the supervision, but both of these require a lot
       | more dedication and can't be just mapped to a call to "pledge()"
       | on Linux.)
       | 
       | FWIW, my own (abandoned) implementation is at:
       | https://github.com/gnoack/seccomp-scopes/blob/master/pledge....
       | 
       | IMHO the better approach on Linux is going to be Landlock
       | (https://landlock.io) in the future. I'd encourage you to look
       | into it.
        
         | staticassertion wrote:
         | > - the "exec" promise cannot elevate privileges again, as it
         | does in OpenBSD
         | 
         | I agree with all of this fwiw, but I actually was very glad to
         | see this. I find it really weird that the openbsd pledge lets
         | you just escalate out of it.
        
           | wahern wrote:
           | > I find it really weird that the openbsd pledge lets you
           | just escalate out of it.
           | 
           | It's only weird because the normal M.O. with facilities in
           | other environments is to sandbox specific, high-exposure
           | applications, which are typically run in isolation, such as
           | system daemons or end-user GUI applications. The semantics of
           | pledge and unveil were fine-tuned from OpenBSD developers
           | systematically sandboxing almost the entire base system--most
           | command-line utilities in OpenBSD are pledged, as are all
           | daemons.
           | 
           | Inheritance is only a "problem" if you're exec'ing other
           | programs, but the vast majority of programs, even command-
           | line utilities, never need to exec, at least not during
           | runtime (as opposed to startup). Most programs using pledge
           | drop the ability to exec entirely (i.e. don't specify the
           | "exec" pledge), so inheritance is irrelevant as there could
           | never be anything to inherit. (Note that upon the first call
           | to pledge, you lose any capabilities you don't explicitly
           | request.) But if you do need to exec other programs, then
           | inheritance can quickly become a problem--counter-productive,
           | even, as workarounds typically involve the parent program
           | _preserving_ permissions which it might not need directly.
           | (Note that this is also why pledge and unveil are superior
           | APIs to relying on the invoker--e.g. systemd--dropping
           | permissions as only the program itself knows best which
           | permissions it needs and _when_.)
           | 
           | OpenBSD is developed as a comprehensive system, and it's in
           | this context that you need to understand pledge and unveil.
           | On OpenBSD, if program A exec's program B, program B should
           | be making use of pledge and unveil itself, and if it's not
           | then that can and will be fixed. Unlike in the cat-herding
           | Linux ecosystem, OpenBSD developers have little reason for a
           | security model that prioritizes the ability for program A to
           | implement workarounds for deficiencies in program B; their
           | habit is fixing program B or refactoring A _and_ B so they
           | can work better together.
        
         | gnoack wrote:
         | I guess the TL;DR is: This is a cool project, don't get me
         | wrong :)
         | 
         | I just feel that it's difficult to do in Linux's heterogeneous
         | environment where everyone uses their own kernel configuration
         | and libc variant... the reason is not just the difficult C API
         | (with BPF in it...) but it's also the surprises and weak
         | guarantees in the environment where these programs run.
         | 
         | We should at some point be able to do unprivileged sandboxing,
         | but seccomp-bpf may not be the way to do this at scale.
        
         | _wldu wrote:
         | Here's a landlock wrapper for FireFox:
         | https://github.com/62726164/misc/tree/main/go/landlock/firef...
         | 
         | It's more restrictive than Firejail and is not suid.
        
         | the8472 wrote:
         | Landlock suffers from the same limitations as seccomp when it
         | comes to pledge-emulation: you can't opt out of inheritance.
        
           | staticassertion wrote:
           | That's a good thing.
        
             | mzs wrote:
             | No that's a linux thing. The OpenBSD way is to do things
             | that could be abused later early and then drop privs to
             | prevent abuse. How is some program going to know what other
             | programs you use will need? How is the dynamic linker of
             | the later program supposed to deal?
        
       | jacobmischka wrote:
       | Very neat! Unfortunately can't get the `curl` example to work no
       | matter what I do (on Arch Linux).                   $ pledge.com
       | -p 'stdio rpath wpath cpath dpath flock tty recvfd fattr inet
       | unix dns proc thread id exec' curl http://justine.lol/hello.txt
       | curl: (6) getaddrinfo() thread failed to start
       | 
       | I tried following the Troubleshooting section and looking through
       | strace output, but unfortunately I'm not sure what I'm looking
       | for, I see a few EPERMs for calls that I don't know what they do:
       | rseq, set_robust_list, and sysinfo to name a few.
        
         | fweimer wrote:
         | That could mean that the clone3 system call fails with EPERM
         | instead of ENOSYS. Suppressing system call implementations with
         | ENOSYS is generally safer because it just looks like an older
         | kernel, while EPERM is an regular error code for some system
         | calls.
         | 
         | Put differently, ENOSYS tells userspace that the system call
         | isn't implemented and you need use some fallback code. EPERM
         | means that the operation was denied by policy. But in that
         | case, it might not be a good idea to approximate it by using
         | different system calls because it might circumvent the intended
         | security policy.
        
         | jart wrote:
         | It works fine for me if Curl is built with Musl Libc. I can see
         | you're using a very cutting edge glibc. I tried reproducing
         | this on Debian 10. The only calls that got EPERM'd were
         | set_robust_list() and prlimit64(). I recompiled pledge.com by
         | adding those, and Curl is still failing for reasons that aren't
         | obvious. I've encountered issues like this in the past. Me
         | personally I've always solved this by keeping a healthy
         | distance from Glibc by using things like Musl and Cosmo.
         | However I want to see Glibc users benefitting from our work
         | too! So I'd welcome contributions from anyone who can help us
         | do that.
        
       | rank0 wrote:
       | Excellent work Justine! You consistently create interesting high
       | quality projects and it's turned me into a fan :)
       | 
       | Keep it up! I'll be upping my sponsorship in the hopes that you
       | can continue doing this full time.
        
       | notaplumber1 wrote:
       | Hi jart,
       | 
       | I noticed that you're missing the sendfd promise. Is there a
       | reason for that omission? Also you've added a number of
       | extensions that perhaps should be documented as such.
       | 
       | Also there's a pretty significant undocumented difference between
       | your implementation and OpenBSD, in that promises are by
       | inherited across exec in yours, and not on OpenBSD.
       | 
       | OpenBSD experimented with that by specifying the second argument
       | as execpromises, but discovered that it was extremely difficult
       | if not impossible to write meaningful execpromises in the parent
       | for potentially unrelated programs, it's also happening too early
       | before dynamic linking, and before the program has had an
       | opportunity to "initialize" or "do privileged stuff" and call
       | pledge(2) later itself with more accurate knowledge of what to
       | self-restrict. As such, no calls with execpromises set to
       | anything but NULL/0 exist today. I'm curious how to reconcile
       | those differences.
        
         | jart wrote:
         | sendfd is something we can add. Note that seccomp has limited
         | visibility into recvmsg / sendmsg args because bpf can't
         | dereference syscall arg pointers. I mention some of this in the
         | caveats section. As for execpromises, it's documented in the
         | Cosmopolitan Libc source code, but that got lost in translation
         | when I copied the docs to the website. I just updated the site.
         | I also appreciate the eyeballs. Something like this deserves
         | critical examination. There's so much breadth to the modern
         | system call interface and pledge. I started working on this
         | about a month ago. With the support of folks like yourself, I
         | think we'll have something really nice that will benefit Linux
         | users! I'll definitely be doing more to make the C API as
         | compatible with OpenBSD as possible.
        
           | tych0 wrote:
           | > Note that seccomp has limited visibility into recvmsg /
           | sendmsg args because bpf can't dereference syscall arg
           | pointers.
           | 
           | I guess landlock can't help you here since it is still mostly
           | about filesystem access right now, but maybe someday? It
           | looks like "minimal network access control" is on the long
           | term roadmap: https://landlock.io/
        
           | archivator wrote:
           | > Note that seccomp has limited visibility into recvmsg /
           | sendmsg args because bpf can't dereference syscall arg
           | pointers.
           | 
           | BPF programs attached to syscalls (via kprobe or fentry)
           | _can_ read arguments via helpers
           | (bpf_probe_read_{user,kernel}). Seccomp uses  "classic BPF"
           | which has no concept of helpers or calls.
        
           | notaplumber1 wrote:
           | > I'll definitely be doing more to make the C API as
           | compatible with OpenBSD as possible.
           | 
           | One suggestion I might add, it would be worth trying to
           | compile any of OpenBSD's privilege separated network daemons
           | on Linux (w/ Cosmopolitan Libc, or others). While you may
           | have intended to use this facility primarily for your own APE
           | Binaries, I suspect you'll find that the despite your
           | intentions to make this compatible with the C API definition
           | of pledge(2), in practice, your implementation is
           | incompatible with privsep/privdrop software, for which pledge
           | was designed. It was never intended for application
           | "sandboxing".
        
             | jart wrote:
             | pledge() wasn't intended for our awesome sandboxing tool?
             | Well that just goes to show how brilliant the OpenBSD
             | developers are, that folks like myself are finding great
             | uses for their ideas and design that they didn't intend. We
             | might not be able to live up to OpenBSD's model given the
             | way Linux is, but I do believe we're going to have a better
             | and more secure Linux thanks to the influence of OpenBSD.
        
               | notaplumber1 wrote:
               | The idea of a "pledge" utility isn't a novel one, it is
               | my understanding that one was intentionally not provided.
        
           | octernion wrote:
           | this is one of the more lovely replies i've seen on HN
        
       | gbrown_ wrote:
       | I'm just going to dump some other links to pledge just for others
       | that are interested. Here's some presentations on attempts at
       | natively implementing pledge in Linux (YouTube's auto-translate
       | does a decent job) [1][2].
       | 
       | The topic of a pledged process starting other processes un-
       | pledged often comes up (and already has done in the comments
       | here). I'd recommend checking out this section of Theo de Raadt's
       | presentation that explains why this is [3].
       | 
       | As mentioned in the article the nice thing of pledge on OpenBSD
       | is the integration of the pledge interface with the reality of
       | underlying system. So as one example a program can pledge only
       | dns and say not have filesystem access, but really under the
       | covers it can read /etc/resolv.conf.
       | 
       | [1]https://www.youtube.com/watch?v=uXgxMDglxVM
       | 
       | [2] https://www.youtube.com/watch?v=PK7gETZURx0
       | 
       | [3] https://youtu.be/Er44ur7wkXQ?t=1497
        
       | grimgrin wrote:
       | If you find this post interesting, and would like to follow (or
       | take part in) the discussions that happen around these new
       | developments, I highly suggest you pop into the redbean discord!
       | It covers more than just the scope of redbean and the community
       | is really blossoming
       | 
       | https://discord.gg/mvkhxRaW
        
       | turndown wrote:
       | If you liked this you might like [0].
       | 
       | 0: https://www.youtube.com/watch?v=-a5hLBuW6tY
        
       | djhworld wrote:
       | Could the CLI tool be combined with something like firejail [1]
       | to solve the filesystem blindspot issue?
       | 
       | [1] https://firejail.wordpress.com/
        
       | crtxcr wrote:
       | Great work!
       | 
       | >.. So how do we get it that simple on Linux? I believe the
       | answer is to find someone with enough free time to figure out how
       | to use SECCOMP BPF to implement pledge.
       | 
       | > There's been a few devs in the past who've tried this. I'm not
       | going to name names, because most of these projects were never
       | completed.
       | 
       | I guess I am also one of those. I am giving it a shot with my WIP
       | sandboxing library, which aims at making sandboxing easier for
       | applications in general:
       | https://github.com/quitesimpleorg/exile.h. It also aims to fix
       | the "file system blind spot" mentioned in the article, by using
       | Landlock and Namespaces/chroot.
       | 
       | Though I am calling my attempt "vows" instead of "pledge" to
       | avoid misunderstandings. At the the end of the day, pledge()
       | cannot be pledge() on Linux, due to limitations which the article
       | also mentions.
       | 
       | Nevertheless, as has already been mentioned in this thread, as
       | all attempts, mine also suffers from the fact that one has to
       | keep up constantly with kernel releases and all software must
       | recompiled from time to time against new library releases. This
       | is a suboptimal situation. Secondly, there systems calls with
       | currently cannot be filtered with seccomp BPF, such as openat2()
       | and clone3() and so on.
       | 
       | Therefore, at this time you cannot have pledge() on Linux
       | properly. So I am putting it on hold until deep argument
       | inspection lands.
       | 
       | Overall, my experience led me to believe in order to have true,
       | partical pledge() on Linux, it must be implemented in the kernel
       | ultimately.
        
         | thomashabets2 wrote:
         | Thanks for your work!
         | 
         | As someone else who's banged their head against seccomp and
         | given up (put on hold) I have to say that you're missing one
         | roadblock though. It's not enough that the kernel gets
         | pledge(), but libc needs to cooperate too.
         | 
         | E.g. as I found in https://blog.habets.se/2022/03/seccomp-
         | unsafe-at-any-speed.h... the first printf() you do will do a
         | newfstatat() syscall.
         | 
         | So really there's no way for user space to know which syscalls
         | will be called, just based on common sense. libc can call
         | anything and everything.
         | 
         | And this is why I have less hope for a real pledge() on Linux.
        
       | waynesonfire wrote:
       | it's so great and nobody porting this to the other BSDs?
        
       | asveikau wrote:
       | I think there have to be more than 7000 OpenBSD users. The link
       | to that claim was not responding when I clicked it.
        
         | octetta wrote:
         | ...maybe that means there are only 6,999 users now... I KEED...
        
         | shp0ngle wrote:
         | It seems to be some copypasta meme from 2003
        
         | efortis wrote:
         | Yes, that statistic is from 20 years ago (11/02)
        
           | asveikau wrote:
           | I was an OpenBSD user then. What are the odds I was 1 out of
           | 7000?
        
         | volkadav wrote:
         | It's a joking reference to an ancient copypasta troll/meme
         | alleging that bsd is dying, cf the phrase "netcraft confirms
         | it" and troll comments on slashdot 20+ years ago. :)
        
           | asveikau wrote:
           | Of course, now I remember, those comments would cite fake
           | sources estimating usage numbers, and probably some of them
           | claimed to have data from de Raadt.
        
       | levodelellis wrote:
       | This is great
       | 
       | If you like I can run pledge against my more complicated app to
       | see if it complains. I did it on a simple app and it seemed to
       | not like how I used memory map (MAP_PRIVATE | MAP_ANONYMOUS |
       | MAP_POPULATE). I also do MAP_PRIVATE | MAP_ANONYMOUS |
       | MAP_POPULATE | MAP_STACK | MAP_GROWSDOWN which might be weird to
       | pledge too
        
         | jart wrote:
         | MAP_POPULATE is intentionally disallowed currently by the Cosmo
         | Libc pledge() implementation, because it's Linux-specific, I've
         | rarely seen it used, and I was erring on the side of caution
         | since I wasn't sure how much prefaulting reads could be
         | considered a borderline privileged operation. If you remove
         | that flag, then mmap() should work fine.
         | 
         | MAP_STACK can be used correctly with Cosmo by saying MAP_STACK
         | | MAP_ANONYMOUS. That's all you need. You can also call Cosmo's
         | _mapstack() function. Cosmo is somewhat unique in that it
         | polyfills the platform-specific underlying flags automatically
         | when you do that. So you shouldn't include MAP_GROWSDOWN
         | because we chose to adopt the FreeBSD behavior which we
         | polyfill on Linux using MAP_GROWSDOWN. See our docs for further
         | details.
         | https://github.com/jart/cosmopolitan/blob/0a589add4167c1b587...
        
           | levodelellis wrote:
           | I see. I should check again because things can change but my
           | app is performance sensitive and when I checked last it
           | seemed to give myself a boost since I was writing to the
           | memory so quickly.
           | 
           | One of the reasons why I use MAP_GROWSDOWN is because it
           | gives me a page guard. Your link mentions/implements a page
           | guard. Well done
           | 
           | I tried my complicated app for fun removing the MAP_POPULATE
           | flag. I get an assert because it seems like mmap didn't align
           | the pointer to 4K. I don't need this to work I was just
           | playing around with it
        
             | jart wrote:
             | As you wish. I've just pushed a change removing the
             | restriction on MAP_POPULATE. https://github.com/jart/cosmop
             | olitan/commit/ccd057a85daf0d2d... Now that we have -n
             | (maximum niceness flag) I doubt anyone will object. If your
             | app is public and you're building it with Cosmo, then I
             | look forward to the opportunity to see it someday. Please
             | stay in touch. You're also welcome to join our Discord
             | community! https://discord.gg/mw3j3sa2
        
       ___________________________________________________________________
       (page generated 2022-07-14 23:00 UTC)