4 ms·
this reminds me of a recent presentation posted here about OpenBSD's coming support for "pledges" [1]. I suppose the difference here is that pledges use a sing
by aabaker99 11y ago
this reminds me of a recent presentation posted here about OpenBSD's coming support for "pledges" [1].
I suppose the difference here is that pledges use a single kernel but restrict kernel interfaces for each process while the unikernel approach creates a kernel subset for each VM (and thus each process, for VMs dedicated to a single process).
Can anyone knowledgeable comment about the advantages or disadvantages of each? I'm guessing unikernals will be more portable (only OpenBSD is doing pledges to my knowledge) and more popular with the containerization movement. Can pledges accomplish the same objective with better use of system resources?
Edit: clarity about portability point
[1] http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/pledge.2 http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/...
- masklinn 11y agoThey're compatible approaches, you could use pledges in a unikernel for exactly the same reason in order to further reduce the application's attack surface: a unikernel includes only what the application needs but it can't take advantage of the application's needs varying (reducing) over time[0], which is pledge(2) allows. [0] one of the reasons for pledge(2) was the realisation/understanding that many applications have an initial setup phase followed by a "stable state", where the stable state needs significantly less services than the setup e.g. setup might require reading config files but the steady state doesn't and just listens on a socket, so you can call pledge(2) multiple times and further reduce the application's abilities (attempting to increase them will fail with EPERM)
- cpuguy83 11y agoNeat!
- avsm 11y ago(I'm a slacking OpenBSD developer and a unikernel hacker, so I guess I should respond :-) Pledging is the most usable form of priv-dropping I've seen yet in any OS, since it was designed after looking at the "flow" of how a typical daemon interacts with the kernel, rather than a low-level syscall interface that the typical programmer would have no idea about. I've used many of the different privilege dropping interfaces in OpenBSD over the years, and to recall the journey: - Separating out syslogd back in 2003 was a fun adventure in manual privsepping before it became mainstream; I think just sshd used in it base before that. This required building an automaton of how the privileged messages from syslog would work, and carefully coordinating the state machine and message passing around that. http://marc.info/?l=openbsd-cvs&m=105967566808306&w=2 http://marc.info/?l=openbsd-cvs&m=105967566808306&w=2 At this point we had two processes, but the root process couldn't do fine-grained dropping of privileges and just had to be carefully audited by lots of people. - systrace came along, which allowed policies to be built about which syscalls could be called. The policy language was limited, so I got really excited by the possibilities and wrote a DSL to make it easier to build systrace policies; http://anil.recoil.org/papers/sam03-secpol.pdf http://anil.recoil.org/papers/sam03-secpol.pdf. In the end I gave up on using systrace since it was so brittle to unrelated changes in libc or dependent libraries changing the order of system calls and causing apps to break all the time. - Pledge is almost the opposite of systrace. You provide a series of human-readable strings, and the OS takes care of mapping those to groups of syscalls. This makes so much more sense, since the person making the change can also update the pledge, and applications don't break! If you look at OpenBSD current, over half of the base daemons are now pledging. At no point are there insanely complex policies like SELinux, nor are there the race conditions of systrace. In fact, the most similar approach to this I've found is MacOS X entitlements, which also let the application specify what functionality it would like (as opposed to what syscalls it needs) So, what's the relation to unikernels? Well, they are completely the opposite approach. Instead of starting with a wide kernel interface and then restricting it, unikernels start with a very narrow interface (the hypervisor) and build up higher level abstractions as they are demanded by the application. This happens via a series of libraries, and so the programmer can choose at compile time how to weave in privilege levels and the use of hardware enforcement (such as processes). I can see both pledge and unikernels converging in the future, specifically by a linker that would be aware of the pledges that a library needs, and mapping the appropriate hardware enforcement into the resulting unikernel. I'm not aware of anyone actually working on this, but get in touch with me if you are interested... (anil@recoil.org)