diff options
author | Jorge Lucangeli Obes <jorgelo@google.com> | 2016-03-14 14:34:10 -0700 |
---|---|---|
committer | Jorge Lucangeli Obes <jorgelo@google.com> | 2016-03-21 14:21:01 -0700 |
commit | f783b5273d66d19a78705276a38ae68ef2e3e165 (patch) | |
tree | 6cc2402f12faffc14aca6b6e11a0f430ee43b7c5 | |
parent | a867c8204c1fe303f2de9a202e6454d230488a47 (diff) | |
download | minijail-f783b5273d66d19a78705276a38ae68ef2e3e165.tar.gz |
Fix use of SECURE_ALL_BITS/SECURE_ALL_LOCKS.
Kernels 4.3+ define a new securebit (SECURE_NO_CAP_AMBIENT_RAISE),
so using the SECURE_ALL_BITS and SECURE_ALL_LOCKS masks from newer
kernel headers will return EPERM on older kernels. Detect this, and
retry with the right mask for older (2.6.26-4.2) kernels.
Also add a compile-time assert to make sure we identify these changes
sooner going forward.
Bug: 27632733
Change-Id: I6cf9c56fec222347575bd0d1147287aac6572e67
-rw-r--r-- | Android.mk | 4 | ||||
-rw-r--r-- | libminijail.c | 44 |
2 files changed, 39 insertions, 9 deletions
@@ -24,9 +24,7 @@ libminijailSrcFiles := \ syscall_filter.c \ util.c -# TODO(b/27632733): Re-enable including the system's <linux/securebits.h>. -#minijailCommonCFlags := -DHAVE_SECUREBITS_H -Wall -Werror -minijailCommonCFlags := -Wall -Werror +minijailCommonCFlags := -DHAVE_SECUREBITS_H -Wall -Werror minijailCommonLibraries := libcap # Android devices running kernel version < 3.8 are not required to diff --git a/libminijail.c b/libminijail.c index 2927b62..fcfee1e 100644 --- a/libminijail.c +++ b/libminijail.c @@ -43,13 +43,28 @@ #include "util.h" #ifdef HAVE_SECUREBITS_H -#include <linux/securebits.h> +# include <linux/securebits.h> #else -#define SECURE_ALL_BITS 0x15 -#define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1) +# define SECURE_ALL_BITS 0x55 +# define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1) #endif +/* For kernels < 4.3. */ +#define OLD_SECURE_ALL_BITS 0x15 +#define OLD_SECURE_ALL_LOCKS (OLD_SECURE_ALL_BITS << 1) -/* Until these are reliably available in linux/prctl.h */ +/* + * Assert the value of SECURE_ALL_BITS at compile-time. + * Brillo devices are currently compiled against 4.4 kernel headers. Kernel 4.3 + * added a new securebit. + * When a new securebit is added, the new SECURE_ALL_BITS mask will return EPERM + * when used on older kernels. The compile-time assert will catch this situation + * at compile time. + */ +#ifdef __BRILLO__ +_Static_assert(SECURE_ALL_BITS == 0x55, "SECURE_ALL_BITS == 0x55."); +#endif + +/* Until these are reliably available in linux/prctl.h. */ #ifndef PR_SET_SECCOMP # define PR_SET_SECCOMP 22 #endif @@ -1444,8 +1459,25 @@ void API minijail_enter(const struct minijail *j) */ if (prctl(PR_SET_KEEPCAPS, 1)) pdie("prctl(PR_SET_KEEPCAPS)"); - if (prctl - (PR_SET_SECUREBITS, SECURE_ALL_BITS | SECURE_ALL_LOCKS)) + + /* + * Kernels 4.3+ define a new securebit + * (SECURE_NO_CAP_AMBIENT_RAISE), so using the SECURE_ALL_BITS + * and SECURE_ALL_LOCKS masks from newer kernel headers will + * return EPERM on older kernels. Detect this, and retry with + * the right mask for older (2.6.26-4.2) kernels. + */ + int securebits_ret = prctl(PR_SET_SECUREBITS, + SECURE_ALL_BITS | SECURE_ALL_LOCKS); + if (securebits_ret < 0) { + if (errno == EPERM) { + /* Possibly running on kernel < 4.3. */ + securebits_ret = prctl( + PR_SET_SECUREBITS, + OLD_SECURE_ALL_BITS | OLD_SECURE_ALL_LOCKS); + } + } + if (securebits_ret < 0) pdie("prctl(PR_SET_SECUREBITS)"); } |