Commit 960b6b4e authored by Paolo \'Blaisorblade\' Giarrusso's avatar Paolo \'Blaisorblade\' Giarrusso Committed by Linus Torvalds

[PATCH] uml: add startup check for mmap(...PROT_EXEC...) from /tmp.

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: default avatarPaolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 1eae58a2
...@@ -67,6 +67,7 @@ extern void map_memory(unsigned long virt, unsigned long phys, ...@@ -67,6 +67,7 @@ extern void map_memory(unsigned long virt, unsigned long phys,
extern int protect_memory(unsigned long addr, unsigned long len, extern int protect_memory(unsigned long addr, unsigned long len,
int r, int w, int x, int must_succeed); int r, int w, int x, int must_succeed);
extern unsigned long get_kmem_end(void); extern unsigned long get_kmem_end(void);
extern void check_tmpexec(void);
#endif #endif
......
...@@ -83,6 +83,26 @@ static int create_tmp_file(unsigned long len) ...@@ -83,6 +83,26 @@ static int create_tmp_file(unsigned long len)
return(fd); 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; static int have_devanon = 0;
void check_devanon(void) void check_devanon(void)
...@@ -111,7 +131,7 @@ static int create_anon_file(unsigned long len) ...@@ -111,7 +131,7 @@ static int create_anon_file(unsigned long len)
exit(1); 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){ if(addr == MAP_FAILED){
os_print_error((int) addr, "mapping physmem file"); os_print_error((int) addr, "mapping physmem file");
exit(1); exit(1);
......
...@@ -321,6 +321,11 @@ int linux_main(int argc, char **argv) ...@@ -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, uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
&host_task_size, &task_size); &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); brk_start = (unsigned long) sbrk(0);
CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start); CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
/* Increase physical memory size for exec-shield users /* Increase physical memory size for exec-shield users
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment