Browse Source

MIPS: O32: Do not handle require 32 bytes from the stack to be readable.

Commit 46e12c07b3b9603c60fc1d421ff18618241cb081 (MIPS: O32 / 32-bit:
Always copy 4 stack arguments.) change the O32 syscall handler to always
load four arguments from the userspace stack even for syscalls that
require fewer or no arguments to be copied.  This removes a large table
from kernel space and need to maintain it.  It appeared that it was ok
the implementation chosen requires 16 bytes of readable stack space
above the user stack pointer.

Turned out a few threading implementations munmap the user stack before
the thread exits resulting in errors due to the unreadable stack.

We now treat any failed load as a if the loaded value was zero and let
the actual syscall deal with the situation.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Ralf Baechle 10 years ago
parent
commit
7928eb0370
2 changed files with 52 additions and 18 deletions
  1. 27 10
      arch/mips/kernel/scall32-o32.S
  2. 25 8
      arch/mips/kernel/scall64-o32.S

+ 27 - 10
arch/mips/kernel/scall32-o32.S

@@ -73,10 +73,11 @@ NESTED(handle_sys, PT_SIZE, sp)
 	.set    noreorder
 	.set    noreorder
 	.set	nomacro
 	.set	nomacro
 
 
-1:	user_lw(t5, 16(t0))		# argument #5 from usp
-4:	user_lw(t6, 20(t0))		# argument #6 from usp
-3:	user_lw(t7, 24(t0))		# argument #7 from usp
-2:	user_lw(t8, 28(t0))		# argument #8 from usp
+load_a4: user_lw(t5, 16(t0))		# argument #5 from usp
+load_a5: user_lw(t6, 20(t0))		# argument #6 from usp
+load_a6: user_lw(t7, 24(t0))		# argument #7 from usp
+load_a7: user_lw(t8, 28(t0))		# argument #8 from usp
+loads_done:
 
 
 	sw	t5, 16(sp)		# argument #5 to ksp
 	sw	t5, 16(sp)		# argument #5 to ksp
 	sw	t6, 20(sp)		# argument #6 to ksp
 	sw	t6, 20(sp)		# argument #6 to ksp
@@ -85,10 +86,10 @@ NESTED(handle_sys, PT_SIZE, sp)
 	.set	pop
 	.set	pop
 
 
 	.section __ex_table,"a"
 	.section __ex_table,"a"
-	PTR	1b,bad_stack
-	PTR	2b,bad_stack
-	PTR	3b,bad_stack
-	PTR	4b,bad_stack
+	PTR	load_a4, bad_stack_a4
+	PTR	load_a5, bad_stack_a5
+	PTR	load_a6, bad_stack_a6
+	PTR	load_a7, bad_stack_a7
 	.previous
 	.previous
 
 
 	lw	t0, TI_FLAGS($28)	# syscall tracing enabled?
 	lw	t0, TI_FLAGS($28)	# syscall tracing enabled?
@@ -153,8 +154,8 @@ syscall_trace_entry:
 /* ------------------------------------------------------------------------ */
 /* ------------------------------------------------------------------------ */
 
 
 	/*
 	/*
-	 * The stackpointer for a call with more than 4 arguments is bad.
-	 * We probably should handle this case a bit more drastic.
+	 * Our open-coded access area sanity test for the stack pointer
+	 * failed. We probably should handle this case a bit more drastic.
 	 */
 	 */
 bad_stack:
 bad_stack:
 	li	v0, EFAULT
 	li	v0, EFAULT
@@ -163,6 +164,22 @@ bad_stack:
 	sw	t0, PT_R7(sp)
 	sw	t0, PT_R7(sp)
 	j	o32_syscall_exit
 	j	o32_syscall_exit
 
 
+bad_stack_a4:
+	li	t5, 0
+	b	load_a5
+
+bad_stack_a5:
+	li	t6, 0
+	b	load_a6
+
+bad_stack_a6:
+	li	t7, 0
+	b	load_a7
+
+bad_stack_a7:
+	li	t8, 0
+	b	loads_done
+
 	/*
 	/*
 	 * The system call does not exist in this kernel
 	 * The system call does not exist in this kernel
 	 */
 	 */

+ 25 - 8
arch/mips/kernel/scall64-o32.S

@@ -69,16 +69,17 @@ NESTED(handle_sys, PT_SIZE, sp)
 	daddu	t1, t0, 32
 	daddu	t1, t0, 32
 	bltz	t1, bad_stack
 	bltz	t1, bad_stack
 
 
-1:	lw	a4, 16(t0)		# argument #5 from usp
-2:	lw	a5, 20(t0)		# argument #6 from usp
-3:	lw	a6, 24(t0)		# argument #7 from usp
-4:	lw	a7, 28(t0)		# argument #8 from usp (for indirect syscalls)
+load_a4: lw	a4, 16(t0)		# argument #5 from usp
+load_a5: lw	a5, 20(t0)		# argument #6 from usp
+load_a6: lw	a6, 24(t0)		# argument #7 from usp
+load_a7: lw	a7, 28(t0)		# argument #8 from usp
+loads_done:
 
 
 	.section __ex_table,"a"
 	.section __ex_table,"a"
-	PTR	1b, bad_stack
-	PTR	2b, bad_stack
-	PTR	3b, bad_stack
-	PTR	4b, bad_stack
+	PTR	load_a4, bad_stack_a4
+	PTR	load_a5, bad_stack_a5
+	PTR	load_a6, bad_stack_a6
+	PTR	load_a7, bad_stack_a7
 	.previous
 	.previous
 
 
 	li	t1, _TIF_WORK_SYSCALL_ENTRY
 	li	t1, _TIF_WORK_SYSCALL_ENTRY
@@ -167,6 +168,22 @@ bad_stack:
 	sd	t0, PT_R7(sp)
 	sd	t0, PT_R7(sp)
 	j	o32_syscall_exit
 	j	o32_syscall_exit
 
 
+bad_stack_a4:
+	li	a4, 0
+	b	load_a5
+
+bad_stack_a5:
+	li	a5, 0
+	b	load_a6
+
+bad_stack_a6:
+	li	a6, 0
+	b	load_a7
+
+bad_stack_a7:
+	li	a7, 0
+	b	loads_done
+
 not_o32_scall:
 not_o32_scall:
 	/*
 	/*
 	 * This is not an o32 compatibility syscall, pass it on
 	 * This is not an o32 compatibility syscall, pass it on