diff options
Diffstat (limited to 'arch/um/os-Linux/start_up.c')
-rw-r--r-- | arch/um/os-Linux/start_up.c | 55 |
1 files changed, 20 insertions, 35 deletions
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index f22715868929..c5c36dbe819b 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include "registers.h" | 25 | #include "registers.h" |
26 | #include "skas_ptrace.h" | 26 | #include "skas_ptrace.h" |
27 | 27 | ||
28 | static int ptrace_child(void *arg) | 28 | static int ptrace_child(void) |
29 | { | 29 | { |
30 | int ret; | 30 | int ret; |
31 | int pid = os_getpid(), ppid = getppid(); | 31 | int pid = os_getpid(), ppid = getppid(); |
@@ -90,31 +90,23 @@ static void non_fatal(char *fmt, ...) | |||
90 | fflush(stdout); | 90 | fflush(stdout); |
91 | } | 91 | } |
92 | 92 | ||
93 | static int start_ptraced_child(void **stack_out) | 93 | static int start_ptraced_child(void) |
94 | { | 94 | { |
95 | void *stack; | ||
96 | unsigned long sp; | ||
97 | int pid, n, status; | 95 | int pid, n, status; |
98 | 96 | ||
99 | stack = mmap(NULL, UM_KERN_PAGE_SIZE, | 97 | pid = fork(); |
100 | PROT_READ | PROT_WRITE | PROT_EXEC, | 98 | if (pid == 0) |
101 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | 99 | ptrace_child(); |
102 | if (stack == MAP_FAILED) | 100 | else if (pid < 0) |
103 | fatal_perror("check_ptrace : mmap failed"); | 101 | fatal_perror("start_ptraced_child : fork failed"); |
104 | |||
105 | sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); | ||
106 | pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); | ||
107 | if (pid < 0) | ||
108 | fatal_perror("start_ptraced_child : clone failed"); | ||
109 | 102 | ||
110 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); | 103 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); |
111 | if (n < 0) | 104 | if (n < 0) |
112 | fatal_perror("check_ptrace : clone failed"); | 105 | fatal_perror("check_ptrace : waitpid failed"); |
113 | if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) | 106 | if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) |
114 | fatal("check_ptrace : expected SIGSTOP, got status = %d", | 107 | fatal("check_ptrace : expected SIGSTOP, got status = %d", |
115 | status); | 108 | status); |
116 | 109 | ||
117 | *stack_out = stack; | ||
118 | return pid; | 110 | return pid; |
119 | } | 111 | } |
120 | 112 | ||
@@ -124,8 +116,7 @@ static int start_ptraced_child(void **stack_out) | |||
124 | * So only for SYSEMU features we test mustpanic, while normal host features | 116 | * So only for SYSEMU features we test mustpanic, while normal host features |
125 | * must work anyway! | 117 | * must work anyway! |
126 | */ | 118 | */ |
127 | static int stop_ptraced_child(int pid, void *stack, int exitcode, | 119 | static int stop_ptraced_child(int pid, int exitcode, int mustexit) |
128 | int mustexit) | ||
129 | { | 120 | { |
130 | int status, n, ret = 0; | 121 | int status, n, ret = 0; |
131 | 122 | ||
@@ -145,8 +136,6 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, | |||
145 | ret = -1; | 136 | ret = -1; |
146 | } | 137 | } |
147 | 138 | ||
148 | if (munmap(stack, UM_KERN_PAGE_SIZE) < 0) | ||
149 | fatal_perror("check_ptrace : munmap failed"); | ||
150 | return ret; | 139 | return ret; |
151 | } | 140 | } |
152 | 141 | ||
@@ -198,13 +187,12 @@ __uml_setup("nosysemu", nosysemu_cmd_param, | |||
198 | 187 | ||
199 | static void __init check_sysemu(void) | 188 | static void __init check_sysemu(void) |
200 | { | 189 | { |
201 | void *stack; | ||
202 | unsigned long regs[MAX_REG_NR]; | 190 | unsigned long regs[MAX_REG_NR]; |
203 | int pid, n, status, count=0; | 191 | int pid, n, status, count=0; |
204 | 192 | ||
205 | non_fatal("Checking syscall emulation patch for ptrace..."); | 193 | non_fatal("Checking syscall emulation patch for ptrace..."); |
206 | sysemu_supported = 0; | 194 | sysemu_supported = 0; |
207 | pid = start_ptraced_child(&stack); | 195 | pid = start_ptraced_child(); |
208 | 196 | ||
209 | if (ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) | 197 | if (ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) |
210 | goto fail; | 198 | goto fail; |
@@ -231,7 +219,7 @@ static void __init check_sysemu(void) | |||
231 | goto fail; | 219 | goto fail; |
232 | } | 220 | } |
233 | 221 | ||
234 | if (stop_ptraced_child(pid, stack, 0, 0) < 0) | 222 | if (stop_ptraced_child(pid, 0, 0) < 0) |
235 | goto fail_stopped; | 223 | goto fail_stopped; |
236 | 224 | ||
237 | sysemu_supported = 1; | 225 | sysemu_supported = 1; |
@@ -239,7 +227,7 @@ static void __init check_sysemu(void) | |||
239 | set_using_sysemu(!force_sysemu_disabled); | 227 | set_using_sysemu(!force_sysemu_disabled); |
240 | 228 | ||
241 | non_fatal("Checking advanced syscall emulation patch for ptrace..."); | 229 | non_fatal("Checking advanced syscall emulation patch for ptrace..."); |
242 | pid = start_ptraced_child(&stack); | 230 | pid = start_ptraced_child(); |
243 | 231 | ||
244 | if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, | 232 | if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, |
245 | (void *) PTRACE_O_TRACESYSGOOD) < 0)) | 233 | (void *) PTRACE_O_TRACESYSGOOD) < 0)) |
@@ -271,7 +259,7 @@ static void __init check_sysemu(void) | |||
271 | fatal("check_ptrace : expected SIGTRAP or " | 259 | fatal("check_ptrace : expected SIGTRAP or " |
272 | "(SIGTRAP | 0x80), got status = %d", status); | 260 | "(SIGTRAP | 0x80), got status = %d", status); |
273 | } | 261 | } |
274 | if (stop_ptraced_child(pid, stack, 0, 0) < 0) | 262 | if (stop_ptraced_child(pid, 0, 0) < 0) |
275 | goto fail_stopped; | 263 | goto fail_stopped; |
276 | 264 | ||
277 | sysemu_supported = 2; | 265 | sysemu_supported = 2; |
@@ -282,18 +270,17 @@ static void __init check_sysemu(void) | |||
282 | return; | 270 | return; |
283 | 271 | ||
284 | fail: | 272 | fail: |
285 | stop_ptraced_child(pid, stack, 1, 0); | 273 | stop_ptraced_child(pid, 1, 0); |
286 | fail_stopped: | 274 | fail_stopped: |
287 | non_fatal("missing\n"); | 275 | non_fatal("missing\n"); |
288 | } | 276 | } |
289 | 277 | ||
290 | static void __init check_ptrace(void) | 278 | static void __init check_ptrace(void) |
291 | { | 279 | { |
292 | void *stack; | ||
293 | int pid, syscall, n, status; | 280 | int pid, syscall, n, status; |
294 | 281 | ||
295 | non_fatal("Checking that ptrace can change system call numbers..."); | 282 | non_fatal("Checking that ptrace can change system call numbers..."); |
296 | pid = start_ptraced_child(&stack); | 283 | pid = start_ptraced_child(); |
297 | 284 | ||
298 | if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, | 285 | if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, |
299 | (void *) PTRACE_O_TRACESYSGOOD) < 0)) | 286 | (void *) PTRACE_O_TRACESYSGOOD) < 0)) |
@@ -323,7 +310,7 @@ static void __init check_ptrace(void) | |||
323 | break; | 310 | break; |
324 | } | 311 | } |
325 | } | 312 | } |
326 | stop_ptraced_child(pid, stack, 0, 1); | 313 | stop_ptraced_child(pid, 0, 1); |
327 | non_fatal("OK\n"); | 314 | non_fatal("OK\n"); |
328 | check_sysemu(); | 315 | check_sysemu(); |
329 | } | 316 | } |
@@ -403,11 +390,10 @@ __uml_setup("noptraceldt", noptraceldt_cmd_param, | |||
403 | static inline void check_skas3_ptrace_faultinfo(void) | 390 | static inline void check_skas3_ptrace_faultinfo(void) |
404 | { | 391 | { |
405 | struct ptrace_faultinfo fi; | 392 | struct ptrace_faultinfo fi; |
406 | void *stack; | ||
407 | int pid, n; | 393 | int pid, n; |
408 | 394 | ||
409 | non_fatal(" - PTRACE_FAULTINFO..."); | 395 | non_fatal(" - PTRACE_FAULTINFO..."); |
410 | pid = start_ptraced_child(&stack); | 396 | pid = start_ptraced_child(); |
411 | 397 | ||
412 | n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); | 398 | n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); |
413 | if (n < 0) { | 399 | if (n < 0) { |
@@ -425,13 +411,12 @@ static inline void check_skas3_ptrace_faultinfo(void) | |||
425 | } | 411 | } |
426 | 412 | ||
427 | init_registers(pid); | 413 | init_registers(pid); |
428 | stop_ptraced_child(pid, stack, 1, 1); | 414 | stop_ptraced_child(pid, 1, 1); |
429 | } | 415 | } |
430 | 416 | ||
431 | static inline void check_skas3_ptrace_ldt(void) | 417 | static inline void check_skas3_ptrace_ldt(void) |
432 | { | 418 | { |
433 | #ifdef PTRACE_LDT | 419 | #ifdef PTRACE_LDT |
434 | void *stack; | ||
435 | int pid, n; | 420 | int pid, n; |
436 | unsigned char ldtbuf[40]; | 421 | unsigned char ldtbuf[40]; |
437 | struct ptrace_ldt ldt_op = (struct ptrace_ldt) { | 422 | struct ptrace_ldt ldt_op = (struct ptrace_ldt) { |
@@ -440,7 +425,7 @@ static inline void check_skas3_ptrace_ldt(void) | |||
440 | .bytecount = sizeof(ldtbuf)}; | 425 | .bytecount = sizeof(ldtbuf)}; |
441 | 426 | ||
442 | non_fatal(" - PTRACE_LDT..."); | 427 | non_fatal(" - PTRACE_LDT..."); |
443 | pid = start_ptraced_child(&stack); | 428 | pid = start_ptraced_child(); |
444 | 429 | ||
445 | n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op); | 430 | n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op); |
446 | if (n < 0) { | 431 | if (n < 0) { |
@@ -458,7 +443,7 @@ static inline void check_skas3_ptrace_ldt(void) | |||
458 | non_fatal("found, but use is disabled\n"); | 443 | non_fatal("found, but use is disabled\n"); |
459 | } | 444 | } |
460 | 445 | ||
461 | stop_ptraced_child(pid, stack, 1, 1); | 446 | stop_ptraced_child(pid, 1, 1); |
462 | #else | 447 | #else |
463 | /* PTRACE_LDT might be disabled via cmdline option. | 448 | /* PTRACE_LDT might be disabled via cmdline option. |
464 | * We want to override this, else we might use the stub | 449 | * We want to override this, else we might use the stub |