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 Original line Diff line number Diff line
@@ -36,16 +36,8 @@ NESTED(handle_sys, PT_SIZE, sp)
	lw	t1, PT_EPC(sp)		# skip syscall on return
	lw	t1, PT_EPC(sp)		# skip syscall on return


	subu	v0, v0, __NR_O32_Linux	# check syscall number
	subu	v0, v0, __NR_O32_Linux	# check syscall number
	sltiu	t0, v0, __NR_O32_Linux_syscalls + 1
	addiu	t1, 4			# skip to next instruction
	addiu	t1, 4			# skip to next instruction
	sw	t1, PT_EPC(sp)
	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
	sw	a3, PT_R26(sp)		# save a3 for syscall restarting


@@ -96,6 +88,16 @@ loads_done:
	li	t1, _TIF_WORK_SYSCALL_ENTRY
	li	t1, _TIF_WORK_SYSCALL_ENTRY
	and	t0, t1
	and	t0, t1
	bnez	t0, syscall_trace_entry # -> yes
	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)
	jalr	t2			# Do The Real Thing (TM)


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


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


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


1:	jal	syscall_trace_enter
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
	RESTORE_STATIC
	lw	a0, PT_R4(sp)		# Restore argument registers
	lw	a0, PT_R4(sp)		# Restore argument registers
	lw	a1, PT_R5(sp)
	lw	a1, PT_R5(sp)
	lw	a2, PT_R6(sp)
	lw	a2, PT_R6(sp)
	lw	a3, PT_R7(sp)
	lw	a3, PT_R7(sp)
	jalr	t0
	j	syscall_common

	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


2:	j	syscall_exit
1:	j	syscall_exit


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


+16 −22
Original line number Original line Diff line number Diff line
@@ -39,18 +39,11 @@ NESTED(handle_sys64, PT_SIZE, sp)
	.set	at
	.set	at
#endif
#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)
#if !defined(CONFIG_MIPS32_O32) && !defined(CONFIG_MIPS32_N32)
	ld	t1, PT_EPC(sp)		# skip syscall on return
	ld	t1, PT_EPC(sp)		# skip syscall on return
	daddiu	t1, 4			# skip to next instruction
	daddiu	t1, 4			# skip to next instruction
	sd	t1, PT_EPC(sp)
	sd	t1, PT_EPC(sp)
#endif
#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
	sd	a3, PT_R26(sp)		# save a3 for syscall restarting


@@ -59,6 +52,17 @@ NESTED(handle_sys64, PT_SIZE, sp)
	and	t0, t1, t0
	and	t0, t1, t0
	bnez	t0, syscall_trace_entry
	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)
	jalr	t2			# Do The Real Thing (TM)


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


syscall_trace_entry:
syscall_trace_entry:
	SAVE_STATIC
	SAVE_STATIC
	move	s0, t2
	move	s0, v0
	move	a0, sp
	move	a0, sp
	move	a1, v0
	move	a1, v0
	jal	syscall_trace_enter
	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
	RESTORE_STATIC
	ld	a0, PT_R4(sp)		# Restore argument registers
	ld	a0, PT_R4(sp)		# Restore argument registers
	ld	a1, PT_R5(sp)
	ld	a1, PT_R5(sp)
@@ -93,19 +97,9 @@ syscall_trace_entry:
	ld	a3, PT_R7(sp)
	ld	a3, PT_R7(sp)
	ld	a4, PT_R8(sp)
	ld	a4, PT_R8(sp)
	ld	a5, PT_R9(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


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


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


	li	t0, -EMAXERRNO - 1	# error?
	li	t0, -EMAXERRNO - 1	# error?
@@ -75,9 +76,9 @@ n32_syscall_trace_entry:
	move	a1, v0
	move	a1, v0
	jal	syscall_trace_enter
	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
	RESTORE_STATIC
	ld	a0, PT_R4(sp)		# Restore argument registers
	ld	a0, PT_R4(sp)		# Restore argument registers
	ld	a1, PT_R5(sp)
	ld	a1, PT_R5(sp)
@@ -85,19 +86,9 @@ n32_syscall_trace_entry:
	ld	a3, PT_R7(sp)
	ld	a3, PT_R7(sp)
	ld	a4, PT_R8(sp)
	ld	a4, PT_R8(sp)
	ld	a5, PT_R9(sp)
	ld	a5, PT_R9(sp)
	jalr	t0
	j	syscall_common


	li	t0, -EMAXERRNO - 1	# error?
1:	j	syscall_exit
	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


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


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


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


1:	jal	syscall_trace_enter
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
	RESTORE_STATIC
	ld	a0, PT_R4(sp)		# Restore argument registers
	ld	a0, PT_R4(sp)		# Restore argument registers
	ld	a1, PT_R5(sp)
	ld	a1, PT_R5(sp)
@@ -142,19 +143,9 @@ trace_a_syscall:
	ld	a5, PT_R9(sp)
	ld	a5, PT_R9(sp)
	ld	a6, PT_R10(sp)
	ld	a6, PT_R10(sp)
	ld	a7, PT_R11(sp)		# For indirect syscalls
	ld	a7, PT_R11(sp)		# For indirect syscalls
	jalr	t0
	j	syscall_common


	li	t0, -EMAXERRNO - 1	# error?
1:	j	syscall_exit
	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


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