Skip to content

Commit

Permalink
parisc: Fix and enable seccomp filter support
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Helge Deller committed Mar 31, 2016
1 parent 4f4acc9 commit 910cd32
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 2 deletions.
1 change: 1 addition & 0 deletions arch/parisc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,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
Expand Down
13 changes: 13 additions & 0 deletions arch/parisc/include/asm/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
9 changes: 7 additions & 2 deletions arch/parisc/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand All @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions arch/parisc/kernel/syscall.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down

0 comments on commit 910cd32

Please sign in to comment.