
From: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>

This adds a check that /tmp is not mounted noexec.  UML needs to be able to do
PROT_EXEC mmaps of temp files.  Previously, a noexec /tmp would cause an early
mysterious UML crash.  (Actually, not /tmp but $TMP, which often is the same).

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/um/include/mem_user.h |    1 +
 25-akpm/arch/um/kernel/mem_user.c  |   22 +++++++++++++++++++++-
 25-akpm/arch/um/kernel/um_arch.c   |    5 +++++
 3 files changed, 27 insertions(+), 1 deletion(-)

diff -puN arch/um/include/mem_user.h~uml-add-startup-check-for-mmapprot_exec-from-tmp arch/um/include/mem_user.h
--- 25/arch/um/include/mem_user.h~uml-add-startup-check-for-mmapprot_exec-from-tmp	2004-11-03 19:27:48.109476744 -0800
+++ 25-akpm/arch/um/include/mem_user.h	2004-11-03 19:27:48.116475680 -0800
@@ -67,6 +67,7 @@ extern void map_memory(unsigned long vir
 extern int protect_memory(unsigned long addr, unsigned long len, 
 			  int r, int w, int x, int must_succeed);
 extern unsigned long get_kmem_end(void);
+extern void check_tmpexec(void);
 
 #endif
 
diff -puN arch/um/kernel/mem_user.c~uml-add-startup-check-for-mmapprot_exec-from-tmp arch/um/kernel/mem_user.c
--- 25/arch/um/kernel/mem_user.c~uml-add-startup-check-for-mmapprot_exec-from-tmp	2004-11-03 19:27:48.110476592 -0800
+++ 25-akpm/arch/um/kernel/mem_user.c	2004-11-03 19:27:48.116475680 -0800
@@ -83,6 +83,26 @@ static int create_tmp_file(unsigned long
 	return(fd);
 }
 
+void check_tmpexec(void)
+{
+	void *addr;
+	int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE);
+
+	addr = mmap(NULL, UM_KERN_PAGE_SIZE,
+		    PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);
+	printf("Checking PROT_EXEC mmap in /tmp...");
+	fflush(stdout);
+	if(addr == MAP_FAILED){
+		err = errno;
+		perror("failed");
+		if(err == EPERM)
+			printf("/tmp must be not mounted noexec\n");
+		exit(1);
+	}
+	printf("OK\n");
+	munmap(addr, UM_KERN_PAGE_SIZE);
+}
+
 static int have_devanon = 0;
 
 void check_devanon(void)
@@ -111,7 +131,7 @@ static int create_anon_file(unsigned lon
 		exit(1);
 	}
 
-	addr = mmap(NULL, len, PROT_READ | PROT_WRITE , MAP_PRIVATE, fd, 0);
+	addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
 	if(addr == MAP_FAILED){
 		os_print_error((int) addr, "mapping physmem file");
 		exit(1);
diff -puN arch/um/kernel/um_arch.c~uml-add-startup-check-for-mmapprot_exec-from-tmp arch/um/kernel/um_arch.c
--- 25/arch/um/kernel/um_arch.c~uml-add-startup-check-for-mmapprot_exec-from-tmp	2004-11-03 19:27:48.112476288 -0800
+++ 25-akpm/arch/um/kernel/um_arch.c	2004-11-03 19:27:48.117475528 -0800
@@ -321,6 +321,11 @@ int linux_main(int argc, char **argv)
 	uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
 				     &host_task_size, &task_size);
 
+	/* Need to check this early because mmapping happens before the
+	 * kernel is running.
+	 */
+	check_tmpexec();
+
 	brk_start = (unsigned long) sbrk(0);
 	CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
 	/* Increase physical memory size for exec-shield users
_
