[OpenWrt-Devel] [PATCH] kernel: MIPS: math-emu Write-protect delay slot emulation pages

Yousong Zhou yszhou4tech at gmail.com
Sun Dec 23 22:53:49 EST 2018


On Sat, 22 Dec 2018 at 01:21, Kevin 'ldir' Darbyshire-Bryant
<ldir at darbyshire-bryant.me.uk> wrote:
>
> Backport https://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git/commit/?id=adcc81f148d733b7e8e641300c5590a2cdc13bf3
>
> "Mapping the delay slot emulation page as both writeable & executable
> presents a security risk, in that if an exploit can write to & jump into
> the page then it can be used as an easy way to execute arbitrary code.
>
> Prevent this by mapping the page read-only for userland, and using
> access_process_vm() with the FOLL_FORCE flag to write to it from
> mips_dsemul().
>
> This will likely be less efficient due to copy_to_user_page() performing
> cache maintenance on a whole page, rather than a single line as in the
> previous use of flush_cache_sigtramp(). However this delay slot
> emulation code ought not to be running in any performance critical paths
> anyway so this isn't really a problem, and we can probably do better in
> copy_to_user_page() anyway in future.
>
> A major advantage of this approach is that the fix is small & simple to
> backport to stable kernels.
>
> Reported-by: Andy Lutomirski <luto at kernel.org>
> Signed-off-by: Paul Burton <paul.burton at mips.com>
> Fixes: 432c6bacbd0c ("MIPS: Use per-mm page to execute branch delay slot instructions")"
>
> Without patch:
>
> cat /proc/self/maps
> 00400000-0047a000 r-xp 00000000 1f:03 1823       /bin/busybox
> 00489000-0048a000 r-xp 00079000 1f:03 1823       /bin/busybox
> 0048a000-0048b000 rwxp 0007a000 1f:03 1823       /bin/busybox
> 77ec8000-77eed000 r-xp 00000000 1f:03 2296       /lib/libgcc_s.so.1
> 77eed000-77eee000 rwxp 00015000 1f:03 2296       /lib/libgcc_s.so.1
> 77eee000-77f81000 r-xp 00000000 1f:03 2470       /lib/libc.so
> 77f90000-77f92000 rwxp 00092000 1f:03 2470       /lib/libc.so
> 77f92000-77f94000 rwxp 00000000 00:00 0
> 7f946000-7f967000 rw-p 00000000 00:00 0          [stack]
> 7fefb000-7fefc000 rwxp 00000000 00:00 0
> 7ffac000-7ffad000 r--p 00000000 00:00 0          [vvar]
> 7ffad000-7ffae000 r-xp 00000000 00:00 0          [vdso]
>
> Patch applied:
>
> cat /proc/self/maps
> 00400000-0047a000 r-xp 00000000 1f:03 1825       /bin/busybox
> 00489000-0048a000 r-xp 00079000 1f:03 1825       /bin/busybox
> 0048a000-0048b000 rwxp 0007a000 1f:03 1825       /bin/busybox
> 77ed0000-77ef5000 r-xp 00000000 1f:03 2298       /lib/libgcc_s.so.1
> 77ef5000-77ef6000 rwxp 00015000 1f:03 2298       /lib/libgcc_s.so.1
> 77ef6000-77f89000 r-xp 00000000 1f:03 2474       /lib/libc.so
> 77f98000-77f9a000 rwxp 00092000 1f:03 2474       /lib/libc.so
> 77f9a000-77f9c000 rwxp 00000000 00:00 0
> 7fbed000-7fc0e000 rw-p 00000000 00:00 0          [stack]
> 7fefb000-7fefc000 r-xp 00000000 00:00 0
> 7fff6000-7fff7000 r--p 00000000 00:00 0          [vvar]
> 7fff7000-7fff8000 r-xp 00000000 00:00 0          [vdso]
>
> Note lack of write permission to 7fefb000-7fefc000
>
> This has received minimal testing on ath79 4.14 Archer C7 v2 only
>
> Signed-off-by: Kevin Darbyshire-Bryant <ldir at darbyshire-bryant.me.uk>

Hi, Kevin

I just took another look at the build system.  On OpenWrt, we have a
pending patch 304-mips_disable_fpu.patch that makes fpu emulation for
mips an optional feature.  We have most mips targets have that feature
disabled.   The absence should be fine as we tell toolchain to use
soft-float explicitly for the whole build.

So another approach would be enhancing the disable-fpu patch to also
not mapping the dsemu page at all.

diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index d4f7fd4550e1..b55676040e22 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -651,8 +651,10 @@ unsigned long mips_stack_top(void)
 {
  unsigned long top = TASK_SIZE & PAGE_MASK;

- /* One page for branch delay slot "emulation" */
- top -= PAGE_SIZE;
+ if (IS_ENABLED(CONFIG_MIPS_FPU_EMULATOR)) {
+ /* One page for branch delay slot "emulation" */
+ top -= PAGE_SIZE;
+ }

  /* Space for the VDSO, data page & GIC user page */
  top -= PAGE_ALIGN(current->thread.abi->vdso->size);
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index 48a9c6b90e07..1852440bb43e 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -124,14 +124,16 @@ int arch_setup_additional_pages(struct
linux_binprm *bprm, int uses_interp)
  if (down_write_killable(&mm->mmap_sem))
  return -EINTR;

- /* Map delay slot emulation page */
- base = mmap_region(NULL, STACK_TOP, PAGE_SIZE,
-    VM_READ|VM_WRITE|VM_EXEC|
-    VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
-    0, NULL);
- if (IS_ERR_VALUE(base)) {
- ret = base;
- goto out;
+ if (IS_ENABLED(CONFIG_MIPS_FPU_EMULATOR)) {
+ /* Map delay slot emulation page */
+ base = mmap_region(NULL, STACK_TOP, PAGE_SIZE,
+    VM_READ|VM_WRITE|VM_EXEC|
+    VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
+    0, NULL);
+ if (IS_ERR_VALUE(base)) {
+ ret = base;
+ goto out;
+ }
  }

  /*

Regards,
                yousong

_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list