One of the prerequisites for seccomp filter is the new PR_SET_NO_NEW_PRIVS
prctl from Andy Lutomirski.
If you’re not interested in digging into creating a seccomp filter for your program, but you know your program should be effectively a “leaf node” in the process tree, you can call PR_SET_NO_NEW_PRIVS (nnp) to make sure that the current process and its children can not gain new privileges (like through running a setuid binary). This produces some fun results, since things like the “ping” tool expect to gain enough privileges to open a raw socket. If you set nnp to “1”, suddenly that can’t happen any more.
Here’s a quick example that sets nnp, and tries to run the command line arguments:
#include <stdio.h> #include <unistd.h> #include <sys/prctl.h> #ifndef PR_SET_NO_NEW_PRIVS # define PR_SET_NO_NEW_PRIVS 38 #endif int main(int argc, char * argv[]) { if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { perror("prctl(NO_NEW_PRIVS)"); return 1; } return execvp(argv[1], &argv[1]); }
When it tries to run ping, the setuid-ness just gets ignored:
$ gcc -Wall nnp.c -o nnp $ ./nnp ping -c1 localhost ping: icmp open socket: Operation not permitted
So, if your program has all the privs its going to need, consider using nnp to keep it from being a potential gateway to more trouble. Hopefully we can ship something like this trivial nnp helper as part of coreutils or similar, like nohup, nice, etc.
© 2012, Kees Cook. This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 License.