diff options
Diffstat (limited to 'arch/um/os-Linux/start_up.c')
-rw-r--r-- | arch/um/os-Linux/start_up.c | 153 |
1 files changed, 74 insertions, 79 deletions
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index abfc094c3c4..f2271586892 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -1,41 +1,29 @@ /* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <pty.h> #include <stdio.h> -#include <stddef.h> -#include <stdarg.h> #include <stdlib.h> -#include <string.h> +#include <stdarg.h> #include <unistd.h> -#include <signal.h> -#include <sched.h> -#include <fcntl.h> #include <errno.h> -#include <sys/time.h> -#include <sys/wait.h> +#include <fcntl.h> +#include <sched.h> +#include <signal.h> +#include <string.h> #include <sys/mman.h> -#include <sys/resource.h> +#include <sys/ptrace.h> +#include <sys/stat.h> +#include <sys/wait.h> #include <asm/unistd.h> -#include <sys/types.h> -#include "kern_util.h" -#include "user.h" -#include "signal_kern.h" -#include "sysdep/ptrace.h" -#include "sysdep/sigcontext.h" -#include "irq_user.h" -#include "ptrace_user.h" -#include "mem_user.h" #include "init.h" -#include "os.h" -#include "uml-config.h" -#include "tempfile.h" #include "kern_constants.h" -#include "skas.h" -#include "skas_ptrace.h" +#include "os.h" +#include "mem_user.h" +#include "ptrace_user.h" #include "registers.h" +#include "skas_ptrace.h" static int ptrace_child(void *arg) { @@ -44,26 +32,33 @@ static int ptrace_child(void *arg) int sc_result; change_sig(SIGWINCH, 0); - if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ + if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) { perror("ptrace"); os_kill_process(pid, 0); } kill(pid, SIGSTOP); - /*This syscall will be intercepted by the parent. Don't call more than - * once, please.*/ + /* + * This syscall will be intercepted by the parent. Don't call more than + * once, please. + */ sc_result = os_getpid(); if (sc_result == pid) - ret = 1; /*Nothing modified by the parent, we are running - normally.*/ + /* Nothing modified by the parent, we are running normally. */ + ret = 1; else if (sc_result == ppid) - ret = 0; /*Expected in check_ptrace and check_sysemu when they - succeed in modifying the stack frame*/ + /* + * Expected in check_ptrace and check_sysemu when they succeed + * in modifying the stack frame + */ + ret = 0; else - ret = 2; /*Serious trouble! This could be caused by a bug in - host 2.6 SKAS3/2.6 patch before release -V6, together - with a bug in the UML code itself.*/ + /* Serious trouble! This could be caused by a bug in host 2.6 + * SKAS3/2.6 patch before release -V6, together with a bug in + * the UML code itself. + */ + ret = 2; _exit(ret); } @@ -104,16 +99,18 @@ static int start_ptraced_child(void **stack_out) stack = mmap(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if(stack == MAP_FAILED) + if (stack == MAP_FAILED) fatal_perror("check_ptrace : mmap failed"); + sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); - if(pid < 0) + if (pid < 0) fatal_perror("start_ptraced_child : clone failed"); + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0) + if (n < 0) fatal_perror("check_ptrace : clone failed"); - if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) + if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) fatal("check_ptrace : expected SIGSTOP, got status = %d", status); @@ -132,10 +129,10 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, { int status, n, ret = 0; - if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) + if (ptrace(PTRACE_CONT, pid, 0, 0) < 0) fatal_perror("stop_ptraced_child : ptrace failed"); CATCH_EINTR(n = waitpid(pid, &status, 0)); - if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { + if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { int exit_with = WEXITSTATUS(status); if (exit_with == 2) non_fatal("check_ptrace : child exited with status 2. " @@ -148,7 +145,7 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, ret = -1; } - if(munmap(stack, UM_KERN_PAGE_SIZE) < 0) + if (munmap(stack, UM_KERN_PAGE_SIZE) < 0) fatal_perror("check_ptrace : munmap failed"); return ret; } @@ -209,26 +206,26 @@ static void __init check_sysemu(void) sysemu_supported = 0; pid = start_ptraced_child(&stack); - if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) + if (ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) goto fail; CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if (n < 0) fatal_perror("check_sysemu : wait failed"); - if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) + if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) fatal("check_sysemu : expected SIGTRAP, got status = %d", status); - if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) + if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) fatal_perror("check_sysemu : PTRACE_GETREGS failed"); - if(PT_SYSCALL_NR(regs) != __NR_getpid){ + if (PT_SYSCALL_NR(regs) != __NR_getpid) { non_fatal("check_sysemu got system call number %d, " "expected %d...", PT_SYSCALL_NR(regs), __NR_getpid); goto fail; } n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); - if(n < 0){ + if (n < 0) { non_fatal("check_sysemu : failed to modify system call " "return"); goto fail; @@ -244,30 +241,31 @@ static void __init check_sysemu(void) non_fatal("Checking advanced syscall emulation patch for ptrace..."); pid = start_ptraced_child(&stack); - if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, + if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *) PTRACE_O_TRACESYSGOOD) < 0)) fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed"); - while(1){ + while (1) { count++; - if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) + if (ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) goto fail; CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0) + if (n < 0) fatal_perror("check_ptrace : wait failed"); - if(WIFSTOPPED(status) && (WSTOPSIG(status) == (SIGTRAP|0x80))){ + if (WIFSTOPPED(status) && + (WSTOPSIG(status) == (SIGTRAP|0x80))) { if (!count) fatal("check_ptrace : SYSEMU_SINGLESTEP " "doesn't singlestep"); n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); - if(n < 0) + if (n < 0) fatal_perror("check_sysemu : failed to modify " "system call return"); break; } - else if(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) + else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) count++; else fatal("check_ptrace : expected SIGTRAP or " @@ -279,7 +277,7 @@ static void __init check_sysemu(void) sysemu_supported = 2; non_fatal("OK\n"); - if ( !force_sysemu_disabled ) + if (!force_sysemu_disabled) set_using_sysemu(sysemu_supported); return; @@ -297,29 +295,29 @@ static void __init check_ptrace(void) non_fatal("Checking that ptrace can change system call numbers..."); pid = start_ptraced_child(&stack); - if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, + if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *) PTRACE_O_TRACESYSGOOD) < 0)) fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed"); - while(1){ - if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) + while (1) { + if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) fatal_perror("check_ptrace : ptrace failed"); CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0) + if (n < 0) fatal_perror("check_ptrace : wait failed"); - if(!WIFSTOPPED(status) || + if (!WIFSTOPPED(status) || (WSTOPSIG(status) != (SIGTRAP | 0x80))) fatal("check_ptrace : expected (SIGTRAP|0x80), " "got status = %d", status); syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET, 0); - if(syscall == __NR_getpid){ + if (syscall == __NR_getpid) { n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, __NR_getppid); - if(n < 0) + if (n < 0) fatal_perror("check_ptrace : failed to modify " "system call"); break; @@ -337,18 +335,18 @@ static void __init check_coredump_limit(void) struct rlimit lim; int err = getrlimit(RLIMIT_CORE, &lim); - if(err){ + if (err) { perror("Getting core dump limit"); return; } printf("Core dump limits :\n\tsoft - "); - if(lim.rlim_cur == RLIM_INFINITY) + if (lim.rlim_cur == RLIM_INFINITY) printf("NONE\n"); else printf("%lu\n", lim.rlim_cur); printf("\thard - "); - if(lim.rlim_max == RLIM_INFINITY) + if (lim.rlim_max == RLIM_INFINITY) printf("NONE\n"); else printf("%lu\n", lim.rlim_max); } @@ -414,7 +412,7 @@ static inline void check_skas3_ptrace_faultinfo(void) n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); if (n < 0) { ptrace_faultinfo = 0; - if(errno == EIO) + if (errno == EIO) non_fatal("not found\n"); else perror("not found"); @@ -446,7 +444,7 @@ static inline void check_skas3_ptrace_ldt(void) n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op); if (n < 0) { - if(errno == EIO) + if (errno == EIO) non_fatal("not found\n"); else { perror("not found"); @@ -454,7 +452,7 @@ static inline void check_skas3_ptrace_ldt(void) ptrace_ldt = 0; } else { - if(ptrace_ldt) + if (ptrace_ldt) non_fatal("found\n"); else non_fatal("found, but use is disabled\n"); @@ -477,12 +475,9 @@ static inline void check_skas3_proc_mm(void) proc_mm = 0; perror("not found"); } - else { - if (!proc_mm) - non_fatal("found but disabled on command line\n"); - else - non_fatal("found\n"); - } + else if (!proc_mm) + non_fatal("found but disabled on command line\n"); + else non_fatal("found\n"); } int can_do_skas(void) @@ -493,7 +488,7 @@ int can_do_skas(void) check_skas3_ptrace_faultinfo(); check_skas3_ptrace_ldt(); - if(!proc_mm || !ptrace_faultinfo || !ptrace_ldt) + if (!proc_mm || !ptrace_faultinfo || !ptrace_ldt) skas_needs_stub = 1; return 1; @@ -508,25 +503,25 @@ int __init parse_iomem(char *str, int *add) driver = str; file = strchr(str,','); - if(file == NULL){ + if (file == NULL) { printf("parse_iomem : failed to parse iomem\n"); goto out; } *file = '\0'; file++; fd = open(file, O_RDWR, 0); - if(fd < 0){ + if (fd < 0) { os_print_error(fd, "parse_iomem - Couldn't open io file"); goto out; } - if(fstat64(fd, &buf) < 0){ + if (fstat64(fd, &buf) < 0) { perror("parse_iomem - cannot stat_fd file"); goto out_close; } new = malloc(sizeof(*new)); - if(new == NULL){ + if (new == NULL) { perror("Couldn't allocate iomem_region struct"); goto out_close; } |