
Support of OpenBSD pledge(2) in programming languages - protomyth
https://gist.github.com/ligurio/f6114bd1df371047dd80ea9b8a55c104
======
teamhappy
Here's Theo de Raadt explaining how pledge(2) works:
[https://www.youtube.com/watch?v=F_7S1eqKsFk](https://www.youtube.com/watch?v=F_7S1eqKsFk)

~~~
kristopolous
can anyone provide a textual description of what this is? so far all I've
found is a broken manpage and a slideshow presentation without much
explanation.

~~~
tobik
[http://man.openbsd.org/OpenBSD-
current/man2/pledge.2](http://man.openbsd.org/OpenBSD-current/man2/pledge.2)
and the slides to the presentation
[http://www.openbsd.org/papers/hackfest2015-pledge/index.html](http://www.openbsd.org/papers/hackfest2015-pledge/index.html)

~~~
kristopolous
thanks ... that works. Also this register article is decent:
[http://www.theregister.co.uk/2015/11/10/untamed_pledge_hopes...](http://www.theregister.co.uk/2015/11/10/untamed_pledge_hopes_to_improve_openbsd_security/)

------
peter_tonoli
I've created a full 'awesome' list of Pledge resources at
[https://github.com/PeterTonoli/awesome-
pledge](https://github.com/PeterTonoli/awesome-pledge)

------
jack9
What a great way to fix up the choices that were necessarily lazy (socket to
syslogd) and are now attack vectors. I REALLY liked this talk and the concept.
It's not perfect, but it leads to better software by thinking about existing
programs in a new way (much like the priv-drop).

------
tyingq
The popular equivalent on Linux is seccomp, and the most straightforward way
to use it is libseccomp.[1]

A gist someone posted that's fairly easy to follow:
[https://gist.github.com/ya790206/9579145](https://gist.github.com/ya790206/9579145)

Theo de Raadt doesn't like it
([http://www.openbsd.org/papers/hackfest2015-pledge/mgp00011.h...](http://www.openbsd.org/papers/hackfest2015-pledge/mgp00011.html)),
but I don't see a huge difference between it and pledge.

[1]
[https://github.com/seccomp/libseccomp](https://github.com/seccomp/libseccomp)

~~~
justincormack
You really need to know your system calls back to front to work out how to
apply seccomp usefully and effectively. There are several hundred of them,
including historical versions which may or may not be used, depending on the
libc version that runs.

~~~
tyingq
Sure. But libseccomp does use the same "only explicitly allowed" path that
pledge() does. It also uses "pseudo" names for the syscalls, so there's one
place to look up the list:
[https://github.com/seccomp/libseccomp/blob/master/include/se...](https://github.com/seccomp/libseccomp/blob/master/include/seccomp.h.in#L581)

The aliases that pledge offers (like stdio) that sum up logical groups would
be nice, but that's a minor difference to me.

~~~
justincormack
You can blacklist or whitelist with seccomp it is up to you. The pseudo names
dont help significantly. It gives you a small amount of help with the
socketcall issues on 32 bit linux, but you are largely on your own.

Pledge also gives you ability to block or allow on pathnames, which you cant
do easily with seccomp, as you just get pointers. You are better off using one
of the other security mechanisms to deal with paths, but it is not simple.

------
Animats
OK, now someone put this in PDF readers, so that once they open the specified
PDF file, but before they start reading and parsing it, they call "pledge" and
lock out further file opens. (If this breaks Adobe WebBuy, so be it.)

~~~
stsp
The mupdf PDF reader has been patched to make use of pledge on OpenBSD.

~~~
nickpsecurity
An OpenBSD developer vouched for MuPDF's code quality on Schneier's blog. A
combo of good code and use of OS mitigations is a good sign. Might try to
switch to it soon.

------
mulander
Additional info in comments on lobste.rs:
[https://lobste.rs/s/dmhmdc/support_of_openbsd_pledge_2_in_pr...](https://lobste.rs/s/dmhmdc/support_of_openbsd_pledge_2_in_programming_languages)

------
OJFord
I'm not familiar with OpenBSD and certainly not with pledge, so I'm having
little luck finding the answer to:

Can I start a process in some way that means "demand a pledge call, and only
allow [x,y,z] / disallow [a,b,c]"?

~~~
umanwizard
The same way you start any other process: fork/exec. But in between (i.e.,
after you fork but before you exec), call pledge.

I can't test that since I don't have openbsd installed, but I don't see why it
wouldn't work.

~~~
sdkmvx
That won't work because exec resets pledge.

A very important part of pledge's design is that a parent can be more
restricted than its child. This isn't a sandboxing mechanism. It's intended to
mitigate the dangers of some other vulnerability leading to remote code
execution. With pledge, even if you get into the system you may not be able to
make all the syscalls you need.

~~~
amluto
> A very important part of pledge's design is that a parent can be more
> restricted than its child. This isn't a sandboxing mechanism. It's intended
> to mitigate the dangers of some other vulnerability leading to remote code
> execution. With pledge, even if you get into the system you may not be able
> to make all the syscalls you need.

ISTM this will just slightly raise the bar so that attackers who get code
execution have to force a call to execve.

On the other hand, it avoids needing to worry about all the setuid issues that
Linux's seccomp avoids using PR_SET_NO_NEW_PRIVS.

~~~
brynet
It is indeed another security mitigation, any potential attack payload will
need to do more work and hence require more code.

In fact, most programs will not need the exec promise in which case any
attempt to call execv(3)..

 _Abort trap (core dumped)_

If you think about the semantics of execv(3), it needs a path to an existing
executable. So an attacker will need to know of one in advance, or write one
out to disk beforehand.. oh but--

 _Abort trap (core dumped)_

The exploited process pledged "stdio rpath proc exec" and cannot write to
arbitrary files. Hmm. Bummer.

~~~
amluto
> If you think about the semantics of execv(3), it needs a path to an existing
> executable. So an attacker will need to know of one in advance, or write one
> out to disk beforehand.. oh but--

/bin/sh, perhaps? It's harder to pass in machine code, but I bet there's a
way. /bin/sh -c "echo -e shellcode_here >/tmp/foo; chmod 700 /tmp/foo;
/tmp/foo" seems plausible to me.

~~~
mbrock
Well, binary shellcode often has the sole purpose of providing shell access,
so if you can just exec /bin/sh then that job is already done...

------
f2f
it seems to me that the Go package can easily slot in golang.org/x/unix, where
all the extra syscalls not present in the fixed stdlib syscall package go.
that's a minor point. if pledge becomes widespread in usage it will get its
spot there.

------
bluejekyll
pledge seems like it could also help in another scenario that the recent npm
issues should make us worry about.

When using a third party library, it should be possible to have more faith
that it's not doing something unexpected. So not only can it protect you
against ingress attacks, but also potentially against malicious code you might
accidentally include in your software.

(I'm assuming of course that the third party library can't reset the pledge)

------
BogusIKnow
Idea looks really really nice.

Not sure how some edge cases (?) are handled. For example if a database server
goes down, my app that uses pledge needs to open another socket to another
server. Reload of changed configurations?

"Unpledge" then pledge again? Whitepaths?

~~~
yxlx
I think being able to "unpledge" would defeat the purpose of pledge. Instead,
I think the better way would be to have your app run by a parent, and when you
lose connectivity to your db server, you crash your app on purpose and
whenever your app crashes, parent restarts it. Problem solved, I think.

~~~
BogusIKnow
Thanks!

------
umanwizard
Anyone know what the major differences are between OpenBSD's pledge and OS X's
libsandbox ?

~~~
sdkmvx
OS X's libsandbox is much closer to SELinux. It's MAC-based (mandatory access
control not Macintosh) and is actually TrustedBSD under the covers. Pledge
simply disallows access to syscalls and paths outside a list. It's not very
fine-grained. It also resets on exec, so it can't be used as a sandbox or
container.

~~~
brynet
The entire point of pledge is self-sandboxing, in the case of an exec promise
the expectation is the new process will also self-sandbox.

If you think of a shell as an example, it will need to exec programs that do
privileged things before they can drop them, but the parent shell itself may
never need to say.. create sockets.

~~~
icebraining
Unless it's Bash, with its /dev/tcp interface.

