aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuis Hector Chavez <lhchavez@chromium.org>2013-09-22 19:44:06 -0700
committerSamuel Tan <samueltan@google.com>2015-10-05 16:34:28 -0700
commit40b25744de32ad8c5ae1f34189f07c7a438c95c9 (patch)
tree66ee16187e1d12edd2ddf9c7275eefaae58ac5fe
parent3e954eceba13f2e7547ada506a735f084108ea12 (diff)
downloadminijail-40b25744de32ad8c5ae1f34189f07c7a438c95c9.tar.gz
minijail: Add named constants for seccomp filters
This makes it possible to write filters using named constants (like ENOSYS instead of 38). BUG=chromium:516701 TEST=syscall_filter_unittest passes. Change-Id: Ic44cbdfb6f2228f6f658b1cc48adf5a923394306 Reviewed-on: https://chromium-review.googlesource.com/290540 Reviewed-by: Jorge Lucangeli Obes <jorgelo@chromium.org> Trybot-Ready: Luis Hector Chavez <lhchavez@google.com> Tested-by: Luis Hector Chavez <lhchavez@google.com> Commit-Queue: Luis Hector Chavez <lhchavez@google.com>
-rw-r--r--Makefile27
-rwxr-xr-xgen_constants.sh56
-rw-r--r--libconstants.h15
-rw-r--r--syscall_filter.c11
-rw-r--r--syscall_filter_unittest.c2
-rw-r--r--util.c17
-rw-r--r--util.h1
7 files changed, 118 insertions, 11 deletions
diff --git a/Makefile b/Makefile
index 75ea871..64ba1c5 100644
--- a/Makefile
+++ b/Makefile
@@ -23,27 +23,27 @@ all: CC_BINARY(minijail0) CC_LIBRARY(libminijail.so) \
tests: CC_BINARY(libminijail_unittest) CC_BINARY(syscall_filter_unittest)
CC_BINARY(minijail0): LDLIBS += -lcap -ldl
-CC_BINARY(minijail0): libsyscalls.gen.o libminijail.o syscall_filter.o \
- signal.o bpf.o util.o elfparse.o minijail0.o
+CC_BINARY(minijail0): libconstants.gen.o libsyscalls.gen.o libminijail.o \
+ syscall_filter.o signal.o bpf.o util.o elfparse.o minijail0.o
clean: CLEAN(minijail0)
CC_LIBRARY(libminijail.so): LDLIBS += -lcap
CC_LIBRARY(libminijail.so): libminijail.o syscall_filter.o signal.o bpf.o \
- util.o libsyscalls.gen.o
+ util.o libconstants.gen.o libsyscalls.gen.o
clean: CLEAN(libminijail.so)
CC_BINARY(libminijail_unittest): LDLIBS += -lcap
CC_BINARY(libminijail_unittest): libminijail_unittest.o libminijail.o \
- syscall_filter.o signal.o bpf.o util.o libsyscalls.gen.o
+ syscall_filter.o signal.o bpf.o util.o libconstants.gen.o libsyscalls.gen.o
clean: CLEAN(libminijail_unittest)
CC_LIBRARY(libminijailpreload.so): LDLIBS += -lcap -ldl
CC_LIBRARY(libminijailpreload.so): libminijailpreload.o libminijail.o \
- libsyscalls.gen.o syscall_filter.o signal.o bpf.o util.o
+ libconstants.gen.o libsyscalls.gen.o syscall_filter.o signal.o bpf.o util.o
clean: CLEAN(libminijailpreload.so)
CC_BINARY(syscall_filter_unittest): syscall_filter_unittest.o syscall_filter.o \
- bpf.o util.o libsyscalls.gen.o
+ bpf.o util.o libconstants.gen.o libsyscalls.gen.o
clean: CLEAN(syscall_filter_unittest)
libsyscalls.gen.o: CPPFLAGS += -I$(SRC)
@@ -60,3 +60,18 @@ libsyscalls.gen.c: $(SRC)/Makefile $(SRC)/libsyscalls.h
clean: CLEAN(libsyscalls.gen.c)
$(eval $(call add_object_rules,libsyscalls.gen.o,CC,c,CFLAGS))
+
+libconstants.gen.o: CPPFLAGS += -I$(SRC)
+
+libconstants.gen.o.depends: libconstants.gen.c
+
+# Only regenerate libconstants.gen.c if the Makefile or header changes.
+# NOTE! This will not detect if the file is not appropriate for the target.
+# TODO(jorgelo): fix generation when 'CC' env variable is not set.
+libconstants.gen.c: $(SRC)/Makefile $(SRC)/libconstants.h
+ @printf "Generating target-arch specific $@... "
+ $(QUIET)$(SRC)/gen_constants.sh $@
+ @printf "done.\n"
+clean: CLEAN(libconstants.gen.c)
+
+$(eval $(call add_object_rules,libconstants.gen.o,CC,c,CFLAGS))
diff --git a/gen_constants.sh b/gen_constants.sh
new file mode 100755
index 0000000..8dcbca2
--- /dev/null
+++ b/gen_constants.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+# Copyright 2015 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Generates a header file with a named constant table made up of "name", value
+# entries by including several build target header files and emitting the list
+# of defines. Use of the preprocessor is needed to recursively include all
+# relevant headers.
+
+set -e
+
+if [ $# -ne 1 ] && [ $# -ne 3]; then
+ echo "Usage: $(basename "$0") OUTFILE"
+ echo "Usage: $(basename "$0") CC CFLAGS OUTFILE"
+ exit 1
+fi
+
+if [ $# -eq 3 ]; then
+ CC="$1"
+ shift
+ CFLAGS="$1"
+ shift
+fi
+OUTFILE="$1"
+
+INCLUDES='
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/prctl.h>
+#include <linux/sched.h>
+#include <stddef.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/types.h>'
+
+# Passes the previous list of #includes to the C preprocessor and prints out
+# all #defines whose name is all-caps. Excludes a few symbols that are known
+# macro functions that don't evaluate to a constant.
+cat <<-EOF > "${OUTFILE}"
+/* GENERATED BY MAKEFILE */
+$INCLUDES
+
+#include "libconstants.h"
+const struct constant_entry constant_table[] = {
+$(echo "$INCLUDES" | \
+ ${CC} ${CFLAGS} -dD - -E | \
+ grep '^#define [A-Z][A-Z0-9_]* ' | \
+ grep -v '\(SIGRTMAX\|SIGRTMIN\|SIG_\|NULL\)' | \
+ sort | \
+ uniq | \
+ sed -e 's/#define \([A-Z0-9_]\+\).*$/#ifdef \1\n { "\1", \1 },\n#endif \/\/ \1/')
+ { NULL, 0 },
+};
+EOF
diff --git a/libconstants.h b/libconstants.h
new file mode 100644
index 0000000..865f9d3
--- /dev/null
+++ b/libconstants.h
@@ -0,0 +1,15 @@
+/* Copyright 2015 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef MINIJAIL_LIBCONSTANTS_H_
+#define MINIJAIL_LIBCONSTANTS_H_
+
+struct constant_entry {
+ const char *name;
+ unsigned long value;
+};
+
+extern const struct constant_entry constant_table[];
+
+#endif /* MINIJAIL_LIBCONSTANTS_H_ */
diff --git a/syscall_filter.c b/syscall_filter.c
index 9ea5dca..3335a07 100644
--- a/syscall_filter.c
+++ b/syscall_filter.c
@@ -182,7 +182,11 @@ int compile_atom(struct filter_block *head, char *atom,
if (argidx_ptr == argidx_str + 3)
return -1;
- long int c = strtol(constant_str, NULL, 0);
+ char *constant_str_ptr;
+ long int c = parse_constant(constant_str, &constant_str_ptr);
+ if (constant_str_ptr == constant_str)
+ return -1;
+
/*
* Looks up the label for the end of the AND statement
* this atom belongs to.
@@ -220,10 +224,9 @@ int compile_errno(struct filter_block *head, char *ret_errno)
if (errno_val_str) {
char *errno_val_ptr;
- int errno_val = strtol(
- errno_val_str, &errno_val_ptr, 0);
+ int errno_val = parse_constant(errno_val_str, &errno_val_ptr);
/* Checks to see if we parsed an actual errno. */
- if (errno_val_ptr == errno_val_str)
+ if (errno_val_ptr == errno_val_str || errno_val == -1)
return -1;
append_ret_errno(head, errno_val);
diff --git a/syscall_filter_unittest.c b/syscall_filter_unittest.c
index fb903c5..df014c3 100644
--- a/syscall_filter_unittest.c
+++ b/syscall_filter_unittest.c
@@ -290,7 +290,7 @@ TEST_F(arg_filter, arg0_equals) {
}
TEST_F(arg_filter, arg0_mask) {
- const char *fragment = "arg1 & 02"; /* O_RDWR */
+ const char *fragment = "arg1 & O_RDWR";
int nr = 1;
unsigned int id = 0;
struct filter_block *block =
diff --git a/util.c b/util.c
index 550ed78..6b16a23 100644
--- a/util.c
+++ b/util.c
@@ -4,10 +4,12 @@
*/
#include <ctype.h>
+#include <stdio.h>
#include <string.h>
#include "util.h"
+#include "libconstants.h"
#include "libsyscalls.h"
/*
@@ -56,6 +58,21 @@ const char *lookup_syscall_name(int nr)
return NULL;
}
+long int parse_constant(char *constant_str, char **endptr)
+{
+ const struct constant_entry *entry = constant_table;
+ for (; entry->name; ++entry) {
+ if (!strcmp(entry->name, constant_str)) {
+ if (endptr)
+ *endptr = constant_str + strlen(constant_str);
+
+ return entry->value;
+ }
+ }
+
+ return strtol(constant_str, endptr, 0);
+}
+
char *strip(char *s)
{
char *end;
diff --git a/util.h b/util.h
index d07e5b1..a88cbc8 100644
--- a/util.h
+++ b/util.h
@@ -31,6 +31,7 @@ extern const size_t log_syscalls_len;
int lookup_syscall(const char *name);
const char *lookup_syscall_name(int nr);
+long int parse_constant(char *constant_str, char **endptr);
char *strip(char *s);
char *tokenize(char **stringp, const char *delim);