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