[mips] Correctly bounds check virt_addr_valid (Closes: #929366)
This commit is contained in:
parent
3b44df1499
commit
cbcfb20ce0
|
@ -20,6 +20,9 @@ linux (4.19.37-4) UNRELEASED; urgency=medium
|
||||||
(CVE-2019-11833)
|
(CVE-2019-11833)
|
||||||
* Bluetooth: hidp: fix buffer overflow (CVE-2019-11884)
|
* Bluetooth: hidp: fix buffer overflow (CVE-2019-11884)
|
||||||
|
|
||||||
|
[ Aurelien Jarno ]
|
||||||
|
* [mips] Correctly bounds check virt_addr_valid (Closes: #929366)
|
||||||
|
|
||||||
-- Ben Hutchings <ben@decadent.org.uk> Sun, 19 May 2019 00:04:16 +0100
|
-- Ben Hutchings <ben@decadent.org.uk> Sun, 19 May 2019 00:04:16 +0100
|
||||||
|
|
||||||
linux (4.19.37-3) unstable; urgency=medium
|
linux (4.19.37-3) unstable; urgency=medium
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
From: Paul Burton <paul.burton@mips.com>
|
||||||
|
Date: Tue, 28 May 2019 17:05:03 +0000
|
||||||
|
Subject: MIPS: Bounds check virt_addr_valid
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
Origin: https://git.kernel.org/linus/074a1e1167afd82c26f6d03a9a8b997d564bb241
|
||||||
|
|
||||||
|
The virt_addr_valid() function is meant to return true iff
|
||||||
|
virt_to_page() will return a valid struct page reference. This is true
|
||||||
|
iff the address provided is found within the unmapped address range
|
||||||
|
between PAGE_OFFSET & MAP_BASE, but we don't currently check for that
|
||||||
|
condition. Instead we simply mask the address to obtain what will be a
|
||||||
|
physical address if the virtual address is indeed in the desired range,
|
||||||
|
shift it to form a PFN & then call pfn_valid(). This can incorrectly
|
||||||
|
return true if called with a virtual address which, after masking,
|
||||||
|
happens to form a physical address corresponding to a valid PFN.
|
||||||
|
|
||||||
|
For example we may vmalloc an address in the kernel mapped region
|
||||||
|
starting a MAP_BASE & obtain the virtual address:
|
||||||
|
|
||||||
|
addr = 0xc000000000002000
|
||||||
|
|
||||||
|
When masked by virt_to_phys(), which uses __pa() & in turn CPHYSADDR(),
|
||||||
|
we obtain the following (bogus) physical address:
|
||||||
|
|
||||||
|
addr = 0x2000
|
||||||
|
|
||||||
|
In a common system with PHYS_OFFSET=0 this will correspond to a valid
|
||||||
|
struct page which should really be accessed by virtual address
|
||||||
|
PAGE_OFFSET+0x2000, causing virt_addr_valid() to incorrectly return 1
|
||||||
|
indicating that the original address corresponds to a struct page.
|
||||||
|
|
||||||
|
This is equivalent to the ARM64 change made in commit ca219452c6b8
|
||||||
|
("arm64: Correctly bounds check virt_addr_valid").
|
||||||
|
|
||||||
|
This fixes fallout when hardened usercopy is enabled caused by the
|
||||||
|
related commit 517e1fbeb65f ("mm/usercopy: Drop extra
|
||||||
|
is_vmalloc_or_module() check") which removed a check for the vmalloc
|
||||||
|
range that was present from the introduction of the hardened usercopy
|
||||||
|
feature.
|
||||||
|
|
||||||
|
Signed-off-by: Paul Burton <paul.burton@mips.com>
|
||||||
|
References: ca219452c6b8 ("arm64: Correctly bounds check virt_addr_valid")
|
||||||
|
References: 517e1fbeb65f ("mm/usercopy: Drop extra is_vmalloc_or_module() check")
|
||||||
|
Reported-by: Julien Cristau <jcristau@debian.org>
|
||||||
|
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||||
|
Tested-by: YunQiang Su <ysu@wavecomp.com>
|
||||||
|
URL: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=929366
|
||||||
|
Cc: stable@vger.kernel.org # v4.12+
|
||||||
|
Cc: linux-mips@vger.kernel.org
|
||||||
|
Cc: Yunqiang Su <ysu@wavecomp.com>
|
||||||
|
---
|
||||||
|
arch/mips/mm/mmap.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
|
||||||
|
index 2f616ebeb7e0..7755a1fad05a 100644
|
||||||
|
--- a/arch/mips/mm/mmap.c
|
||||||
|
+++ b/arch/mips/mm/mmap.c
|
||||||
|
@@ -203,6 +203,11 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
|
||||||
|
|
||||||
|
int __virt_addr_valid(const volatile void *kaddr)
|
||||||
|
{
|
||||||
|
+ unsigned long vaddr = (unsigned long)vaddr;
|
||||||
|
+
|
||||||
|
+ if ((vaddr < PAGE_OFFSET) || (vaddr >= MAP_BASE))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(__virt_addr_valid);
|
||||||
|
--
|
||||||
|
2.20.1
|
||||||
|
|
|
@ -82,6 +82,7 @@ bugfix/arm64/arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch
|
||||||
bugfix/mips/MIPS-Loongson-Introduce-and-use-loongson_llsc_mb.patch
|
bugfix/mips/MIPS-Loongson-Introduce-and-use-loongson_llsc_mb.patch
|
||||||
bugfix/powerpc/powerpc-vdso-make-vdso32-installation-conditional-in.patch
|
bugfix/powerpc/powerpc-vdso-make-vdso32-installation-conditional-in.patch
|
||||||
bugfix/mips/MIPS-scall64-o32-Fix-indirect-syscall-number-load.patch
|
bugfix/mips/MIPS-scall64-o32-Fix-indirect-syscall-number-load.patch
|
||||||
|
bugfix/mips/MIPS-Bounds-check-virt_addr_valid.patch
|
||||||
|
|
||||||
# Arch features
|
# Arch features
|
||||||
features/mips/MIPS-increase-MAX-PHYSMEM-BITS-on-Loongson-3-only.patch
|
features/mips/MIPS-increase-MAX-PHYSMEM-BITS-on-Loongson-3-only.patch
|
||||||
|
|
Loading…
Reference in New Issue