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. Signed-off-by: Paolo 'Blaisorblade' Giarrusso --- um-linux-2.4.27-paolo/arch/um/include/mem_user.h | 1 + um-linux-2.4.27-paolo/arch/um/kernel/mem_user.c | 22 +++++++++++++++++++++- um-linux-2.4.27-paolo/arch/um/kernel/um_arch.c | 5 +++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff -puN arch/um/include/mem_user.h~tmp-exec arch/um/include/mem_user.h --- um-linux-2.4.27/arch/um/include/mem_user.h~tmp-exec 2005-04-15 11:13:04.000000000 +0200 +++ um-linux-2.4.27-paolo/arch/um/include/mem_user.h 2005-04-15 11:13:04.000000000 +0200 @@ -66,6 +66,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~tmp-exec arch/um/kernel/mem_user.c --- um-linux-2.4.27/arch/um/kernel/mem_user.c~tmp-exec 2005-04-15 11:13:04.000000000 +0200 +++ um-linux-2.4.27-paolo/arch/um/kernel/mem_user.c 2005-04-15 11:13:04.000000000 +0200 @@ -84,6 +84,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(void) { int fd; @@ -110,7 +130,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~tmp-exec arch/um/kernel/um_arch.c --- um-linux-2.4.27/arch/um/kernel/um_arch.c~tmp-exec 2005-04-15 11:13:04.000000000 +0200 +++ um-linux-2.4.27-paolo/arch/um/kernel/um_arch.c 2005-04-15 11:13:04.000000000 +0200 @@ -319,6 +319,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 _