mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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: Markos Chandras <markos.chandras@imgtec.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/11236/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
		
							parent
							
								
									66803dd919
								
							
						
					
					
						commit
						d218af7849
					
				
					 4 changed files with 42 additions and 73 deletions
				
			
		| 
						 | 
				
			
			@ -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
 | 
			
		||||
	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
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
	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:
 | 
			
		||||
	/* This also isn't a 64-bit syscall, throw an error.  */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue