From 0b5aedfe0e6654ec54f35109e1929a1cf7fc4cdd Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sun, 28 Jun 2015 22:55:26 +0200 Subject: [PATCH 1/4] um: Fix out-of-tree build Commit 30b11ee9a (um: Remove copy&paste code from init.h) uncovered an issue wrt. out-of-tree builds. For out-of-tree builds, we must not rely on relative paths. Before 30b11ee9a it worked by chance as no host code included generated header files. Acked-by: Randy Dunlap Signed-off-by: Richard Weinberger --- arch/um/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/um/Makefile b/arch/um/Makefile index 098ab3333e7c..e3abe6f3156d 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -70,8 +70,8 @@ KBUILD_AFLAGS += $(ARCH_INCLUDE) USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \ $(ARCH_INCLUDE) $(MODE_INCLUDE) $(filter -I%,$(CFLAGS)) \ - -D_FILE_OFFSET_BITS=64 -idirafter include \ - -D__KERNEL__ -D__UM_HOST__ + -D_FILE_OFFSET_BITS=64 -idirafter $(srctree)/include \ + -idirafter $(obj)/include -D__KERNEL__ -D__UM_HOST__ #This will adjust *FLAGS accordingly to the platform. include $(ARCH_DIR)/Makefile-os-$(OS) From 37e81a016cc847c03ea71570fea29f12ca390bee Mon Sep 17 00:00:00 2001 From: Hans-Werner Hilse Date: Mon, 29 Jun 2015 11:50:32 +0200 Subject: [PATCH 2/4] um: Do not rely on libc to provide modify_ldt() modify_ldt() was declared as an external symbol. Despite the man page for this syscall telling that there is no wrapper in glibc, since version 2.1 there actually is, so linking to the glibc works. Since modify_ldt() is not a POSIX interface, other libc implementations do not always provide a wrapper function. Even glibc headers do not provide a corresponding declaration. So go the recommended way to call this using syscall(). Signed-off-by: Hans-Werner Hilse Signed-off-by: Richard Weinberger --- arch/x86/um/ldt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/um/ldt.c b/arch/x86/um/ldt.c index 9701a4fd7bf2..836a1eb5df43 100644 --- a/arch/x86/um/ldt.c +++ b/arch/x86/um/ldt.c @@ -12,7 +12,10 @@ #include #include -extern int modify_ldt(int func, void *ptr, unsigned long bytecount); +static inline int modify_ldt (int func, void *ptr, unsigned long bytecount) +{ + return syscall(__NR_modify_ldt, func, ptr, bytecount); +} static long write_ldt_entry(struct mm_id *mm_idp, int func, struct user_desc *desc, void **addr, int done) From 6b1873371cea13036171d03a7c1e3e59158b4505 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sun, 9 Aug 2015 21:49:07 +0200 Subject: [PATCH 3/4] um: Fix waitpid() usage in helper code If UML is executing a helper program it is using waitpid() with the __WCLONE flag to wait for the program as the helper is executed from a clone()'ed thread. While using __WCLONE is perfectly fine for clone()'ed childs it won't detect terminated childs if the helper has issued an execve(). We have to use __WALL to wait for both clone()'ed and regular childs to detect the termination before and after an execve(). Reported-and-tested-by: Thomas Meyer Signed-off-by: Richard Weinberger --- arch/um/os-Linux/helper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index e3ee4a51ef63..3f02d4232812 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -96,7 +96,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv) "ret = %d\n", -n); ret = n; } - CATCH_EINTR(waitpid(pid, NULL, __WCLONE)); + CATCH_EINTR(waitpid(pid, NULL, __WALL)); } out_free2: @@ -129,7 +129,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, return err; } if (stack_out == NULL) { - CATCH_EINTR(pid = waitpid(pid, &status, __WCLONE)); + CATCH_EINTR(pid = waitpid(pid, &status, __WALL)); if (pid < 0) { err = -errno; printk(UM_KERN_ERR "run_helper_thread - wait failed, " @@ -148,7 +148,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, int helper_wait(int pid) { int ret, status; - int wflags = __WCLONE; + int wflags = __WALL; CATCH_EINTR(ret = waitpid(pid, &status, wflags)); if (ret < 0) { From 56b88a3bf97a39d3f4f010509917b76a865a6dc8 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sun, 9 Aug 2015 22:26:33 +0200 Subject: [PATCH 4/4] um: Fix kernel mode fault condition We have to exclude memory locations <= PAGE_SIZE from the condition and let the kernel mode fault path catch it. Otherwise a kernel NULL pointer exception will be reported as a kernel user space access. Fixes: d2313084e2c (um: Catch unprotected user memory access) Signed-off-by: Richard Weinberger --- arch/um/kernel/trap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index d8a9fce6ee2e..98783dd0fa2e 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -220,7 +220,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, show_regs(container_of(regs, struct pt_regs, regs)); panic("Segfault with no mm"); } - else if (!is_user && address < TASK_SIZE) { + else if (!is_user && address > PAGE_SIZE && address < TASK_SIZE) { show_regs(container_of(regs, struct pt_regs, regs)); panic("Kernel tried to access user memory at addr 0x%lx, ip 0x%lx", address, ip);