Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 910cd32e authored by Helge Deller's avatar Helge Deller
Browse files

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: default avatarHelge Deller <deller@gmx.de>
Cc: stable@vger.kernel.org # v4.5
parent 4f4acc94
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+13 −0
Original line number Diff line number Diff line
@@ -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;
+7 −2
Original line number Diff line number Diff line
@@ -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)
+2 −0
Original line number Diff line number Diff line
@@ -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