Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+12 −10
Original line number Original line Diff line number Diff line
@@ -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)
	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)
		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)
		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)
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)
	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)
		}
		}
	}
	}
	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)


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;