diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/um/kernel/process.c | 48 |
1 files changed, 19 insertions, 29 deletions
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 793c77c6ef9c..1b5ef3e96c71 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c | |||
@@ -130,7 +130,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack, | |||
130 | return(arg.pid); | 130 | return(arg.pid); |
131 | } | 131 | } |
132 | 132 | ||
133 | static int ptrace_child(void *arg) | 133 | static int ptrace_child(void) |
134 | { | 134 | { |
135 | int ret; | 135 | int ret; |
136 | int pid = os_getpid(), ppid = getppid(); | 136 | int pid = os_getpid(), ppid = getppid(); |
@@ -159,20 +159,16 @@ static int ptrace_child(void *arg) | |||
159 | _exit(ret); | 159 | _exit(ret); |
160 | } | 160 | } |
161 | 161 | ||
162 | static int start_ptraced_child(void **stack_out) | 162 | static int start_ptraced_child(void) |
163 | { | 163 | { |
164 | void *stack; | ||
165 | unsigned long sp; | ||
166 | int pid, n, status; | 164 | int pid, n, status; |
167 | 165 | ||
168 | stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, | 166 | pid = fork(); |
169 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | 167 | if(pid == 0) |
170 | if(stack == MAP_FAILED) | 168 | ptrace_child(); |
171 | panic("check_ptrace : mmap failed, errno = %d", errno); | 169 | |
172 | sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); | ||
173 | pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); | ||
174 | if(pid < 0) | 170 | if(pid < 0) |
175 | panic("check_ptrace : clone failed, errno = %d", errno); | 171 | panic("check_ptrace : fork failed, errno = %d", errno); |
176 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); | 172 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); |
177 | if(n < 0) | 173 | if(n < 0) |
178 | panic("check_ptrace : wait failed, errno = %d", errno); | 174 | panic("check_ptrace : wait failed, errno = %d", errno); |
@@ -180,7 +176,6 @@ static int start_ptraced_child(void **stack_out) | |||
180 | panic("check_ptrace : expected SIGSTOP, got status = %d", | 176 | panic("check_ptrace : expected SIGSTOP, got status = %d", |
181 | status); | 177 | status); |
182 | 178 | ||
183 | *stack_out = stack; | ||
184 | return(pid); | 179 | return(pid); |
185 | } | 180 | } |
186 | 181 | ||
@@ -188,12 +183,12 @@ static int start_ptraced_child(void **stack_out) | |||
188 | * just avoid using sysemu, not panic, but only if SYSEMU features are broken. | 183 | * just avoid using sysemu, not panic, but only if SYSEMU features are broken. |
189 | * So only for SYSEMU features we test mustpanic, while normal host features | 184 | * So only for SYSEMU features we test mustpanic, while normal host features |
190 | * must work anyway!*/ | 185 | * must work anyway!*/ |
191 | static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) | 186 | static int stop_ptraced_child(int pid, int exitcode, int mustexit) |
192 | { | 187 | { |
193 | int status, n, ret = 0; | 188 | int status, n, ret = 0; |
194 | 189 | ||
195 | if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) | 190 | if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) |
196 | panic("check_ptrace : ptrace failed, errno = %d", errno); | 191 | panic("stop_ptraced_child : ptrace failed, errno = %d", errno); |
197 | CATCH_EINTR(n = waitpid(pid, &status, 0)); | 192 | CATCH_EINTR(n = waitpid(pid, &status, 0)); |
198 | if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { | 193 | if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { |
199 | int exit_with = WEXITSTATUS(status); | 194 | int exit_with = WEXITSTATUS(status); |
@@ -204,15 +199,13 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) | |||
204 | printk("check_ptrace : child exited with exitcode %d, while " | 199 | printk("check_ptrace : child exited with exitcode %d, while " |
205 | "expecting %d; status 0x%x", exit_with, | 200 | "expecting %d; status 0x%x", exit_with, |
206 | exitcode, status); | 201 | exitcode, status); |
207 | if (mustpanic) | 202 | if (mustexit) |
208 | panic("\n"); | 203 | panic("\n"); |
209 | else | 204 | else |
210 | printk("\n"); | 205 | printk("\n"); |
211 | ret = -1; | 206 | ret = -1; |
212 | } | 207 | } |
213 | 208 | ||
214 | if(munmap(stack, PAGE_SIZE) < 0) | ||
215 | panic("check_ptrace : munmap failed, errno = %d", errno); | ||
216 | return ret; | 209 | return ret; |
217 | } | 210 | } |
218 | 211 | ||
@@ -234,12 +227,11 @@ __uml_setup("nosysemu", nosysemu_cmd_param, | |||
234 | 227 | ||
235 | static void __init check_sysemu(void) | 228 | static void __init check_sysemu(void) |
236 | { | 229 | { |
237 | void *stack; | ||
238 | int pid, syscall, n, status, count=0; | 230 | int pid, syscall, n, status, count=0; |
239 | 231 | ||
240 | printk("Checking syscall emulation patch for ptrace..."); | 232 | printk("Checking syscall emulation patch for ptrace..."); |
241 | sysemu_supported = 0; | 233 | sysemu_supported = 0; |
242 | pid = start_ptraced_child(&stack); | 234 | pid = start_ptraced_child(); |
243 | 235 | ||
244 | if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) | 236 | if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) |
245 | goto fail; | 237 | goto fail; |
@@ -257,7 +249,7 @@ static void __init check_sysemu(void) | |||
257 | panic("check_sysemu : failed to modify system " | 249 | panic("check_sysemu : failed to modify system " |
258 | "call return, errno = %d", errno); | 250 | "call return, errno = %d", errno); |
259 | 251 | ||
260 | if (stop_ptraced_child(pid, stack, 0, 0) < 0) | 252 | if (stop_ptraced_child(pid, 0, 0) < 0) |
261 | goto fail_stopped; | 253 | goto fail_stopped; |
262 | 254 | ||
263 | sysemu_supported = 1; | 255 | sysemu_supported = 1; |
@@ -265,7 +257,7 @@ static void __init check_sysemu(void) | |||
265 | set_using_sysemu(!force_sysemu_disabled); | 257 | set_using_sysemu(!force_sysemu_disabled); |
266 | 258 | ||
267 | printk("Checking advanced syscall emulation patch for ptrace..."); | 259 | printk("Checking advanced syscall emulation patch for ptrace..."); |
268 | pid = start_ptraced_child(&stack); | 260 | pid = start_ptraced_child(); |
269 | while(1){ | 261 | while(1){ |
270 | count++; | 262 | count++; |
271 | if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) | 263 | if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) |
@@ -290,7 +282,7 @@ static void __init check_sysemu(void) | |||
290 | break; | 282 | break; |
291 | } | 283 | } |
292 | } | 284 | } |
293 | if (stop_ptraced_child(pid, stack, 0, 0) < 0) | 285 | if (stop_ptraced_child(pid, 0, 0) < 0) |
294 | goto fail_stopped; | 286 | goto fail_stopped; |
295 | 287 | ||
296 | sysemu_supported = 2; | 288 | sysemu_supported = 2; |
@@ -301,18 +293,17 @@ static void __init check_sysemu(void) | |||
301 | return; | 293 | return; |
302 | 294 | ||
303 | fail: | 295 | fail: |
304 | stop_ptraced_child(pid, stack, 1, 0); | 296 | stop_ptraced_child(pid, 1, 0); |
305 | fail_stopped: | 297 | fail_stopped: |
306 | printk("missing\n"); | 298 | printk("missing\n"); |
307 | } | 299 | } |
308 | 300 | ||
309 | void __init check_ptrace(void) | 301 | void __init check_ptrace(void) |
310 | { | 302 | { |
311 | void *stack; | ||
312 | int pid, syscall, n, status; | 303 | int pid, syscall, n, status; |
313 | 304 | ||
314 | printk("Checking that ptrace can change system call numbers..."); | 305 | printk("Checking that ptrace can change system call numbers..."); |
315 | pid = start_ptraced_child(&stack); | 306 | pid = start_ptraced_child(); |
316 | 307 | ||
317 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) | 308 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) |
318 | panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); | 309 | panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); |
@@ -339,7 +330,7 @@ void __init check_ptrace(void) | |||
339 | break; | 330 | break; |
340 | } | 331 | } |
341 | } | 332 | } |
342 | stop_ptraced_child(pid, stack, 0, 1); | 333 | stop_ptraced_child(pid, 0, 1); |
343 | printk("OK\n"); | 334 | printk("OK\n"); |
344 | check_sysemu(); | 335 | check_sysemu(); |
345 | } | 336 | } |
@@ -371,11 +362,10 @@ void forward_pending_sigio(int target) | |||
371 | static inline int check_skas3_ptrace_support(void) | 362 | static inline int check_skas3_ptrace_support(void) |
372 | { | 363 | { |
373 | struct ptrace_faultinfo fi; | 364 | struct ptrace_faultinfo fi; |
374 | void *stack; | ||
375 | int pid, n, ret = 1; | 365 | int pid, n, ret = 1; |
376 | 366 | ||
377 | printf("Checking for the skas3 patch in the host..."); | 367 | printf("Checking for the skas3 patch in the host..."); |
378 | pid = start_ptraced_child(&stack); | 368 | pid = start_ptraced_child(); |
379 | 369 | ||
380 | n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); | 370 | n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); |
381 | if (n < 0) { | 371 | if (n < 0) { |
@@ -390,7 +380,7 @@ static inline int check_skas3_ptrace_support(void) | |||
390 | } | 380 | } |
391 | 381 | ||
392 | init_registers(pid); | 382 | init_registers(pid); |
393 | stop_ptraced_child(pid, stack, 1, 1); | 383 | stop_ptraced_child(pid, 1, 1); |
394 | 384 | ||
395 | return(ret); | 385 | return(ret); |
396 | } | 386 | } |