9 ms·
A subsystem to restrict programs into a “reduced feature operating model”
- deleted 11y ago[deleted]
- vmorgulis 11y agoIt reminds me SELinux.
- Taranis 11y agoNot really.
- deleted 11y ago[deleted]
- vezzy-fnord 11y agoFor another example of a similarly beautiful interface that echoes "difficult solution made stupidly simple to use", checkpointing under DragonFly BSD: http://leaf.dragonflybsd.org/cgi/web-man?command=sys_checkpoint§ion=2 http://leaf.dragonflybsd.org/cgi/web-man?command=sys_checkpo... On an unrelated note, I've always had respect for how Theo de Raadt is both the project leader of a complete BSD system, yet also an active hacker. Contrast to Linus Torvalds, who's mostly a manager nowadays.
- Mister_Snuggles 11y agoThis is a very good point. I definitely see the value in it, and making it simple to use means that programs are more likely to actually use it.
- TheLoneWolfling 11y agoOn an unrelated note, but tangential to your link, why can I not save and restore processes? It seems like something that would be relatively easy to do - suspend all threads, save the thread control blocks, mark all pages as fault-on-write, resume threads, and start saving pages, unmarking them once they are saved. If/when a thread faults, copy (or save immediately) that page and then resume that thread. (Or potentially don't resume the threads until after you save everything, although that may cause problems...) You need to deal with file handles / etc, but that can be done too. Not really different than hibernation.
- thorwafspp 11y agoYou've tickled on the problem but not quite nailed it. > You need to deal with file handles / etc, but that can be done too. That's actually the hard part. To get a real image of that process in time, you need to snapshot the full filesystem state, too. Or it could change out from beneath your program. Even more complicated: network state.
- Demiurge 11y agoWhy is network more complicated? I would think network doesn't have any atomic/uninterruptible states filesystem might?
- duskwuff 11y agoIf a process has a stream socket open to another process, or to another system over the network, what happens to that socket when the process is "thawed"? How about if it's listening on a TCP port -- what happens if that port is in use by another process when the original one is thawed?
- Demiurge 11y agoI understand this can't go 'right', but are those things more difficult than filehandles to files that have been deleted?
- duskwuff 11y agoHandles to deleted files are relatively uncommon in practice. Network sockets aren't.
- dllthomas 11y ago"Handles to deleted files are relatively uncommon in practice." Could you please expand on your reasoning here? We're talking about restoring processes at arbitrary points in the future. That means we're not just talking about handles to files that were deliberately deleted while the process was running, but also anything that the process had open that was frozen that may have been subsequently deleted. That would seem to include any log file that gets rotated, which is not exactly rare, plus a ton more things. I also think that treating network sockets as if they were disconnected is likely to go better than treating files that way - existing programs probably make more assumptions about disk state not changing unexpectedly than about network state not changing unexpectedly (even if both are technically not well founded).
- Mister_Snuggles 11y agoThis is an interesting idea, but something about having various "behaviours" baked into the logic concerns me. I'm certain that Theo has thought about this and understands the implications better than I do though. For example, if your process has TAME_GETPW opening /var/run/ypbind.lock enables TAME_INET. The reasoning behind this makes sense, but now it means that yp always has to open that file before it can do its thing. The behaviour of yp always opening that file before accessing the network is now required by the kernel. The saving grace is that OpenBSD (and the other BSDs) are developed as a unified system, so if yp ever changes to no longer use that file, that change will only come as part of a version upgrade that includes the kernel, etc.
- TheLoneWolfling 11y agoSo, do I have it right that this is effectively a way of a program being able to declare to the operating system "I shouldn't ever do <x>"? Because, if so, that makes a whole lot of sense. (Adding security "for free" generally does). This could conflict with on-the-fly upgrades, though. If it turns out that some later version of your program does in fact require <x>, then you'll have to kill and restart the process as opposed to upgrading on-the-fly. Perhaps not the end of the world, but worth noting.
- Mister_Snuggles 11y agoThat's my interpretation of it. Basically your program does its initialization, then says to the system "Ok, here's all I need from this point forward." Making this level of security this easy is a huge win.
- adrusi 11y agoIt can also be used by a parent process to limit the functionality of a child process, by calling tame() after fork() and before exec(). I can imagine this being used with some a "tame" command in the shell to run untrusted programs. Of course I don't know how thorough the sandboxing is, and I wouldn't trust it to make unsafe programs completely safe.
- cnst 11y ago> Of course I don't know how thorough the sandboxing is, and I wouldn't trust it to make unsafe programs completely safe. That's the best part about OpenBSD -- the APIs may not be binary or even source-code compatible between the releases, but the source code is usually as readable and as clear as it gets.
- Athas 11y ago> I can imagine this being used with some a "tame" command in the shell to run untrusted programs. This might not be useful in practice. The inspiration behind tame() is the observation that a program usually needs many more rights at initialisation-time than in its main-loop. Thus, tame()ing a program before it even starts is unlikely to be practical - if you give it enough permissions to successfully start (including whatever is needed for dynamic linking), you may not have reduced its capabilities much.
- deleted 11y ago[deleted]
- wfunction 11y agoThis won't work for programs that allow for plugins, which are arguably those that need the most protection. Programs don't generally know what permissions plugins when they are compiled.
- icebraining 11y agoI don't see why this would need to be known at compile time. You could load the plugins, ask them what they need, then drop everything else.
- obstinate 11y agoHrm. I don't see why not? The plugin declares its behaviors in a manifest. During program initialization, the program reads all the manifests, sums the permissions, and declares those. Of course, if you download an infected plugin, you're going to have a bad time. But that is likewise a problem if you download an infected program and run it. It's not an attack vector this syscall is meant to prevent.
- yk 11y agoI don't think that the plugin should declare it's behavior. Consider the case were you have a shared webserver and a php-plugin for one user (say a wordpress installation). Then the user ( or anyone with write access to the user directory) can control the permissions of the server. On the other hand, a well designed plugin interface could set default permissions. For example the plugin interface could have a SQL method, so that a plugin does not need to talk to a socket directly.
- wmf 11y agoI think the OpenBSD philosophy is to run plugins in separate processes.
- paulannesley 11y agoI'd presume child processes would inherit the same restrictions as the parent process. I guess a root process could remain privileged, the main restricted process could be a child of that, and that main process could ask the root process to spawn plugins. But, that'd weaken the model a bit.
- icebraining 11y agoWindows 8 has an equivalent of this, using a "mitigation policy" called ProcessSystemCallDisablePolicy, which is set using SetProcessMitigationPolicy(). Chrome uses this for their sandbox of rendering processes.
- gpvos 11y agoIt looks like you can only disable GUI calls with it (the very sparse documentation seems to contradict itself a bit though). Also, a model in which you specify which calls you want to enable (and everything else gets disabled) is stronger than one in which you specify which ones you want to disable.
- higherpurpose 11y agoIndeed, it's the whole whitelist vs blacklist [1] debate. Whitelists are radically safer. [1] - https://farm9.staticflickr.com/8669/16418068728_b8dd8aa200_c.jpg https://farm9.staticflickr.com/8669/16418068728_b8dd8aa200_c...
- geofft 11y agoThis doesn't seem particularly better than Linux's seccomp-bpf or OS X's seatbelt. In particular, I don't really understand the complaint about not wanting to write a program, then turning around and writing a system call, running with full privilege on the system, that hardcodes all sorts of things about userspace. I wish he'd acknowledge and discuss prior, effective work in this space instead of saying things "showed up" and they're "insane". For instance, a direct comparison to either seatbelt or seccomp-bpf would make it clear that the distinction between initialization vs. steady state is well-explored in production systems using this (like sandboxed Chrome renderers) and not novel.
- comex 11y agoThe implementation is better than OS X, because OS X has a ton of kernel API surface available to userland and much of it can't even be sandboxed, while tame starts with one syscall and works its way up. I agree it's not better than seccomp-bpf plus a library to supply these kinds of common policies in userland, with the caveat that I don't know of any such library in common use on Linux.
- geofft 11y agoYeah, seatbelt is not that compelling in practice, but that's true of the OS X kernel/userspace boundary in general. :/ But the design of it seems to match what's wanted here, exactly: you can enable restrictions during the running of a process, and OS X ships with a handful of standard seatbelt profiles. pcwalton's gaol, which has both seccomp-bpf and seatbelt backends, has a concept of "profiles," which I think matches the general idea here: https://github.com/pcwalton/gaol https://github.com/pcwalton/gaol To be fair I wouldn't use it in production yet, but it's quite a bit more reviewed than tame(2) is right now.
- strcat 11y agoI don't think it would be particularly useful. The most common usage of seccomp is hardening an existing sandbox by reducing kernel attack surface. Fine-grained control is crucial for that, since it's the entire point. Every unnecessary system call or permitted system call flag is added attack surface. When seccomp is actually being used to implement the sandbox semantics, the application usually needs to be designed around it. It's very difficult to apply it this way to an existing application. I just don't think there's a strong use case for coarse control when it's so far from being the real hard problem.
- brynet 11y agoThe kernel pieces of tame(2) have just been committed: http://marc.info/?l=openbsd-cvs&m=143727335416513&w=2 http://marc.info/?l=openbsd-cvs&m=143727335416513&w=2
- nitrogen 11y agoI recently asked for exactly this on StackOverflow, but for Linux[0]. Is anyone aware of an interface to seccomp-bpf on Linux that is as easy to use as this tame() syscall? If not, does anyone want to join forces to create one? An ultra-simple library that provides tame()-like functionality on all capable platforms should make writing secure software a lot easier. [0] https://stackoverflow.com/questions/31373203/drop-privileges-as-regular-non-root-user-for-sandboxing/31373324#31373324 https://stackoverflow.com/questions/31373203/drop-privileges... if anyone's curious
- vidarh 11y agoI would look into the Chrome/Chromium sandbox code, as they seem to have at least some facility for parsing simple profiles. This page has some details: http://www.chromium.org/chromium-os/developer-guide/chromium-os-sandboxing http://www.chromium.org/chromium-os/developer-guide/chromium...
- binarycrusader 11y agoSee also, Solaris' Role-Based Access Control and Privileges models. Privileges (seems to fit the post): https://blogs.oracle.com/casper/entry/solaris_privileges https://blogs.oracle.com/casper/entry/solaris_privileges http://www.c0t0d0s0.org/archives/4075-Less-known-Solaris-features-RBAC-and-Privileges-Part-3-Privileges.html http://www.c0t0d0s0.org/archives/4075-Less-known-Solaris-fea... Programming with Privileges Example: http://docs.oracle.com/cd/E23824_01/html/819-2145/ch3priv-25082.html#priv-12 http://docs.oracle.com/cd/E23824_01/html/819-2145/ch3priv-25... Overview: http://www.c0t0d0s0.org/archives/4077-Less-known-Solaris-features-RBAC-and-Privileges.html http://www.c0t0d0s0.org/archives/4077-Less-known-Solaris-fea... In particular, the Solaris privileges model allows a program to gracefully degrade functionality and drop and reinstate privileges at different points of execution.
- SloopJon 11y agoThis interface makes a system call at run time to reduce privileges. I wonder if there is a way to do this statically and automatically, either with some header file magic, or by analyzing the symbols in the executable: just assume at link time that any system calls it makes (and only those) are allowed.
- whacker 11y agowell, if it can create new address space mappings, it can simply create a new text mapping and execute the call from there. If anything, the place to implement it statically could be either a virtual machine jit, or at the compilation stage.
- Mordak 11y agoLooking at a program statically and limiting its privileges automatically would be good (autotame?), but it misses the point that tame appears to be trying to solve. Specifically, it is often the case that programs need more privilege once at initialization time, and less privileges later. So at startup, your program needs to open some files, and open listening network sockets, etc., but once initialization is done it just needs CPU. A static analysis would see that the program opens files and listening sockets and stuff, and grant those privileges forever. If you want to capture the reduced privileges required after the one-time initialization then you need to modify the program to use something like tame (or capsicum, etc.).
- cnst 11y agoFor comparison, the man-page for FreeBSD's capsicum API: http://mdoc.su/f/capsicum.4 http://mdoc.su/f/capsicum.4.
- josephcooney 11y agoThis sounds very similar to code access security (CAS) that Microsoft's CLR had from around 2000 (but at the OS level rather than the VM level).
- philsnow 11y agoI can't see where in this patch forked children inherit the `ps_tame` from the parent process. I don't know this kernel at all but it seems like something like this should be in sys/kern/kern_fork.c pr->ps_tame = parent->ps_tame Otherwise tamed processes could just fork a process to do things they've declared that they won't do.
- brynet 11y agoA tamed process cannot even call fork(2) unless the TAME_PROC flag is passed, in which case I'd assume the child process would then inherit a copy from the parent as part of a normal fork(2) operation. It can be later revoked by the child, but it may want to keep it for kill(2).
- philsnow 11y agoI'm `cvs get`ting as fast as I can to read the rest of sys_fork.c to sate my curiosity, but CVS incredibly slow. I'm spoiled by how git packs the repo.
- philsnow 11y agoturned out to be way faster just to grab http://mirrors.sonic.net/pub/OpenBSD/5.7/sys.tar.gz http://mirrors.sonic.net/pub/OpenBSD/5.7/sys.tar.gz , if anybody else wants to poke around and doesn't want to wait for cvs.
- glass- 11y agoYou can also view the source on the cvs web mirror: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/ http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/
- stsp 11y agoSounds like you're doing something unnecessarily more complicated than this: $ time cvs -d anoncvs@anoncvs1.ca.openbsd.org:/cvs export -rHEAD src/sys/kern/kern_fork.c U src/sys/kern/kern_fork.c 0m2.73s real 0m0.06s user 0m0.04s system
- stock_toaster 11y agoGreat to see another attempt at this model. I do like capsicum (seems pretty straightforward), but it seems like it can require some added complexity with things like casperd for dns. Very interested to see how this works out.
- ghshephard 11y agoThis is pretty brilliant/obvious in hindsight. In addition to the sandboxing protection, you also have a really good inventory of what privileges the application requires. Looking over the diffs in the applications - most of them are two or three lines - a #include <sys/tame.h> followed by something simple like tame(TAME_STDIO | TAME_DNS | TAME_INET); What I really like about a lot of the OpenBSD initiatives, is they don't overthink their solutions - they make them as simple as possible, but no simpler. Signify, which avoided the entire web-of-trust/PKI complication is another example.
- evincarofautumn 11y agoYeah, it’s a basic dynamic role/coeffect system, which goes a long way toward enforcing correctness and safety, much as types do (whether static or dynamic).
- Animats 11y agoHaving fine-grained capabilities and the ability to turn them off is always useful. The usual problem is that some component needs to, say, open a file, so all code gets "open file" privileges. There's a tool like this for Android phones. It not only can turn privileges off for an application, but also offers the option to provide apps fake info for things they don't need. You can, for example, deny address book access; if the app tries to access the address book, it gets a fake empty one. You can deny camera access; the app gets some canned image. This allows you to run overreaching apps while keeping them from overreaching.
- programmer_dude 11y agoWhats the name of this app? Can it run without root permissions?
- pki 11y agoxprivacy/xposed framework, no
- higherpurpose 11y agoI wish Android allowed power users to create "root accounts" on Android, similar to how you can create Admin accounts on Windows, but be completely isolated from the default safe account.
- raverbashing 11y agoYeah, for 'open file' kind of stuff it would be better to have a real sandbox (I think Windows began doing something like this, not sure if in Vista or 7, that if programs wanted to write to certain restricted places they can - but this is written to their sandbox, so if they read it later they can get the files but with no effect on the system files)
- TazeTSchnitzel 11y agoVista did that as a compatibility workaround. Older Windows apps from the 9x and XP era were used to being run as Administrator and being able to write directly to Program Files and the like. In order to make some of these work on Vista without running them as Administrator, the solution was to lie to the applications and make their writes go through to sandboxes instead. The sandboxing was flawed, though. It causes problems for some applications. For example, Gang Garrison 2, a game I have worked on, fails to update itself if stuck in Program Files and not run as admin.
- MichaelCrawford 11y agoA simple easy way to keep a lid on privelige escalation is to remove all the files that you computer does not absolutely require to do its job. Especially the development tools: the Morris worm enabled portability by distributing itself in source code form then building its binary on its target hosts. My sister once read a novel about some very traditional, strictly religious people who fastened their shirts with string ties as they felt buttons were hooks that the Devil could use to grab hold of you. I feel much the same way about files. I dont know what tomorrow's zero-day will look like but the chances are quite good that it will depend on a file that is installed by default. Cliff Stoll wrote in "The Cuckoo's Egg" of a subtle bug in a subprogram used by GNU emacs for email. Had the Lawrence Berkeley Laboratory used vi rather than emacs they would not have been vulnerable. ;-D Yes it is a step in the right direction not to run daemons or windows services you dont need but its even better to remove them. In 1990 I wrote an A/UX 2.0 remote root exploit to drive home my objection to one single file having incorrect permissions. Its source was about a dozen lines. That particular file was required but our default installs have many files we dont really need. Also if you can read - not just execute - the binary to any program or library then your malware can load it into its memory then execute it. We have no way of knowing who is going to do that tomorrow but we do know there are many binaroies we do not really need. If you develop code for your server, install the same distro in a vm on your desktop box then compile it there.
- MichaelCrawford 11y agoIt is common for executables to have these permissions: rwxr-xr-x maybe this is better: --x--x--x what that means is that you can run the program but you cannot read it as a regular file. To delete or create a file you must have write permission to the directory it is or will be found in. Yes it's a PITA to take away your own permissions but your server is not the box you take with you when you hang out at Starbucks.
- gnuvince 11y ago> A simple easy way to keep a lid on privelige escalation is to remove all the files that you computer does not absolutely require to do its job. Taken to its logical conclusion, you sort of end up with a unikernel system, like Mirage OS[1]: only the code necessary for the execution of the service is compiled into the kernel. These systems don't even have a shell. [1] https://mirage.io https://mirage.io
- higherpurpose 11y agoSo when is OpenBSD getting rewritten in Rust?
- SFjulie1 11y agoLet's say I received a SIGHUP and I need to reload my configuration after I dropped my right for reading /etc/ and all the syscall for provisioning my resources. How screwed am I?
- brynet 11y agoYou would have a parent process that retains permissions to read configuration and sends changes to children, i.e: imsg_*(3) on OpenBSD. http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/ibuf_add.3 http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/...