lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20080104180036.GA6974@c2.user-mode-linux.org>
Date:	Fri, 4 Jan 2008 13:00:36 -0500
From:	Jeff Dike <jdike@...toit.com>
To:	Miklos Szeredi <miklos@...redi.hu>
Cc:	akpm@...ux-foundation.org, linux-kernel@...r.kernel.org,
	user-mode-linux-devel@...ts.sourceforge.net
Subject: Re: [uml-devel] UML woes in 2.6.24-rc6-mm1

On Thu, Jan 03, 2008 at 01:55:57PM +0100, Miklos Szeredi wrote:
> This is the one: uml-runtime-detection-of-host-vmsplit-on-i386.patch
> 
> The relevant log line (both for successful and failed boots):
> 
> Locating the top of the address space ... 0xffc00000

Thanks for narrowing it down.  It turns out I can reproduce it with a
defconfig, but it reproduces much more easily with your config for
some reason.

Anyhow, try the patch below.

				Jeff

-- 
Work email - jdike at linux dot intel dot com

Index: linux-2.6.22/arch/um/include/as-layout.h
===================================================================
--- linux-2.6.22.orig/arch/um/include/as-layout.h	2008-01-01 17:32:04.000000000 -0500
+++ linux-2.6.22/arch/um/include/as-layout.h	2008-01-04 12:27:21.000000000 -0500
@@ -57,6 +57,8 @@ extern unsigned long _stext, _etext, _sd
 extern unsigned long _unprotected_end;
 extern unsigned long brk_start;
 
+extern unsigned long host_task_size;
+
 extern int linux_main(int argc, char **argv);
 
 extern void (*sig_info[])(int, struct uml_pt_regs *);
Index: linux-2.6.22/arch/um/kernel/exec.c
===================================================================
--- linux-2.6.22.orig/arch/um/kernel/exec.c	2008-01-04 12:12:32.000000000 -0500
+++ linux-2.6.22/arch/um/kernel/exec.c	2008-01-04 12:27:48.000000000 -0500
@@ -25,7 +25,7 @@ void flush_thread(void)
 
 	ret = unmap(&current->mm->context.id, 0, STUB_START, 0, &data);
 	ret = ret || unmap(&current->mm->context.id, STUB_END,
-			   TASK_SIZE - STUB_END, 1, &data);
+			   host_task_size - STUB_END, 1, &data);
 	if (ret) {
 		printk(KERN_ERR "flush_thread - clearing address space failed, "
 		       "err = %d\n", ret);
Index: linux-2.6.22/arch/um/kernel/um_arch.c
===================================================================
--- linux-2.6.22.orig/arch/um/kernel/um_arch.c	2008-01-04 12:11:33.000000000 -0500
+++ linux-2.6.22/arch/um/kernel/um_arch.c	2008-01-04 12:53:53.000000000 -0500
@@ -244,6 +244,8 @@ static struct notifier_block panic_exit_
 unsigned long task_size;
 EXPORT_SYMBOL(task_size);
 
+unsigned long host_task_size;
+
 unsigned long brk_start;
 unsigned long end_iomem;
 EXPORT_SYMBOL(end_iomem);
@@ -270,11 +272,12 @@ int __init linux_main(int argc, char **a
 	if (have_root == 0)
 		add_arg(DEFAULT_COMMAND_LINE);
 
+	host_task_size = os_get_task_size();
 	/*
 	 * TASK_SIZE needs to be PGDIR_SIZE aligned or else exit_mmap craps
 	 * out
 	 */
-	task_size = os_get_task_size(PGDIR_SHIFT);
+	task_size = host_task_size & PGDIR_MASK;
 
 	/* OS sanity checks that need to happen before the kernel runs */
 	os_early_checks();
Index: linux-2.6.22/arch/um/os-Linux/sys-i386/task_size.c
===================================================================
--- linux-2.6.22.orig/arch/um/os-Linux/sys-i386/task_size.c	2008-01-01 17:32:04.000000000 -0500
+++ linux-2.6.22/arch/um/os-Linux/sys-i386/task_size.c	2008-01-04 12:56:20.000000000 -0500
@@ -49,7 +49,7 @@ static int page_ok(unsigned long page)
 		ok = 1;
 		goto out;
 	} else if (mprotect(address, UM_KERN_PAGE_SIZE,
-			  PROT_READ | PROT_WRITE) != 0)
+			    PROT_READ | PROT_WRITE) != 0)
 		goto out;
 
 	if (setjmp(buf) == 0) {
@@ -63,13 +63,20 @@ static int page_ok(unsigned long page)
 	return ok;
 }
 
-unsigned long os_get_task_size(int shift)
+unsigned long os_get_task_size(void)
 {
 	struct sigaction sa, old;
-	unsigned long bottom = 0 >> shift;
-	unsigned long top = ~0UL >> shift;
+	unsigned long bottom = 0;
+	/*
+	 * A 32-bit UML on a 64-bit host gets confused about the VDSO at
+	 * 0xffffe000.  It is mapped, is readable, can be reprotected writeable
+	 * and written.  However, exec discovers later that it can't be
+	 * unmapped.  So, just set the highest address to be checked to just
+	 * below it.  This might waste some address space on 4G/4G 32-bit
+	 * hosts, but shouldn't hurt otherwise.
+	 */
+	unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT;
 	unsigned long test;
-	int to_page = shift - UM_KERN_PAGE_SHIFT;
 
 	printf("Locating the top of the address space ... ");
 	fflush(stdout);
@@ -83,18 +90,19 @@ unsigned long os_get_task_size(int shift
 	sa.sa_flags = SA_NODEFER;
 	sigaction(SIGSEGV, &sa, &old);
 
-	if (!page_ok(bottom << to_page)) {
-		fprintf(stderr, "Address 0x%x no good?\n", bottom << shift);
+	if (!page_ok(bottom)) {
+		fprintf(stderr, "Address 0x%x no good?\n",
+			bottom << UM_KERN_PAGE_SHIFT);
 		exit(1);
 	}
 
 	/* This could happen with a 4G/4G split */
-	if (page_ok(top << to_page))
+	if (page_ok(top))
 		goto out;
 
 	do {
 		test = bottom + (top - bottom) / 2;
-		if (page_ok(test << to_page))
+		if (page_ok(test))
 			bottom = test;
 		else
 			top = test;
@@ -104,7 +112,9 @@ out:
 	/* Restore the old SIGSEGV handling */
 	sigaction(SIGSEGV, &old, NULL);
 
-	printf("0x%x\n", top << shift);
+	top <<= UM_KERN_PAGE_SHIFT;
+	printf("0x%x\n", top);
 	fflush(stdout);
-	return top << shift;
+
+	return top;
 }
Index: linux-2.6.22/arch/um/include/os.h
===================================================================
--- linux-2.6.22.orig/arch/um/include/os.h	2008-01-04 12:55:38.000000000 -0500
+++ linux-2.6.22/arch/um/include/os.h	2008-01-04 12:55:48.000000000 -0500
@@ -299,6 +299,6 @@ extern int os_arch_prctl(int pid, int co
 extern int get_pty(void);
 
 /* sys-$ARCH/task_size.c */
-extern unsigned long os_get_task_size(int shift);
+extern unsigned long os_get_task_size(void);
 
 #endif
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ