diff options
author | Richard Weinberger <richard@nod.at> | 2015-05-31 22:59:03 +0200 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2015-05-31 22:59:03 +0200 |
commit | 5334cdae407a5778a297a98a75ca61140e37ebfa (patch) | |
tree | 8b1c4aaad459fa26fb13b5ef4244d986c831048d | |
parent | 30b11ee9ae23d78de66b9ae315880af17a64ba83 (diff) | |
download | linux-5334cdae407a5778a297a98a75ca61140e37ebfa.tar.bz2 |
um: Handle tracehook_report_syscall_entry() result
tracehook_report_syscall_entry() is allowed to fail,
in case of failure we have to abort the current syscall.
Signed-off-by: Richard Weinberger <richard@nod.at>
-rw-r--r-- | arch/um/include/asm/ptrace-generic.h | 2 | ||||
-rw-r--r-- | arch/um/kernel/ptrace.c | 6 | ||||
-rw-r--r-- | arch/um/kernel/skas/syscall.c | 6 |
3 files changed, 9 insertions, 5 deletions
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index cb9b3c47ca8e..283480a7ad23 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h @@ -37,7 +37,7 @@ extern int putreg(struct task_struct *child, int regno, unsigned long value); extern int arch_copy_tls(struct task_struct *new); extern void clear_flushed_tls(struct task_struct *task); -extern void syscall_trace_enter(struct pt_regs *regs); +extern int syscall_trace_enter(struct pt_regs *regs); extern void syscall_trace_leave(struct pt_regs *regs); #endif diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 174ee5017264..cac2ea058b7a 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c @@ -131,7 +131,7 @@ static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs, * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check */ -void syscall_trace_enter(struct pt_regs *regs) +int syscall_trace_enter(struct pt_regs *regs) { audit_syscall_entry(UPT_SYSCALL_NR(®s->regs), UPT_SYSCALL_ARG1(®s->regs), @@ -140,9 +140,9 @@ void syscall_trace_enter(struct pt_regs *regs) UPT_SYSCALL_ARG4(®s->regs)); if (!test_thread_flag(TIF_SYSCALL_TRACE)) - return; + return 0; - tracehook_report_syscall_entry(regs); + return tracehook_report_syscall_entry(regs); } void syscall_trace_leave(struct pt_regs *regs) diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index c0681e097432..d9ec0068b623 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c @@ -18,7 +18,10 @@ void handle_syscall(struct uml_pt_regs *r) long result; int syscall; - syscall_trace_enter(regs); + if (syscall_trace_enter(regs)) { + result = -ENOSYS; + goto out; + } /* * This should go in the declaration of syscall, but when I do that, @@ -34,6 +37,7 @@ void handle_syscall(struct uml_pt_regs *r) result = -ENOSYS; else result = EXECUTE_SYSCALL(syscall, regs); +out: PT_REGS_SET_SYSCALL_RETURN(regs, result); syscall_trace_leave(regs); |