17 #include <linux/audit.h>
19 #include <linux/sched.h>
20 #include <linux/seccomp.h>
24 #ifdef CONFIG_SECCOMP_FILTER
25 #include <asm/syscall.h>
26 #include <linux/filter.h>
27 #include <linux/ptrace.h>
29 #include <linux/slab.h>
62 #define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
83 #define BPF_DATA(_name) offsetof(struct seccomp_data, _name)
92 u32 seccomp_bpf_load(
int off)
95 if (off == BPF_DATA(
nr))
97 if (off == BPF_DATA(
arch))
99 if (off >= BPF_DATA(
args[0]) && off < BPF_DATA(
args[6])) {
101 int arg = (off - BPF_DATA(
args[0])) /
sizeof(
u64);
102 int index = !!(off %
sizeof(
u64));
104 return get_u32(value, index);
129 for (pc = 0; pc < flen; pc++) {
213 for (f =
current->seccomp.filter; f; f = f->prev) {
227 static long seccomp_attach_filter(
struct sock_fprog *fprog)
231 unsigned long total_insns = fprog->
len;
237 for (filter =
current->seccomp.filter; filter; filter = filter->prev)
238 total_insns += filter->len + 4;
239 if (total_insns > MAX_INSNS_PER_PATH)
259 filter->len = fprog->
len;
272 ret = seccomp_check_filter(filter->insns, filter->len);
280 filter->prev =
current->seccomp.filter;
294 long seccomp_attach_user_filter(
char __user *user_filter)
301 struct compat_sock_fprog fprog32;
304 fprog.
len = fprog32.len;
305 fprog.
filter = compat_ptr(fprog32.filter);
310 ret = seccomp_attach_filter(&fprog);
344 static void seccomp_send_sigsys(
int syscall,
int reason)
353 info.si_syscall = syscall;
363 static int mode1_syscalls[] = {
369 static int mode1_syscalls_32[] = {
384 syscall = mode1_syscalls;
387 syscall = mode1_syscalls_32;
390 if (*syscall == this_syscall)
392 }
while (*++syscall);
396 #ifdef CONFIG_SECCOMP_FILTER
399 ret = seccomp_run_filters(this_syscall);
412 seccomp_send_sigsys(this_syscall, data);
426 if (fatal_signal_pending(
current))
446 audit_seccomp(this_syscall, exit_sig, ret);
448 #ifdef CONFIG_SECCOMP_FILTER
450 audit_seccomp(this_syscall, exit_sig, ret);
479 current->seccomp.mode != seccomp_mode)
482 switch (seccomp_mode) {
489 #ifdef CONFIG_SECCOMP_FILTER
491 ret = seccomp_attach_user_filter(filter);
500 current->seccomp.mode = seccomp_mode;