From: Paolo 'Blaisorblade' Giarrusso 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 Signed-off-by: Andrew Morton --- 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 _