aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJorge Lucangeli Obes <jorgelo@google.com>2016-03-14 14:34:10 -0700
committerJorge Lucangeli Obes <jorgelo@google.com>2016-03-21 14:21:01 -0700
commitf783b5273d66d19a78705276a38ae68ef2e3e165 (patch)
tree6cc2402f12faffc14aca6b6e11a0f430ee43b7c5
parenta867c8204c1fe303f2de9a202e6454d230488a47 (diff)
downloadminijail-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.mk4
-rw-r--r--libminijail.c44
2 files changed, 39 insertions, 9 deletions
diff --git a/Android.mk b/Android.mk
index 82f4c29..9be2907 100644
--- a/Android.mk
+++ b/Android.mk
@@ -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)");
}