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

Commit d218af78 authored by Markos Chandras's avatar Markos Chandras Committed by Ralf Baechle
Browse files

MIPS: scall: Always run the seccomp syscall filters



The MIPS syscall handler code used to return -ENOSYS on invalid
syscalls. Whilst this is expected, it caused problems for seccomp
filters because the said filters never had the change to run since
the code returned -ENOSYS before triggering them. This caused
problems on the chromium testsuite for filters looking for invalid
syscalls. This has now changed and the seccomp filters are always
run even if the syscall is invalid. We return -ENOSYS once we
return from the seccomp filters. Moreover, similar codepaths have
been merged in the process which simplifies somewhat the overall
syscall code.

Signed-off-by: default avatarMarkos Chandras <markos.chandras@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/11236/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 66803dd9
Loading
Loading
Loading
Loading
+16 −23
Original line number Diff line number Diff line
@@ -36,16 +36,8 @@ NESTED(handle_sys, PT_SIZE, sp)
	lw	t1, PT_EPC(sp)		# skip syscall on return

	subu	v0, v0, __NR_O32_Linux	# check syscall number
	sltiu	t0, v0, __NR_O32_Linux_syscalls + 1
	addiu	t1, 4			# skip to next instruction
	sw	t1, PT_EPC(sp)
	beqz	t0, illegal_syscall

	sll	t0, v0, 2
	la	t1, sys_call_table
	addu	t1, t0
	lw	t2, (t1)		# syscall routine
	beqz	t2, illegal_syscall

	sw	a3, PT_R26(sp)		# save a3 for syscall restarting

@@ -96,6 +88,16 @@ loads_done:
	li	t1, _TIF_WORK_SYSCALL_ENTRY
	and	t0, t1
	bnez	t0, syscall_trace_entry # -> yes
syscall_common:
	sltiu	t0, v0, __NR_O32_Linux_syscalls + 1
	beqz	t0, illegal_syscall

	sll	t0, v0, 2
	la	t1, sys_call_table
	addu	t1, t0
	lw	t2, (t1)		# syscall routine

	beqz	t2, illegal_syscall

	jalr	t2			# Do The Real Thing (TM)

@@ -116,7 +118,7 @@ o32_syscall_exit:

syscall_trace_entry:
	SAVE_STATIC
	move	s0, t2
	move	s0, v0
	move	a0, sp

	/*
@@ -129,27 +131,18 @@ syscall_trace_entry:

1:	jal	syscall_trace_enter

	bltz	v0, 2f			# seccomp failed? Skip syscall
	bltz	v0, 1f			# seccomp failed? Skip syscall

	move	v0, s0			# restore syscall

	move	t0, s0
	RESTORE_STATIC
	lw	a0, PT_R4(sp)		# Restore argument registers
	lw	a1, PT_R5(sp)
	lw	a2, PT_R6(sp)
	lw	a3, PT_R7(sp)
	jalr	t0

	li	t0, -EMAXERRNO - 1	# error?
	sltu	t0, t0, v0
	sw	t0, PT_R7(sp)		# set error flag
	beqz	t0, 1f

	lw	t1, PT_R2(sp)		# syscall number
	negu	v0			# error
	sw	t1, PT_R0(sp)		# save it for syscall restarting
1:	sw	v0, PT_R2(sp)		# result
	j	syscall_common

2:	j	syscall_exit
1:	j	syscall_exit

/* ------------------------------------------------------------------------ */

+16 −22
Original line number Diff line number Diff line
@@ -39,18 +39,11 @@ NESTED(handle_sys64, PT_SIZE, sp)
	.set	at
#endif

	dsubu	t0, v0, __NR_64_Linux	# check syscall number
	sltiu	t0, t0, __NR_64_Linux_syscalls + 1
#if !defined(CONFIG_MIPS32_O32) && !defined(CONFIG_MIPS32_N32)
	ld	t1, PT_EPC(sp)		# skip syscall on return
	daddiu	t1, 4			# skip to next instruction
	sd	t1, PT_EPC(sp)
#endif
	beqz	t0, illegal_syscall

	dsll	t0, v0, 3		# offset into table
	ld	t2, (sys_call_table - (__NR_64_Linux * 8))(t0)
					# syscall routine

	sd	a3, PT_R26(sp)		# save a3 for syscall restarting

@@ -59,6 +52,17 @@ NESTED(handle_sys64, PT_SIZE, sp)
	and	t0, t1, t0
	bnez	t0, syscall_trace_entry

syscall_common:
	dsubu	t2, v0, __NR_64_Linux
	sltiu   t0, t2, __NR_64_Linux_syscalls + 1
	beqz	t0, illegal_syscall

	dsll	t0, t2, 3		# offset into table
	dla	t2, sys_call_table
	daddu	t0, t2, t0
	ld	t2, (t0)		# syscall routine
	beqz	t2, illegal_syscall

	jalr	t2			# Do The Real Thing (TM)

	li	t0, -EMAXERRNO - 1	# error?
@@ -78,14 +82,14 @@ n64_syscall_exit:

syscall_trace_entry:
	SAVE_STATIC
	move	s0, t2
	move	s0, v0
	move	a0, sp
	move	a1, v0
	jal	syscall_trace_enter

	bltz	v0, 2f			# seccomp failed? Skip syscall
	bltz	v0, 1f			# seccomp failed? Skip syscall

	move	t0, s0
	move	v0, s0
	RESTORE_STATIC
	ld	a0, PT_R4(sp)		# Restore argument registers
	ld	a1, PT_R5(sp)
@@ -93,19 +97,9 @@ syscall_trace_entry:
	ld	a3, PT_R7(sp)
	ld	a4, PT_R8(sp)
	ld	a5, PT_R9(sp)
	jalr	t0

	li	t0, -EMAXERRNO - 1	# error?
	sltu	t0, t0, v0
	sd	t0, PT_R7(sp)		# set error flag
	beqz	t0, 1f

	ld	t1, PT_R2(sp)		# syscall number
	dnegu	v0			# error
	sd	t1, PT_R0(sp)		# save it for syscall restarting
1:	sd	v0, PT_R2(sp)		# result
	j	syscall_common

2:	j	syscall_exit
1:	j	syscall_exit

illegal_syscall:
	/* This also isn't a 64-bit syscall, throw an error.  */
+5 −14
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ NESTED(handle_sysn32, PT_SIZE, sp)
	and	t0, t1, t0
	bnez	t0, n32_syscall_trace_entry

syscall_common:
	jalr	t2			# Do The Real Thing (TM)

	li	t0, -EMAXERRNO - 1	# error?
@@ -75,9 +76,9 @@ n32_syscall_trace_entry:
	move	a1, v0
	jal	syscall_trace_enter

	bltz	v0, 2f			# seccomp failed? Skip syscall
	bltz	v0, 1f			# seccomp failed? Skip syscall

	move	t0, s0
	move	t2, s0
	RESTORE_STATIC
	ld	a0, PT_R4(sp)		# Restore argument registers
	ld	a1, PT_R5(sp)
@@ -85,19 +86,9 @@ n32_syscall_trace_entry:
	ld	a3, PT_R7(sp)
	ld	a4, PT_R8(sp)
	ld	a5, PT_R9(sp)
	jalr	t0
	j	syscall_common

	li	t0, -EMAXERRNO - 1	# error?
	sltu	t0, t0, v0
	sd	t0, PT_R7(sp)		# set error flag
	beqz	t0, 1f

	ld	t1, PT_R2(sp)		# syscall number
	dnegu	v0			# error
	sd	t1, PT_R0(sp)		# save it for syscall restarting
1:	sd	v0, PT_R2(sp)		# result

2:	j	syscall_exit
1:	j	syscall_exit

not_n32_scall:
	/* This is not an n32 compatibility syscall, pass it on to
+5 −14
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ loads_done:
	and	t0, t1, t0
	bnez	t0, trace_a_syscall

syscall_common:
	jalr	t2			# Do The Real Thing (TM)

	li	t0, -EMAXERRNO - 1	# error?
@@ -130,9 +131,9 @@ trace_a_syscall:

1:	jal	syscall_trace_enter

	bltz	v0, 2f			# seccomp failed? Skip syscall
	bltz	v0, 1f			# seccomp failed? Skip syscall

	move	t0, s0
	move	t2, s0
	RESTORE_STATIC
	ld	a0, PT_R4(sp)		# Restore argument registers
	ld	a1, PT_R5(sp)
@@ -142,19 +143,9 @@ trace_a_syscall:
	ld	a5, PT_R9(sp)
	ld	a6, PT_R10(sp)
	ld	a7, PT_R11(sp)		# For indirect syscalls
	jalr	t0
	j	syscall_common

	li	t0, -EMAXERRNO - 1	# error?
	sltu	t0, t0, v0
	sd	t0, PT_R7(sp)		# set error flag
	beqz	t0, 1f

	ld	t1, PT_R2(sp)		# syscall number
	dnegu	v0			# error
	sd	t1, PT_R0(sp)		# save it for syscall restarting
1:	sd	v0, PT_R2(sp)		# result

2:	j	syscall_exit
1:	j	syscall_exit

/* ------------------------------------------------------------------------ */