diff options
Diffstat (limited to 'features/seccomp/seccomp-Add-SECCOMP_RET_TRAP.patch')
-rw-r--r-- | features/seccomp/seccomp-Add-SECCOMP_RET_TRAP.patch | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/features/seccomp/seccomp-Add-SECCOMP_RET_TRAP.patch b/features/seccomp/seccomp-Add-SECCOMP_RET_TRAP.patch new file mode 100644 index 00000000..31466638 --- /dev/null +++ b/features/seccomp/seccomp-Add-SECCOMP_RET_TRAP.patch @@ -0,0 +1,138 @@ +From 365829a1caa9148a289fe895280a1d2ed0e56e37 Mon Sep 17 00:00:00 2001 +From: Will Drewry <wad@chromium.org> +Date: Thu, 12 Apr 2012 16:48:01 -0500 +Subject: [PATCH] seccomp: Add SECCOMP_RET_TRAP + +commit bb6ea4301a1109afdacaee576fedbfcd7152fc86 upstream. + +Adds a new return value to seccomp filters that triggers a SIGSYS to be +delivered with the new SYS_SECCOMP si_code. + +This allows in-process system call emulation, including just specifying +an errno or cleanly dumping core, rather than just dying. + +Suggested-by: Markus Gutschke <markus@chromium.org> +Suggested-by: Julien Tinnes <jln@chromium.org> +Signed-off-by: Will Drewry <wad@chromium.org> +Acked-by: Eric Paris <eparis@redhat.com> + +v18: - acked-by, rebase + - don't mention secure_computing_int() anymore +v15: - use audit_seccomp/skip + - pad out error spacing; clean up switch (indan@nul.nu) +v14: - n/a +v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc +v12: - rebase on to linux-next +v11: - clarify the comment (indan@nul.nu) + - s/sigtrap/sigsys +v10: - use SIGSYS, syscall_get_arch, updates arch/Kconfig + note suggested-by (though original suggestion had other behaviors) +v9: - changes to SIGILL +v8: - clean up based on changes to dependent patches +v7: - introduction +Signed-off-by: James Morris <james.l.morris@oracle.com> +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +--- + arch/Kconfig | 14 +++++++++----- + include/asm-generic/siginfo.h | 2 +- + include/linux/seccomp.h | 1 + + kernel/seccomp.c | 26 ++++++++++++++++++++++++++ + 4 files changed, 37 insertions(+), 6 deletions(-) + +diff --git a/arch/Kconfig b/arch/Kconfig +index beaab68..66aef13 100644 +--- a/arch/Kconfig ++++ b/arch/Kconfig +@@ -219,11 +219,15 @@ config ARCH_WANT_OLD_COMPAT_IPC + config HAVE_ARCH_SECCOMP_FILTER + bool + help +- This symbol should be selected by an architecure if it provides +- asm/syscall.h, specifically syscall_get_arguments(), +- syscall_get_arch(), and syscall_set_return_value(). Additionally, +- its system call entry path must respect a return value of -1 from +- __secure_computing() and/or secure_computing(). ++ This symbol should be selected by an architecure if it provides: ++ asm/syscall.h: ++ - syscall_get_arch() ++ - syscall_get_arguments() ++ - syscall_rollback() ++ - syscall_set_return_value() ++ SIGSYS siginfo_t support must be implemented. ++ __secure_computing()/secure_computing()'s return value must be ++ checked, with -1 resulting in the syscall being skipped. + + config SECCOMP_FILTER + def_bool y +diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h +index d2c7f29..8ed6777 100644 +--- a/include/asm-generic/siginfo.h ++++ b/include/asm-generic/siginfo.h +@@ -101,7 +101,7 @@ typedef struct siginfo { + + /* SIGSYS */ + struct { +- void __user *_call_addr; /* calling insn */ ++ void __user *_call_addr; /* calling user insn */ + int _syscall; /* triggering system call number */ + unsigned int _arch; /* AUDIT_ARCH_* of syscall */ + } _sigsys; +diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h +index b4ce2c8..317ccb7 100644 +--- a/include/linux/seccomp.h ++++ b/include/linux/seccomp.h +@@ -19,6 +19,7 @@ + * selects the least permissive choice. + */ + #define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */ ++#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ + #define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ + #define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ + +diff --git a/kernel/seccomp.c b/kernel/seccomp.c +index 5f78fb6..9c38306 100644 +--- a/kernel/seccomp.c ++++ b/kernel/seccomp.c +@@ -332,6 +332,26 @@ void put_seccomp_filter(struct task_struct *tsk) + kfree(freeme); + } + } ++ ++/** ++ * seccomp_send_sigsys - signals the task to allow in-process syscall emulation ++ * @syscall: syscall number to send to userland ++ * @reason: filter-supplied reason code to send to userland (via si_errno) ++ * ++ * Forces a SIGSYS with a code of SYS_SECCOMP and related sigsys info. ++ */ ++static void seccomp_send_sigsys(int syscall, int reason) ++{ ++ struct siginfo info; ++ memset(&info, 0, sizeof(info)); ++ info.si_signo = SIGSYS; ++ info.si_code = SYS_SECCOMP; ++ info.si_call_addr = (void __user *)KSTK_EIP(current); ++ info.si_errno = reason; ++ info.si_arch = syscall_get_arch(current, task_pt_regs(current)); ++ info.si_syscall = syscall; ++ force_sig_info(SIGSYS, &info, current); ++} + #endif /* CONFIG_SECCOMP_FILTER */ + + /* +@@ -382,6 +402,12 @@ int __secure_computing(int this_syscall) + syscall_set_return_value(current, task_pt_regs(current), + -data, 0); + goto skip; ++ case SECCOMP_RET_TRAP: ++ /* Show the handler the original registers. */ ++ syscall_rollback(current, task_pt_regs(current)); ++ /* Let the filter pass back 16 bits of data. */ ++ seccomp_send_sigsys(this_syscall, data); ++ goto skip; + case SECCOMP_RET_ALLOW: + return 0; + case SECCOMP_RET_KILL: +-- +1.7.9.1 + |