This fixes a long standing problem that UML crashes
or locks up if a task messes with it' stub vma.

Reported-by: toralf.foers...@gmx.de
Signed-off-by: Richard Weinberger <rich...@nod.at>
---
 arch/um/kernel/tlb.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index 9472079..b33d1d1 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -12,6 +12,7 @@
 #include <mem_user.h>
 #include <os.h>
 #include <skas.h>
+#include <kern_util.h>
 
 struct host_vm_change {
        struct host_vm_op {
@@ -90,6 +91,9 @@ static int add_mmap(unsigned long virt, unsigned long phys, 
unsigned long len,
        struct host_vm_op *last;
        int fd, ret = 0;
 
+       if ((virt >= STUB_START) && (virt < STUB_END))
+               return -EINVAL;
+
        fd = phys_mapping(phys, &offset);
        if (hvc->index != 0) {
                last = &hvc->ops[hvc->index - 1];
@@ -124,6 +128,9 @@ static int add_munmap(unsigned long addr, unsigned long len,
        struct host_vm_op *last;
        int ret = 0;
 
+       if ((addr >= STUB_START) && (addr < STUB_END))
+               return -EINVAL;
+
        if (hvc->index != 0) {
                last = &hvc->ops[hvc->index - 1];
                if ((last->type == MUNMAP) &&
@@ -283,8 +290,10 @@ void fix_range_common(struct mm_struct *mm, unsigned long 
start_addr,
        /* This is not an else because ret is modified above */
        if (ret) {
                printk(KERN_ERR "fix_range_common: failed, killing current "
-                      "process\n");
-               force_sig(SIGKILL, current);
+                      "process: %d\n", task_tgid_vnr(current));
+               /* We are under mmap_sem, release it such that current can 
terminate */
+               up_write(&current->mm->mmap_sem);
+               fatal_sigsegv();
        }
 }
 
@@ -409,6 +418,9 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned 
long address)
                w = 0;
        }
 
+       if ((address >= STUB_START) && (address < STUB_END))
+               goto kill;
+
        mm_id = &mm->context.id;
        prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) |
                (x ? UM_PROT_EXEC : 0));
@@ -435,7 +447,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned 
long address)
 
 kill:
        printk(KERN_ERR "Failed to flush page for address 0x%lx\n", address);
-       force_sig(SIGKILL, current);
+       fatal_sigsegv();
 }
 
 pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
-- 
1.8.1.4


------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.  Get 
unparalleled scalability from the best Selenium testing platform available.
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

Reply via email to