summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2012-11-15 22:12:00 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-11-19 15:14:17 +0100
commit9b790d71d58be65f9508ab60920eb978af828412 (patch)
tree42114518c27f840aca3ef395636ca1f2fcf09a0e /arch/arm/kernel
parentARM: 7577/1: arch/add syscall_get_arch (diff)
downloadlinux-9b790d71d58be65f9508ab60920eb978af828412.tar.xz
linux-9b790d71d58be65f9508ab60920eb978af828412.zip
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: Kees Cook <keescook@chromium.org> Acked-by: Will Drewry <wad@chromium.org> Reviewed-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/entry-common.S10
-rw-r--r--arch/arm/kernel/ptrace.c29
2 files changed, 20 insertions, 19 deletions
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 417bac1846bd..b621871dd277 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -417,16 +417,6 @@ local_restart:
ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing
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?
bne __sys_trace
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 739db3a1b2d2..518536d93fba 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -916,16 +916,11 @@ enum ptrace_syscall_dir {
PTRACE_SYSCALL_EXIT,
};
-static int ptrace_syscall_trace(struct pt_regs *regs, int scno,
- enum ptrace_syscall_dir dir)
+static int tracehook_report_syscall(struct pt_regs *regs,
+ enum ptrace_syscall_dir dir)
{
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 = 0 -> entry, =1 -> exit
@@ -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)
{
- 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))
trace_sys_enter(regs, scno);
+
audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1,
regs->ARM_r2, regs->ARM_r3);
+
return 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))
trace_sys_exit(regs, scno);
+
audit_syscall_exit(regs);
+
return scno;
}