Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

um: mm: check more comprehensively for stub changes

If userspace tries to change the stub, we need to kill it,
because otherwise it can escape the virtual machine. In a
few cases the stub checks weren't good, e.g. if userspace
just tries to

mmap(0x100000 - 0x1000, 0x3000, ...)

it could succeed to get a new private/anonymous mapping
replacing the stubs. Fix this by checking everywhere, and
checking for _overlap_, not just direct changes.

Cc: stable@vger.kernel.org
Fixes: 3963333fe676 ("uml: cover stubs with a VMA")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Richard Weinberger <richard@nod.at>

authored by

Johannes Berg and committed by
Richard Weinberger
47da2976 e1e22d0d

+11 -1
+11 -1
arch/um/kernel/tlb.c
··· 125 125 struct host_vm_op *last; 126 126 int fd = -1, ret = 0; 127 127 128 + if (virt + len > STUB_START && virt < STUB_END) 129 + return -EINVAL; 130 + 128 131 if (hvc->userspace) 129 132 fd = phys_mapping(phys, &offset); 130 133 else ··· 165 162 struct host_vm_op *last; 166 163 int ret = 0; 167 164 168 - if ((addr >= STUB_START) && (addr < STUB_END)) 165 + if (addr + len > STUB_START && addr < STUB_END) 169 166 return -EINVAL; 170 167 171 168 if (hvc->index != 0) { ··· 194 191 { 195 192 struct host_vm_op *last; 196 193 int ret = 0; 194 + 195 + if (addr + len > STUB_START && addr < STUB_END) 196 + return -EINVAL; 197 197 198 198 if (hvc->index != 0) { 199 199 last = &hvc->ops[hvc->index - 1]; ··· 478 472 struct mm_id *mm_id; 479 473 480 474 address &= PAGE_MASK; 475 + 476 + if (address >= STUB_START && address < STUB_END) 477 + goto kill; 478 + 481 479 pgd = pgd_offset(mm, address); 482 480 if (!pgd_present(*pgd)) 483 481 goto kill;