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
diff --git a/Android.mk b/Android.mk
index 82f4c29..9be2907 100644
--- a/Android.mk
+++ b/Android.mk
@@ -24,9 +24,7 @@
 	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)
+
+/*
+ * 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 */
+/* Until these are reliably available in linux/prctl.h. */
 #ifndef PR_SET_SECCOMP
 # define PR_SET_SECCOMP 22
 #endif
@@ -1444,8 +1459,25 @@
 		 */
 		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)");
 	}