3 ms·
The "anet" pledge says that "this allows to accept, but not initiate socket connections"...but then still appears to allow for creating new AF_INET SOCK_DGRAM s
by chc4 3y ago
The "anet" pledge says that "this allows to accept, but not initiate socket connections"...but then still appears to allow for creating new AF_INET SOCK_DGRAM sockets and sendto, which allows for sending UDP packets without an established connection. That's probably a sandbox escape on a lot of systems, since you could sendto localhost UDP daemons.
In general the pledge syscall filters are very permissive, which makes it hard to be sure of security; Chromium libsandbox is insanely restrictive in contrast, because that's really what's needed to be confident in your attack surface, especially if you start worrying about kernel privilege escalation exploits like Chrome does. I wasn't aware of the landlock LSM before this, though, which seems pretty neat and a lot less intrusive than selinux for application specific white/blacklisting.
- jart 3y agoIt needs to be able to send unix datagrams so it can blackhole your IP address in the RAW PREROUTING iptable if you DDOS the system. https://github.com/jart/cosmopolitan/blob/f10845ab9f847e4cadbee93520f17e1661845f50/net/turfwar/blackholed.c#L64 https://github.com/jart/cosmopolitan/blob/f10845ab9f847e4cad... You can't ban someone's IP without root. So we have two choices: (1) create a setuid binary the web server can launch that does it, or (2) run a daemon as root that listens for AF_UNIX datagrams. To do (1) I'd need to grant fork() + execve() privileges, which I view as more problematic than (2) which only needs sendto (possibly even just write). You've helped me realize that I can make the blackholed integration much tighter than the way it's currently being implemented in https://github.com/jart/cosmopolitan/blob/f10845ab9f847e4cadbee93520f17e1661845f50/third_party/python/Modules/tokenbucket.c#L230 https://github.com/jart/cosmopolitan/blob/f10845ab9f847e4cad... so thank you! As for surface area, I expected people to rake me over the coals for blocking io_uring. I didn't anticipate support for Google's zeal. OpenBSD is actually even more permissive than me when it comes to letting stuff through pledge("stdio"). https://github.com/openbsd/src/blob/fb5793d3d4d0fd4795586dd9601a4aa58f1f3efa/sys/kern/kern_pledge.c#L117 https://github.com/openbsd/src/blob/fb5793d3d4d0fd4795586dd9... Also surface area isn't a weakness, it's a paradigm. If a weakness actually exists, then you must exploit it. So long as you tell us what you did, for the post-mortem.
- chc4 3y agoI was specifically talking about AF_INET dgram sockets, not AF_UNIX; I saw that it wasn't pledged and assumed that was by design (since having that and sendto would be extremely unsafe, since you could connect to abstract unix sockets). If you want to use an inherited unix socket for the blacklisting, you should use SOCK_STREAM unix sockets instead so you can't sendto. Even allowing localhost UDP sockets isn't safe to expose to a sandbox, IMO, since Linux programs fairly often expose privileged operations over those and have no way of knowing the client is supposed to be sandboxed and rejected.
- jart 3y agoI see what you mean now. When we created the "anet" category, the main intent was to prevent redbean from making outbound HTTP connections. Allowing UDP looks like a copy and paste error. You're correct that it is a weakness. Thank you for identifying it! I'm in the process of fixing it now. How would you like to be credited?
- chc4 3y agoJust chc4 is fine, otherwise @sickeningsprawl@infosec.exchange (and Twitter, though I haven't used that in several months).
- jart 3y agoSee https://github.com/jart/cosmopolitan/commit/48b2afb192ec18eca40c0b25603c02a2e3b578e9 https://github.com/jart/cosmopolitan/commit/48b2afb192ec18ec... and https://twitter.com/JustineTunney/status/1670600564164657154 https://twitter.com/JustineTunney/status/1670600564164657154
- JoachimSchipper 3y agoI may just be confused, but couldn't you pass a pipe into the whole (server) process, instead of having it open its own sockets? (In https://github.com/jart/cosmopolitan/blob/48b2afb192ec18eca40c0b25603c02a2e3b578e9/third_party/python/Modules/tokenbucket.c#L247 https://github.com/jart/cosmopolitan/blob/48b2afb192ec18eca4..., I gather?) I haven't followed cosmopolitan / Linux pledge() too closely; but I notice your SERVER_PLEDGE and CLIENT_PLEDGE include stdio, so I expect you have write(2) (and could thus handle a pipe, and maybe even a passed-in AF_UNIX socket?) Or is making the challenge more interesting - by actually including some networking - part of the fun?