diff options
author | Colin Walters <walters@verbum.org> | 2012-08-10 15:07:42 -0400 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2012-08-10 15:07:42 -0400 |
commit | ce49cffb83d35e550c16b7aee23fac262e6f359d (patch) | |
tree | b78a5a641e198975a082f3e50cad7f0417fec6c6 | |
parent | 92457a2b2c29bba0ee272b7f86704ca10f44fd55 (diff) | |
download | linux-user-chroot-ce49cffb83d35e550c16b7aee23fac262e6f359d.tar.gz |
Make use of PR_SET_NO_NEW_PRIVS if available
This flag is exactly what we want for this tool (it's what I thought
SECBIT_NOROOT did).
See the linked discussion from here:
http://lwn.net/Articles/504879/
-rw-r--r-- | src/linux-user-chroot.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/src/linux-user-chroot.c b/src/linux-user-chroot.c index 7c2e678..3d5700c 100644 --- a/src/linux-user-chroot.c +++ b/src/linux-user-chroot.c @@ -5,7 +5,8 @@ * "safely": I believe that this program, when deployed as setuid on a * typical "distribution" such as RHEL or Debian, does not, even when * used in combination with typical software installed on that - * distribution, allow privilege escalation. + * distribution, allow privilege escalation. See the README for more + * details. * * Copyright 2011,2012 Colin Walters <walters@verbum.org> * @@ -30,6 +31,7 @@ #include <unistd.h> #include <stdio.h> #include <fcntl.h> +#include <errno.h> #include <stdarg.h> #include <string.h> #include <assert.h> @@ -47,6 +49,10 @@ #define SECBIT_NOROOT_LOCKED (1 << 1) #endif +#ifndef PR_SET_NO_NEW_PRIVS +#define PR_SET_NO_NEW_PRIVS 38 +#endif + static void fatal (const char *message, ...) __attribute__ ((noreturn)) __attribute__ ((format (printf, 1, 2))); static void fatal_errno (const char *message) __attribute__ ((noreturn)); @@ -274,16 +280,20 @@ main (int argc, if (child == 0) { /* - * SECBIT_NOROOT helps close the main historical reason why only - * uid 0 can chroot(2) - because unprivileged users can create - * hard links to setuid binaries, and possibly confuse them into - * looking at data (or loading libraries) that they don't - * expect, and thus elevating privileges. With this, executing - * a setuid program doesn't gain us any new Linux capabilities - * (but it still changes uid). See below for where we create a - * MS_NOSUID bind mount. + * First, we attempt to use PR_SET_NO_NEW_PRIVS, since it does + * exactly what we want - ensures the child can not gain any + * privileges, even attempting to execute setuid binaries. + * + * http://lwn.net/Articles/504879/ + * + * If that's not available, we fall back to using SECBIT_NOROOT. + * + * Following the belt-and-suspenders model, we also make a + * MS_NOSUID bind mount below. */ - if (prctl (PR_SET_SECUREBITS, + if (prctl (PR_SET_NO_NEW_PRIVS, 1) < 0 && errno != EINVAL) + fatal_errno ("prctl (PR_SET_NO_NEW_PRIVS)"); + else if (prctl (PR_SET_SECUREBITS, SECBIT_NOROOT | SECBIT_NOROOT_LOCKED) < 0) fatal_errno ("prctl (SECBIT_NOROOT)"); |