summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorBogdan Purcareata <bogdan.purcareata@freescale.com>2015-03-18 14:03:51 (GMT)
committerHonghua Yin <Hong-Hua.Yin@freescale.com>2015-03-30 05:12:52 (GMT)
commit3d4d72b9459396876e1debbb59abcd585283f433 (patch)
treeb8cc399024cb019e55b8e4a9e17dee2947d90139 /arch
parentbe8d5995081dcfb5487b040d2804cb721efbc219 (diff)
downloadlinux-fsl-qoriq-3d4d72b9459396876e1debbb59abcd585283f433.tar.xz
powerpc: Don't force ENOSYS as error on syscall fail
In certain scenarios - e.g. seccomp filtering with ERRNO as default action - the system call fails for other reasons than the syscall not being available. The seccomp filter can be configured to store a user-defined error code on return from a blacklisted syscall. Don't always set ENOSYS on do_syscall_trace_enter failure. Delegate setting ENOSYS in case of failure, where appropriate, to do_syscall_trace_enter. v4: - update syscall_exit to be local label on 64bit, after rebasing on top of 3.19 v3: - keep setting ENOSYS in the syscall entry assembly for scenarios without syscall tracing v2: - move setting ENOSYS as errno from the syscall entry assembly to do_syscall_trace_enter, only in the specific case Upstream-Status: Pending [https://lkml.org/lkml/2015/2/18/50] Signed-off-by: Bogdan Purcareata <bogdan.purcareata@freescale.com> Change-Id: I938a8754407a60c79fe9485cc76a6ec891e08e82 Reviewed-on: http://git.am.freescale.net:8181/33030 Reviewed-by: Scott Wood <scottwood@freescale.com> Tested-by: Honghua Yin <Hong-Hua.Yin@freescale.com> Reviewed-by: Honghua Yin <Hong-Hua.Yin@freescale.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/entry_32.S7
-rw-r--r--arch/powerpc/kernel/entry_64.S5
-rw-r--r--arch/powerpc/kernel/ptrace.c4
3 files changed, 12 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 59848e5..23e51af 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -339,12 +339,12 @@ _GLOBAL(DoSyscall)
lwz r11,TI_FLAGS(r10)
andi. r11,r11,_TIF_SYSCALL_T_OR_A
bne- syscall_dotrace
-syscall_dotrace_cont:
cmplwi 0,r0,NR_syscalls
lis r10,sys_call_table@h
ori r10,r10,sys_call_table@l
slwi r0,r0,2
bge- 66f
+syscall_dotrace_cont:
lwzx r10,r10,r0 /* Fetch system call handler [ptr] */
mtlr r10
addi r9,r1,STACK_FRAME_OVERHEAD
@@ -466,6 +466,11 @@ syscall_dotrace:
lwz r7,GPR7(r1)
lwz r8,GPR8(r1)
REST_NVGPRS(r1)
+ cmplwi 0,r0,NR_syscalls
+ lis r10,sys_call_table@h
+ ori r10,r10,sys_call_table@l
+ slwi r0,r0,2
+ bge- ret_from_syscall
b syscall_dotrace_cont
syscall_exit_work:
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 24f0cf3..2e2de31 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -153,7 +153,6 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
ld r10,TI_FLAGS(r11)
andi. r11,r10,_TIF_SYSCALL_T_OR_A
bne syscall_dotrace
-.Lsyscall_dotrace_cont:
cmpldi 0,r0,NR_syscalls
bge- syscall_enosys
@@ -266,7 +265,9 @@ syscall_dotrace:
addi r9,r1,STACK_FRAME_OVERHEAD
CURRENT_THREAD_INFO(r10, r1)
ld r10,TI_FLAGS(r10)
- b .Lsyscall_dotrace_cont
+ cmpldi 0,r0,NR_syscalls
+ bge- .Lsyscall_exit
+ b system_call
syscall_enosys:
li r3,-ENOSYS
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 100e01c..ed1f0fb 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1775,13 +1775,15 @@ long do_syscall_trace_enter(struct pt_regs *regs)
secure_computing_strict(regs->gpr[0]);
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
- tracehook_report_syscall_entry(regs))
+ tracehook_report_syscall_entry(regs)) {
/*
* Tracing decided this syscall should not happen.
* We'll return a bogus call number to get an ENOSYS
* error, but leave the original number in regs->gpr[0].
*/
ret = -1L;
+ syscall_set_return_value(current, regs, ENOSYS, 0);
+ }
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
trace_sys_enter(regs, regs->gpr[0]);