diff options
author | Luis Hector Chavez <lhchavez@chromium.org> | 2013-09-22 19:44:06 -0700 |
---|---|---|
committer | Samuel Tan <samueltan@google.com> | 2015-10-05 16:34:28 -0700 |
commit | 40b25744de32ad8c5ae1f34189f07c7a438c95c9 (patch) | |
tree | 66ee16187e1d12edd2ddf9c7275eefaae58ac5fe | |
parent | 3e954eceba13f2e7547ada506a735f084108ea12 (diff) | |
download | minijail-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-- | Makefile | 27 | ||||
-rwxr-xr-x | gen_constants.sh | 56 | ||||
-rw-r--r-- | libconstants.h | 15 | ||||
-rw-r--r-- | syscall_filter.c | 11 | ||||
-rw-r--r-- | syscall_filter_unittest.c | 2 | ||||
-rw-r--r-- | util.c | 17 | ||||
-rw-r--r-- | util.h | 1 |
7 files changed, 118 insertions, 11 deletions
@@ -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 = @@ -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; @@ -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); |