diff options
author | Jorge Lucangeli Obes <jorgelo@chromium.org> | 2012-07-31 16:25:56 -0700 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-08-10 18:07:49 -0700 |
commit | bda833cbcee330eab91561a9b50b6bc24c47f2e9 (patch) | |
tree | 0ee5665a5e09e2a58c376b52fa8eca77aa164280 /syscall_filter.c | |
parent | a6b034dedfb1109adcd88eb1bcea15a29067824c (diff) | |
download | minijail-bda833cbcee330eab91561a9b50b6bc24c47f2e9.tar.gz |
Minijail: add logging for seccomp filter failures.
BUG=chromium-os:33361
TEST=unit tests
TEST=security_Minijail0, security_Minijail_seccomp, platform_CrosDisksArchive
Change-Id: I16cdb8fbcf1cb13f2dee5521f97fb8d0bdbdf93b
Reviewed-on: https://gerrit.chromium.org/gerrit/29053
Reviewed-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
Tested-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
Commit-Ready: Jorge Lucangeli Obes <jorgelo@chromium.org>
Diffstat (limited to 'syscall_filter.c')
-rw-r--r-- | syscall_filter.c | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/syscall_filter.c b/syscall_filter.c index e96ad60..b7dfb77 100644 --- a/syscall_filter.c +++ b/syscall_filter.c @@ -11,7 +11,9 @@ #include "util.h" -#define MAX_LINE_LENGTH 1024 +#define MAX_LINE_LENGTH 1024 +#define MAX_POLICY_LINE_LENGTH 1024 + #define ONE_INSTR 1 #define TWO_INSTRS 2 @@ -85,6 +87,13 @@ void append_ret_kill(struct filter_block *head) append_filter_block(head, filter, ONE_INSTR); } +void append_ret_trap(struct filter_block *head) +{ + struct sock_filter *filter = new_instr_buf(ONE_INSTR); + set_bpf_ret_trap(filter); + append_filter_block(head, filter, ONE_INSTR); +} + void append_ret_errno(struct filter_block *head, int errno_val) { struct sock_filter *filter = new_instr_buf(ONE_INSTR); @@ -92,6 +101,22 @@ void append_ret_errno(struct filter_block *head, int errno_val) append_filter_block(head, filter, ONE_INSTR); } +void append_allow_syscall(struct filter_block *head, int nr) { + struct sock_filter *filter = new_instr_buf(ALLOW_SYSCALL_LEN); + size_t len = bpf_allow_syscall(filter, nr); + if (len != ALLOW_SYSCALL_LEN) + die("error building syscall number comparison"); + + append_filter_block(head, filter, len); +} + +void allow_log_syscalls(struct filter_block *head) +{ + unsigned int i; + for (i = 0; i < log_syscalls_len; i++) + append_allow_syscall(head, lookup_syscall(log_syscalls[i])); +} + unsigned int get_label_id(struct bpf_labels *labels, const char *label_str) { int label_id = bpf_label_id(labels, label_str); @@ -147,11 +172,11 @@ struct filter_block *compile_section(int nr, const char *policy_line, int group_idx = 0; /* Checks for overly long policy lines. */ - if (strlen(policy_line) >= MAX_POLICY_LINE_LEN) + if (strlen(policy_line) >= MAX_POLICY_LINE_LENGTH) return NULL; /* strtok() modifies its first argument, so let's make a copy. */ - char *line = strndup(policy_line, MAX_POLICY_LINE_LEN); + char *line = strndup(policy_line, MAX_POLICY_LINE_LENGTH); if (!line) return NULL; @@ -311,7 +336,8 @@ struct filter_block *compile_section(int nr, const char *policy_line, return head; } -int compile_filter(FILE *policy, struct sock_fprog *prog) +int compile_filter(FILE *policy, struct sock_fprog *prog, + int log_failures) { char line[MAX_LINE_LENGTH]; int line_count = 0; @@ -334,11 +360,15 @@ int compile_filter(FILE *policy, struct sock_fprog *prog) size_t len = bpf_validate_arch(valid_arch); append_filter_block(head, valid_arch, len); - /* Loading syscall number. */ + /* Load syscall number. */ struct sock_filter *load_nr = new_instr_buf(ONE_INSTR); len = bpf_load_syscall_nr(load_nr); append_filter_block(head, load_nr, len); + /* If we're logging failures, allow the necessary syscalls first. */ + if (log_failures) + allow_log_syscalls(head); + /* * Loop through all the lines in the policy file. * Build a jump table for the syscall number. @@ -374,10 +404,7 @@ int compile_filter(FILE *policy, struct sock_fprog *prog) */ if (strcmp(policy, "1") == 0) { /* Add simple ALLOW. */ - struct sock_filter *nr_comp = - new_instr_buf(ALLOW_SYSCALL_LEN); - bpf_allow_syscall(nr_comp, nr); - append_filter_block(head, nr_comp, ALLOW_SYSCALL_LEN); + append_allow_syscall(head, nr); } else { /* * Create and jump to the label that will hold @@ -404,8 +431,14 @@ int compile_filter(FILE *policy, struct sock_fprog *prog) } } - /* If none of the syscalls match, fall back to KILL. */ - append_ret_kill(head); + /* + * If none of the syscalls match, either fall back to KILL, + * or return TRAP. + */ + if (!log_failures) + append_ret_kill(head); + else + append_ret_trap(head); /* Allocate the final buffer, now that we know its size. */ size_t final_filter_len = head->total_len + |