diff options
author | Helge Deller <deller@gmx.de> | 2016-03-30 08:14:31 -0400 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2016-03-31 06:28:38 -0400 |
commit | 910cd32e552ea09caa89cdbe328e468979b030dd (patch) | |
tree | 02cc8c1d9d0202d76f988ae242ccbc328a8e43cd /arch | |
parent | 4f4acc9472e54ce702f1d85fc9e6d57767dec91f (diff) |
parisc: Fix and enable seccomp filter support
The seccomp filter support requires careful handling of task registers. This
includes reloading of the return value (%r28) and proper syscall exit if
secure_computing() returned -1.
Additionally we need to sign-extend the syscall number from signed 32bit to
signed 64bit in do_syscall_trace_enter() since the ptrace interface only allows
storing 32bit values in compat mode.
Signed-off-by: Helge Deller <deller@gmx.de>
Cc: stable@vger.kernel.org # v4.5
Diffstat (limited to 'arch')
-rw-r--r-- | arch/parisc/Kconfig | 1 | ||||
-rw-r--r-- | arch/parisc/include/asm/syscall.h | 13 | ||||
-rw-r--r-- | arch/parisc/kernel/ptrace.c | 9 | ||||
-rw-r--r-- | arch/parisc/kernel/syscall.S | 2 |
4 files changed, 23 insertions, 2 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 14f655cf542e..86ed37671ef5 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig | |||
@@ -29,6 +29,7 @@ config PARISC | |||
29 | select TTY # Needed for pdc_cons.c | 29 | select TTY # Needed for pdc_cons.c |
30 | select HAVE_DEBUG_STACKOVERFLOW | 30 | select HAVE_DEBUG_STACKOVERFLOW |
31 | select HAVE_ARCH_AUDITSYSCALL | 31 | select HAVE_ARCH_AUDITSYSCALL |
32 | select HAVE_ARCH_SECCOMP_FILTER | ||
32 | select ARCH_NO_COHERENT_DMA_MMAP | 33 | select ARCH_NO_COHERENT_DMA_MMAP |
33 | 34 | ||
34 | help | 35 | help |
diff --git a/arch/parisc/include/asm/syscall.h b/arch/parisc/include/asm/syscall.h index a5eba95d87fe..637ce8d6f375 100644 --- a/arch/parisc/include/asm/syscall.h +++ b/arch/parisc/include/asm/syscall.h | |||
@@ -39,6 +39,19 @@ static inline void syscall_get_arguments(struct task_struct *tsk, | |||
39 | } | 39 | } |
40 | } | 40 | } |
41 | 41 | ||
42 | static inline void syscall_set_return_value(struct task_struct *task, | ||
43 | struct pt_regs *regs, | ||
44 | int error, long val) | ||
45 | { | ||
46 | regs->gr[28] = error ? error : val; | ||
47 | } | ||
48 | |||
49 | static inline void syscall_rollback(struct task_struct *task, | ||
50 | struct pt_regs *regs) | ||
51 | { | ||
52 | /* do nothing */ | ||
53 | } | ||
54 | |||
42 | static inline int syscall_get_arch(void) | 55 | static inline int syscall_get_arch(void) |
43 | { | 56 | { |
44 | int arch = AUDIT_ARCH_PARISC; | 57 | int arch = AUDIT_ARCH_PARISC; |
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index ce0b2b4075c7..8fb81a391599 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c | |||
@@ -270,7 +270,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, | |||
270 | long do_syscall_trace_enter(struct pt_regs *regs) | 270 | long do_syscall_trace_enter(struct pt_regs *regs) |
271 | { | 271 | { |
272 | /* Do the secure computing check first. */ | 272 | /* Do the secure computing check first. */ |
273 | secure_computing_strict(regs->gr[20]); | 273 | if (secure_computing() == -1) |
274 | return -1; | ||
274 | 275 | ||
275 | if (test_thread_flag(TIF_SYSCALL_TRACE) && | 276 | if (test_thread_flag(TIF_SYSCALL_TRACE) && |
276 | tracehook_report_syscall_entry(regs)) { | 277 | tracehook_report_syscall_entry(regs)) { |
@@ -296,7 +297,11 @@ long do_syscall_trace_enter(struct pt_regs *regs) | |||
296 | regs->gr[23] & 0xffffffff); | 297 | regs->gr[23] & 0xffffffff); |
297 | 298 | ||
298 | out: | 299 | out: |
299 | return regs->gr[20]; | 300 | /* |
301 | * Sign extend the syscall number to 64bit since it may have been | ||
302 | * modified by a compat ptrace call | ||
303 | */ | ||
304 | return (int) ((u32) regs->gr[20]); | ||
300 | } | 305 | } |
301 | 306 | ||
302 | void do_syscall_trace_exit(struct pt_regs *regs) | 307 | void do_syscall_trace_exit(struct pt_regs *regs) |
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index fbafa0d0e2bf..c976ebfe2269 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S | |||
@@ -329,6 +329,7 @@ tracesys_next: | |||
329 | 329 | ||
330 | ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ | 330 | ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ |
331 | LDREG TI_TASK(%r1), %r1 | 331 | LDREG TI_TASK(%r1), %r1 |
332 | LDREG TASK_PT_GR28(%r1), %r28 /* Restore return value */ | ||
332 | LDREG TASK_PT_GR26(%r1), %r26 /* Restore the users args */ | 333 | LDREG TASK_PT_GR26(%r1), %r26 /* Restore the users args */ |
333 | LDREG TASK_PT_GR25(%r1), %r25 | 334 | LDREG TASK_PT_GR25(%r1), %r25 |
334 | LDREG TASK_PT_GR24(%r1), %r24 | 335 | LDREG TASK_PT_GR24(%r1), %r24 |
@@ -342,6 +343,7 @@ tracesys_next: | |||
342 | stw %r21, -56(%r30) /* 6th argument */ | 343 | stw %r21, -56(%r30) /* 6th argument */ |
343 | #endif | 344 | #endif |
344 | 345 | ||
346 | cmpib,COND(=),n -1,%r20,tracesys_exit /* seccomp may have returned -1 */ | ||
345 | comiclr,>>= __NR_Linux_syscalls, %r20, %r0 | 347 | comiclr,>>= __NR_Linux_syscalls, %r20, %r0 |
346 | b,n .Ltracesys_nosys | 348 | b,n .Ltracesys_nosys |
347 | 349 | ||