softfail on older kernels that lack seccomp support
Attempt to set up a seccomp filter. If seccomp not supported
on an Android device and kernel version < 3.8 fail softly
i.e. allow process to run without seccomp protections.
Bug: 26435980
Change-Id: Ied6ac053908b6b0b81ba822621b1969bdedce4af
diff --git a/libminijail.c b/libminijail.c
index c7b5738..da2ea54 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -31,6 +31,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/user.h>
+#include <sys/utsname.h>
#include <sys/wait.h>
#include <unistd.h>
@@ -172,6 +173,34 @@
/* Note, |pids| will already have been used before this call. */
}
+/* Return true if kernel version is less than 3.8. */
+static int seccomp_kernel_support_not_required()
+{
+ int major, minor;
+ struct utsname uts;
+ return (uname(&uts) != -1 &&
+ sscanf(uts.release, "%d.%d", &major, &minor) == 2 &&
+ ((major < 3) || ((major == 3) && (minor < 8))));
+}
+
+/*
+ * Allow softfail on Android devices with kernel version < 3.8.
+ */
+static int can_softfail()
+{
+#if SECCOMP_SOFTFAIL
+ if (is_android()) {
+ if (seccomp_kernel_support_not_required())
+ return 1;
+ else
+ return 0;
+ } else {
+ return 1;
+ }
+#endif
+ return 0;
+}
+
/* Minijail API. */
struct minijail API *minijail_new(void)
@@ -563,10 +592,14 @@
void API minijail_parse_seccomp_filters(struct minijail *j, const char *path)
{
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL)) {
- if ((errno == ENOSYS) && SECCOMP_SOFTFAIL) {
+ if ((errno == EINVAL) && can_softfail()) {
warn("not loading seccomp filter,"
" seccomp not supported");
- return;
+ j->flags.seccomp_filter = 0;
+ j->flags.log_seccomp_filter = 0;
+ j->filter_len = 0;
+ j->filter_prog = NULL;
+ j->flags.no_new_privs = 0;
}
}
FILE *file = fopen(path, "r");
@@ -1188,7 +1221,7 @@
if (j->flags.seccomp_filter) {
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER,
j->filter_prog)) {
- if ((errno == ENOSYS) && SECCOMP_SOFTFAIL) {
+ if ((errno == EINVAL) && can_softfail()) {
warn("seccomp not supported");
return;
}
@@ -1311,7 +1344,7 @@
* privilege-dropping syscalls :)
*/
if (j->flags.seccomp && prctl(PR_SET_SECCOMP, 1)) {
- if ((errno == ENOSYS) && SECCOMP_SOFTFAIL) {
+ if ((errno == EINVAL) && can_softfail()) {
warn("seccomp not supported");
return;
}