Commit 9b790d71 authored by Kees Cook's avatar Kees Cook Committed by Russell King

ARM: 7578/1: arch/move secure_computing into trace

There is very little difference in the TIF_SECCOMP and TIF_SYSCALL_WORK
path in entry-common.S, so merge TIF_SECCOMP into TIF_SYSCALL_WORK and
move seccomp into the syscall_trace_enter() handler.

Expanded some of the tracehook logic into the callers to make this code
more readable. Since tracehook needs to do register changing, this portion
is best left in its own function instead of copy/pasting into the callers.

Additionally, the return value for secure_computing() is now checked
and a -1 value will result in the system call being skipped.
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Acked-by: default avatarWill Drewry <wad@chromium.org>
Reviewed-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 1f59d13b
...@@ -151,10 +151,10 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, ...@@ -151,10 +151,10 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define TIF_SYSCALL_TRACE 8 #define TIF_SYSCALL_TRACE 8
#define TIF_SYSCALL_AUDIT 9 #define TIF_SYSCALL_AUDIT 9
#define TIF_SYSCALL_TRACEPOINT 10 #define TIF_SYSCALL_TRACEPOINT 10
#define TIF_SECCOMP 11 /* seccomp syscall filtering active */
#define TIF_USING_IWMMXT 17 #define TIF_USING_IWMMXT 17
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 20 #define TIF_RESTORE_SIGMASK 20
#define TIF_SECCOMP 21
#define TIF_SWITCH_MM 22 /* deferred switch_mm */ #define TIF_SWITCH_MM 22 /* deferred switch_mm */
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
...@@ -163,11 +163,12 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, ...@@ -163,11 +163,12 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
/* Checks for any syscall work in entry-common.S */ /* Checks for any syscall work in entry-common.S */
#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT) #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
_TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP)
/* /*
* Change these and you break ASM code in entry-common.S * Change these and you break ASM code in entry-common.S
......
...@@ -417,16 +417,6 @@ local_restart: ...@@ -417,16 +417,6 @@ local_restart:
ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing
stmdb sp!, {r4, r5} @ push fifth and sixth args stmdb sp!, {r4, r5} @ push fifth and sixth args
#ifdef CONFIG_SECCOMP
tst r10, #_TIF_SECCOMP
beq 1f
mov r0, scno
bl __secure_computing
add r0, sp, #S_R0 + S_OFF @ pointer to regs
ldmia r0, {r0 - r3} @ have to reload r0 - r3
1:
#endif
tst r10, #_TIF_SYSCALL_WORK @ are we tracing syscalls? tst r10, #_TIF_SYSCALL_WORK @ are we tracing syscalls?
bne __sys_trace bne __sys_trace
......
...@@ -916,16 +916,11 @@ enum ptrace_syscall_dir { ...@@ -916,16 +916,11 @@ enum ptrace_syscall_dir {
PTRACE_SYSCALL_EXIT, PTRACE_SYSCALL_EXIT,
}; };
static int ptrace_syscall_trace(struct pt_regs *regs, int scno, static int tracehook_report_syscall(struct pt_regs *regs,
enum ptrace_syscall_dir dir) enum ptrace_syscall_dir dir)
{ {
unsigned long ip; unsigned long ip;
current_thread_info()->syscall = scno;
if (!test_thread_flag(TIF_SYSCALL_TRACE))
return scno;
/* /*
* IP is used to denote syscall entry/exit: * IP is used to denote syscall entry/exit:
* IP = 0 -> entry, =1 -> exit * IP = 0 -> entry, =1 -> exit
...@@ -944,19 +939,35 @@ static int ptrace_syscall_trace(struct pt_regs *regs, int scno, ...@@ -944,19 +939,35 @@ static int ptrace_syscall_trace(struct pt_regs *regs, int scno,
asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno) asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
{ {
scno = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER); current_thread_info()->syscall = scno;
/* Do the secure computing check first; failures should be fast. */
if (secure_computing(scno) == -1)
return -1;
if (test_thread_flag(TIF_SYSCALL_TRACE))
scno = tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_enter(regs, scno); trace_sys_enter(regs, scno);
audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1,
regs->ARM_r2, regs->ARM_r3); regs->ARM_r2, regs->ARM_r3);
return scno; return scno;
} }
asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno) asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno)
{ {
scno = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT); current_thread_info()->syscall = scno;
if (test_thread_flag(TIF_SYSCALL_TRACE))
scno = tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_exit(regs, scno); trace_sys_exit(regs, scno);
audit_syscall_exit(regs); audit_syscall_exit(regs);
return scno; return scno;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment