Commit 51694948 authored by Paolo 'Blaisorblade' Giarrusso's avatar Paolo 'Blaisorblade' Giarrusso Committed by Linus Torvalds

[PATCH] uml: fix random segfaults at bootup

Don't use printk() where "current_thread_info()" is crap.

Until when we switch to running on init_stack, current_thread_info() evaluates
to crap. Printk uses "current" at times (in detail, &current is evaluated with
CONFIG_DEBUG_SPINLOCK to check the spinlock owner task).

And this leads to random segmentation faults.

Exactly, what happens is that &current = *(current_thread_info()), i.e. round
down $esp and dereference the value. I.e. access the stack below $esp, which
causes SIGSEGV on a VM_GROWSDOWN vma (see arch/i386/mm/fault.c).
Signed-off-by: default avatarPaolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 3603bc8d
...@@ -116,16 +116,16 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, ...@@ -116,16 +116,16 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode,
if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
int exit_with = WEXITSTATUS(status); int exit_with = WEXITSTATUS(status);
if (exit_with == 2) if (exit_with == 2)
printk("check_ptrace : child exited with status 2. " printf("check_ptrace : child exited with status 2. "
"Serious trouble happening! Try updating your " "Serious trouble happening! Try updating your "
"host skas patch!\nDisabling SYSEMU support."); "host skas patch!\nDisabling SYSEMU support.");
printk("check_ptrace : child exited with exitcode %d, while " printf("check_ptrace : child exited with exitcode %d, while "
"expecting %d; status 0x%x", exit_with, "expecting %d; status 0x%x", exit_with,
exitcode, status); exitcode, status);
if (mustpanic) if (mustpanic)
panic("\n"); panic("\n");
else else
printk("\n"); printf("\n");
ret = -1; ret = -1;
} }
...@@ -183,7 +183,7 @@ static void __init check_sysemu(void) ...@@ -183,7 +183,7 @@ static void __init check_sysemu(void)
void *stack; void *stack;
int pid, n, status, count=0; int pid, n, status, count=0;
printk("Checking syscall emulation patch for ptrace..."); printf("Checking syscall emulation patch for ptrace...");
sysemu_supported = 0; sysemu_supported = 0;
pid = start_ptraced_child(&stack); pid = start_ptraced_child(&stack);
...@@ -207,10 +207,10 @@ static void __init check_sysemu(void) ...@@ -207,10 +207,10 @@ static void __init check_sysemu(void)
goto fail_stopped; goto fail_stopped;
sysemu_supported = 1; sysemu_supported = 1;
printk("OK\n"); printf("OK\n");
set_using_sysemu(!force_sysemu_disabled); set_using_sysemu(!force_sysemu_disabled);
printk("Checking advanced syscall emulation patch for ptrace..."); printf("Checking advanced syscall emulation patch for ptrace...");
pid = start_ptraced_child(&stack); pid = start_ptraced_child(&stack);
if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0, if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
...@@ -246,7 +246,7 @@ static void __init check_sysemu(void) ...@@ -246,7 +246,7 @@ static void __init check_sysemu(void)
goto fail_stopped; goto fail_stopped;
sysemu_supported = 2; sysemu_supported = 2;
printk("OK\n"); printf("OK\n");
if ( !force_sysemu_disabled ) if ( !force_sysemu_disabled )
set_using_sysemu(sysemu_supported); set_using_sysemu(sysemu_supported);
...@@ -255,7 +255,7 @@ static void __init check_sysemu(void) ...@@ -255,7 +255,7 @@ static void __init check_sysemu(void)
fail: fail:
stop_ptraced_child(pid, stack, 1, 0); stop_ptraced_child(pid, stack, 1, 0);
fail_stopped: fail_stopped:
printk("missing\n"); printf("missing\n");
} }
static void __init check_ptrace(void) static void __init check_ptrace(void)
...@@ -263,7 +263,7 @@ static void __init check_ptrace(void) ...@@ -263,7 +263,7 @@ static void __init check_ptrace(void)
void *stack; void *stack;
int pid, syscall, n, status; int pid, syscall, n, status;
printk("Checking that ptrace can change system call numbers..."); printf("Checking that ptrace can change system call numbers...");
pid = start_ptraced_child(&stack); pid = start_ptraced_child(&stack);
if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
...@@ -292,7 +292,7 @@ static void __init check_ptrace(void) ...@@ -292,7 +292,7 @@ static void __init check_ptrace(void)
} }
} }
stop_ptraced_child(pid, stack, 0, 1); stop_ptraced_child(pid, stack, 0, 1);
printk("OK\n"); printf("OK\n");
check_sysemu(); check_sysemu();
} }
...@@ -472,6 +472,8 @@ int can_do_skas(void) ...@@ -472,6 +472,8 @@ int can_do_skas(void)
int have_devanon = 0; int have_devanon = 0;
/* Runs on boot kernel stack - already safe to use printk. */
void check_devanon(void) void check_devanon(void)
{ {
int fd; int fd;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment