summaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2015-07-07 22:49:10 -0400
committerRalf Baechle <ralf@linux-mips.org>2015-07-07 23:03:30 -0400
commit7928eb0370d1133d0d8cd2f5ddfca19c309079d5 (patch)
tree0302124558fbad7327630babc1804aa5977e8c2f /arch/mips
parent0bb383a2d8f51e32ecc156f3f84067420ffe6d20 (diff)
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>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/kernel/scall32-o32.S37
-rw-r--r--arch/mips/kernel/scall64-o32.S33
2 files changed, 52 insertions, 18 deletions
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 6e8de80bb446..4cc13508d967 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -73,10 +73,11 @@ NESTED(handle_sys, PT_SIZE, sp)
73 .set noreorder 73 .set noreorder
74 .set nomacro 74 .set nomacro
75 75
761: user_lw(t5, 16(t0)) # argument #5 from usp 76load_a4: user_lw(t5, 16(t0)) # argument #5 from usp
774: user_lw(t6, 20(t0)) # argument #6 from usp 77load_a5: user_lw(t6, 20(t0)) # argument #6 from usp
783: user_lw(t7, 24(t0)) # argument #7 from usp 78load_a6: user_lw(t7, 24(t0)) # argument #7 from usp
792: user_lw(t8, 28(t0)) # argument #8 from usp 79load_a7: user_lw(t8, 28(t0)) # argument #8 from usp
80loads_done:
80 81
81 sw t5, 16(sp) # argument #5 to ksp 82 sw t5, 16(sp) # argument #5 to ksp
82 sw t6, 20(sp) # argument #6 to ksp 83 sw t6, 20(sp) # argument #6 to ksp
@@ -85,10 +86,10 @@ NESTED(handle_sys, PT_SIZE, sp)
85 .set pop 86 .set pop
86 87
87 .section __ex_table,"a" 88 .section __ex_table,"a"
88 PTR 1b,bad_stack 89 PTR load_a4, bad_stack_a4
89 PTR 2b,bad_stack 90 PTR load_a5, bad_stack_a5
90 PTR 3b,bad_stack 91 PTR load_a6, bad_stack_a6
91 PTR 4b,bad_stack 92 PTR load_a7, bad_stack_a7
92 .previous 93 .previous
93 94
94 lw t0, TI_FLAGS($28) # syscall tracing enabled? 95 lw t0, TI_FLAGS($28) # syscall tracing enabled?
@@ -153,8 +154,8 @@ syscall_trace_entry:
153/* ------------------------------------------------------------------------ */ 154/* ------------------------------------------------------------------------ */
154 155
155 /* 156 /*
156 * The stackpointer for a call with more than 4 arguments is bad. 157 * Our open-coded access area sanity test for the stack pointer
157 * We probably should handle this case a bit more drastic. 158 * failed. We probably should handle this case a bit more drastic.
158 */ 159 */
159bad_stack: 160bad_stack:
160 li v0, EFAULT 161 li v0, EFAULT
@@ -163,6 +164,22 @@ bad_stack:
163 sw t0, PT_R7(sp) 164 sw t0, PT_R7(sp)
164 j o32_syscall_exit 165 j o32_syscall_exit
165 166
167bad_stack_a4:
168 li t5, 0
169 b load_a5
170
171bad_stack_a5:
172 li t6, 0
173 b load_a6
174
175bad_stack_a6:
176 li t7, 0
177 b load_a7
178
179bad_stack_a7:
180 li t8, 0
181 b loads_done
182
166 /* 183 /*
167 * The system call does not exist in this kernel 184 * The system call does not exist in this kernel
168 */ 185 */
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index d07b210fbeff..66d618bb2fa2 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -69,16 +69,17 @@ NESTED(handle_sys, PT_SIZE, sp)
69 daddu t1, t0, 32 69 daddu t1, t0, 32
70 bltz t1, bad_stack 70 bltz t1, bad_stack
71 71
721: lw a4, 16(t0) # argument #5 from usp 72load_a4: lw a4, 16(t0) # argument #5 from usp
732: lw a5, 20(t0) # argument #6 from usp 73load_a5: lw a5, 20(t0) # argument #6 from usp
743: lw a6, 24(t0) # argument #7 from usp 74load_a6: lw a6, 24(t0) # argument #7 from usp
754: lw a7, 28(t0) # argument #8 from usp (for indirect syscalls) 75load_a7: lw a7, 28(t0) # argument #8 from usp
76loads_done:
76 77
77 .section __ex_table,"a" 78 .section __ex_table,"a"
78 PTR 1b, bad_stack 79 PTR load_a4, bad_stack_a4
79 PTR 2b, bad_stack 80 PTR load_a5, bad_stack_a5
80 PTR 3b, bad_stack 81 PTR load_a6, bad_stack_a6
81 PTR 4b, bad_stack 82 PTR load_a7, bad_stack_a7
82 .previous 83 .previous
83 84
84 li t1, _TIF_WORK_SYSCALL_ENTRY 85 li t1, _TIF_WORK_SYSCALL_ENTRY
@@ -167,6 +168,22 @@ bad_stack:
167 sd t0, PT_R7(sp) 168 sd t0, PT_R7(sp)
168 j o32_syscall_exit 169 j o32_syscall_exit
169 170
171bad_stack_a4:
172 li a4, 0
173 b load_a5
174
175bad_stack_a5:
176 li a5, 0
177 b load_a6
178
179bad_stack_a6:
180 li a6, 0
181 b load_a7
182
183bad_stack_a7:
184 li a7, 0
185 b loads_done
186
170not_o32_scall: 187not_o32_scall:
171 /* 188 /*
172 * This is not an o32 compatibility syscall, pass it on 189 * This is not an o32 compatibility syscall, pass it on