Is it possible to use a set of C library or system calls to drop all user privileges on POSIX, or at least on Linux? Note that I am not asking how to drop root
privileges, which is what all of the other StackOverflow search results seem to be asking and answering.
I want the same effect as switching to user nobody
, but stronger if possible. That is, I want my C application to do the following:
root
, and without the setuid file permission bit$HOME
accept
Things I have considered so far that don't fit the bill:
nobody
with setuid
/setgid
nobody
), and the application should not require root
just to switch to nobody
.root
-like privileges, not take away ordinary user privilegesexit
, sigreturn
, read
, and write
Things that look interesting, but for which I couldn't find documentation, appear to be unmaintained, or appear to be non-portable:
So is there a well-documented, preferably portable way to drop nonessential user privileges and sandbox a process without having to become root
first?
It's unlikely any solution will work on all POSIX, since POSIX doesn't define the mechanism you're looking for.
Looking at just the requirements and just Linux, probably the easiest way to satisfy them is actual via the security modules. Any of apparmor, selinux, RBAC will do what you need, but only via external profile - not something built into your app. The problem may be that adding a profile in all those cases requires the root user to do it (but the profile applies to user process too).
A bit more complicated solution that almost satisfies the requirements is seccomp. While it doesn't understand paths at all (you can only see pointers), there are ways to limit the access: seccomp policies can be defined per thread, so you could redesign your system to have a "path verification thread", which doesn't do anything apart from reading paths and returning sockets if they match your specification. Then limit that thread to just recv()
, open()
and send()
. Thread doing other work can then drop open()
and use the other service.
Or if you can configure the paths at program startup, you can put them into an array, mark that page as read-only, and setup seccomp policy which will only accept open()
with filenames from that array (that's just a pointer comparison in that case).
To some extent, the approach of splitting application into separate processes which have very limited responsibilities is something you could replicate on other systems, but without the same guarantees as on Linux. For example qmail is kind of a system of very small processes which work as a pipeline for data (simplification). On Linux you could still apply seccomp to them, on Solaris just drop exec
and other capabilities, on other systems... I don't know, but probably you can do something.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With