diff options
-rw-r--r-- | arch/parisc/Kconfig | 1 | ||||
-rw-r--r-- | arch/parisc/include/asm/compat.h | 7 | ||||
-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/signal32.c | 5 | ||||
-rw-r--r-- | arch/parisc/kernel/syscall.S | 2 |
6 files changed, 35 insertions, 2 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 989fa14..bd3c873 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -30,6 +30,7 @@ config PARISC select TTY # Needed for pdc_cons.c select HAVE_DEBUG_STACKOVERFLOW select HAVE_ARCH_AUDITSYSCALL + select HAVE_ARCH_SECCOMP_FILTER select ARCH_NO_COHERENT_DMA_MMAP help diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h index 0448a2c..3387307 100644 --- a/arch/parisc/include/asm/compat.h +++ b/arch/parisc/include/asm/compat.h @@ -183,6 +183,13 @@ typedef struct compat_siginfo { int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ int _fd; } _sigpoll; + + /* SIGSYS */ + struct { + compat_uptr_t _call_addr; /* calling user insn */ + int _syscall; /* triggering system call number */ + compat_uint_t _arch; /* AUDIT_ARCH_* of syscall */ + } _sigsys; } _sifields; } compat_siginfo_t; diff --git a/arch/parisc/include/asm/syscall.h b/arch/parisc/include/asm/syscall.h index a5eba95..637ce8d 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, } } +static inline void syscall_set_return_value(struct task_struct *task, + struct pt_regs *regs, + int error, long val) +{ + regs->gr[28] = error ? error : val; +} + +static inline void syscall_rollback(struct task_struct *task, + struct pt_regs *regs) +{ + /* do nothing */ +} + static inline int syscall_get_arch(void) { int arch = AUDIT_ARCH_PARISC; diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index ce0b2b4..8fb81a3 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, long do_syscall_trace_enter(struct pt_regs *regs) { /* Do the secure computing check first. */ - secure_computing_strict(regs->gr[20]); + if (secure_computing() == -1) + return -1; if (test_thread_flag(TIF_SYSCALL_TRACE) && tracehook_report_syscall_entry(regs)) { @@ -296,7 +297,11 @@ long do_syscall_trace_enter(struct pt_regs *regs) regs->gr[23] & 0xffffffff); out: - return regs->gr[20]; + /* + * Sign extend the syscall number to 64bit since it may have been + * modified by a compat ptrace call + */ + return (int) ((u32) regs->gr[20]); } void do_syscall_trace_exit(struct pt_regs *regs) diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index 984abbe..c342b2e 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c @@ -371,6 +371,11 @@ copy_siginfo_to_user32 (compat_siginfo_t __user *to, const siginfo_t *from) val = (compat_int_t)from->si_int; err |= __put_user(val, &to->si_int); break; + case __SI_SYS >> 16: + err |= __put_user(ptr_to_compat(from->si_call_addr), &to->si_call_addr); + err |= __put_user(from->si_syscall, &to->si_syscall); + err |= __put_user(from->si_arch, &to->si_arch); + break; } } return err; diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index fbafa0d..c976ebf 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -329,6 +329,7 @@ tracesys_next: ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ LDREG TI_TASK(%r1), %r1 + LDREG TASK_PT_GR28(%r1), %r28 /* Restore return value */ LDREG TASK_PT_GR26(%r1), %r26 /* Restore the users args */ LDREG TASK_PT_GR25(%r1), %r25 LDREG TASK_PT_GR24(%r1), %r24 @@ -342,6 +343,7 @@ tracesys_next: stw %r21, -56(%r30) /* 6th argument */ #endif + cmpib,COND(=),n -1,%r20,tracesys_exit /* seccomp may have returned -1 */ comiclr,>>= __NR_Linux_syscalls, %r20, %r0 b,n .Ltracesys_nosys |