Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Extend the mmap(2) interface to allow requesting protections...



details:   https://anonhg.NetBSD.org/src/rev/cf19e5f5a5c8
branches:  trunk
changeset: 823735:cf19e5f5a5c8
user:      joerg <joerg%NetBSD.org@localhost>
date:      Sat May 06 21:34:51 2017 +0000

description:
Extend the mmap(2) interface to allow requesting protections for later
use with mprotect(2), but without enabling them immediately.

Extend the mremap(2) interface to allow duplicating mappings, i.e.
create a second range of virtual addresses references the same physical
pages. Duplicated mappings can have different effective protections.

Adjust PAX mprotect logic to disallow effective protections of W&X, but
allow one mapping W and another X protections. This obsoletes using
temporary files for purposes like JIT.

Adjust PAX logic for mmap(2) and mprotect(2) to fail if W&X is requested
and not silently drop the X protection.

Improve test cases to ensure correct operation of the changed
interfaces.

diffstat:

 lib/libc/sys/mmap.2                  |  17 ++++++-
 lib/libc/sys/mprotect.2              |  16 +++++-
 lib/libc/sys/mremap.2                |   7 ++-
 share/man/man9/uvm_map.9             |  11 ++++-
 sys/compat/linux/common/linux_misc.c |   6 +-
 sys/kern/exec_subr.c                 |  25 +++++++---
 sys/kern/kern_pax.c                  |  52 +++++++++++++----------
 sys/sys/mman.h                       |  13 +++++-
 sys/sys/pax.h                        |  29 +++++++++----
 sys/uvm/uvm_extern.h                 |   4 +-
 sys/uvm/uvm_map.c                    |  24 +++++++++-
 sys/uvm/uvm_mmap.c                   |  16 ++++--
 sys/uvm/uvm_mremap.c                 |  12 +++--
 sys/uvm/uvm_unix.c                   |  12 ++--
 tests/lib/libc/sys/t_mprotect.c      |  80 ++++++++++++++++++++++++++++++++++-
 15 files changed, 246 insertions(+), 78 deletions(-)

diffs (truncated from 775 to 300 lines):

diff -r d7a80ffdbc15 -r cf19e5f5a5c8 lib/libc/sys/mmap.2
--- a/lib/libc/sys/mmap.2       Sat May 06 19:56:41 2017 +0000
+++ b/lib/libc/sys/mmap.2       Sat May 06 21:34:51 2017 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: mmap.2,v 1.48 2015/02/27 16:18:00 christos Exp $
+.\"    $NetBSD: mmap.2,v 1.49 2017/05/06 21:34:51 joerg Exp $
 .\"
 .\" Copyright (c) 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"    @(#)mmap.2      8.4 (Berkeley) 5/11/95
 .\"
-.Dd February 27, 2015
+.Dd April 27, 2017
 .Dt MMAP 2
 .Os
 .Sh NAME
@@ -85,8 +85,14 @@
 .It Dv PROT_WRITE
 Pages may be written.
 .It Dv PROT_NONE
-Pages may not be accessed.
+Placeholder when requesting no access permission.
 .El
+As a NetBSD extension,
+.Dv PROT_MPROTECT
+can be used to request additional permissions for later use with
+.Fn mprotect 2 .
+This is necessary for switching pages between writeable and executable
+when PAX mprotect restrictions are in place.
 .Pp
 .Bf -symbolic
 Note that, due to hardware limitations, on some platforms
@@ -238,6 +244,7 @@
 parameter and
 .Fa fd
 was not open for reading.
+.Pp
 The flags
 .Dv MAP_SHARED
 and
@@ -249,6 +256,8 @@
 parameters and
 .Fa fd
 was not open for writing.
+.Pp
+PAX mprotect restrictions prohibit the requested protection.
 .It Bq Er EBADF
 .Fa fd
 is not a valid open file descriptor.
@@ -265,6 +274,7 @@
 .Fa addr
 parameter was not page aligned or was outside of the
 valid address range for a process.
+.Pp
 .Dv MAP_ANON was specified and
 .Fa fd
 was not \-1.
@@ -276,6 +286,7 @@
 was specified and the
 .Fa addr
 parameter wasn't available.
+.Pp
 .Dv MAP_ANON
 was specified and insufficient memory was available.
 .It Bq Er EOVERFLOW
diff -r d7a80ffdbc15 -r cf19e5f5a5c8 lib/libc/sys/mprotect.2
--- a/lib/libc/sys/mprotect.2   Sat May 06 19:56:41 2017 +0000
+++ b/lib/libc/sys/mprotect.2   Sat May 06 21:34:51 2017 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: mprotect.2,v 1.24 2011/04/03 06:54:30 jruoho Exp $
+.\"    $NetBSD: mprotect.2,v 1.25 2017/05/06 21:34:51 joerg Exp $
 .\"
 .\" Copyright (c) 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"    @(#)mprotect.2  8.1 (Berkeley) 6/9/93
 .\"
-.Dd April 3, 2011
+.Dd April 27, 2017
 .Dt MPROTECT 2
 .Os
 .Sh NAME
@@ -64,7 +64,7 @@
 .It Dv PROT_WRITE
 Pages may be written.
 .It Dv PROT_NONE
-No permissions.
+Placeholder when requesting no access permission.
 .El
 .Sh RETURN VALUES
 Upon successful completion,
@@ -75,11 +75,19 @@
 .Sh ERRORS
 .Bl -tag -width Er
 .It Bq Er EACCES
-A memory protection violation occurred, or the
+A memory protection violation occurred.
+.Pp
+The
 .Dv PROT_EXEC
 flag was attempted on pages which belong to a filesystem mounted with the
 .Dv NOEXEC
 flag.
+.Pp
+The new protection is less restrictive than the protection originally
+set with
+.Xr mmap 2 .
+.Pp
+PAX mprotect restrictions prohibit the requested protection.
 .It Bq Er EINVAL
 An invalid memory range, or invalid parameters were provided.
 .It Bq Er ENOMEM
diff -r d7a80ffdbc15 -r cf19e5f5a5c8 lib/libc/sys/mremap.2
--- a/lib/libc/sys/mremap.2     Sat May 06 19:56:41 2017 +0000
+++ b/lib/libc/sys/mremap.2     Sat May 06 21:34:51 2017 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: mremap.2,v 1.4 2011/04/28 12:00:55 wiz Exp $
+.\"    $NetBSD: mremap.2,v 1.5 2017/05/06 21:34:51 joerg Exp $
 .\"
 .\" Copyright (c) 2007 Thomas Klausner and Joerg Sonnenberger
 .\" All rights reserved.
@@ -25,7 +25,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\" ------------------------------------------------------------
-.Dd February 14, 2008
+.Dd April 28, 2017
 .Dt MREMAP 2
 .Os
 .Sh NAME
@@ -82,6 +82,9 @@
 and
 .Ar newp
 are used as hints for the position, factoring in the given alignment.
+.It Dv MAP_REMAPDUP
+Duplicate the mapping.
+Both address ranges reference the same pages, but can have different protection flags.
 .El
 .Sh RETURN VALUES
 .Fn mremap
diff -r d7a80ffdbc15 -r cf19e5f5a5c8 share/man/man9/uvm_map.9
--- a/share/man/man9/uvm_map.9  Sat May 06 19:56:41 2017 +0000
+++ b/share/man/man9/uvm_map.9  Sat May 06 21:34:51 2017 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: uvm_map.9,v 1.6 2014/09/12 21:06:25 riastradh Exp $
+.\"    $NetBSD: uvm_map.9,v 1.7 2017/05/06 21:34:51 joerg Exp $
 .\"
 .\" Copyright (c) 1998 Matthew R. Green
 .\" All rights reserved.
@@ -49,6 +49,9 @@
 .Fn uvm_map_protect "struct vm_map *map" "vaddr_t start" "vaddr_t end" \
 "vm_prot_t new_prot" "bool set_max"
 .Ft int
+.Fn uvm_map_protect_user "struct lwp *l" "vaddr_t start" "vaddr_t end" \
+"vm_prot_t new_prot"
+.Ft int
 .Fn uvm_deallocate "struct vm_map *map" "vaddr_t start" "vsize_t size"
 .Ft struct vmspace *
 .Fn uvmspace_alloc "vaddr_t min" "vaddr_t max"
@@ -308,6 +311,12 @@
 is true.
 This function returns a standard UVM return value.
 .Pp
+.Fn uvm_map_protect_user
+verifies that the new permissions honor PAX restrictions if applicable
+and forwards to
+.Fn uvm_map_protect
+on passing.
+.Pp
 .Fn uvm_deallocate
 deallocates kernel memory in map
 .Fa map
diff -r d7a80ffdbc15 -r cf19e5f5a5c8 sys/compat/linux/common/linux_misc.c
--- a/sys/compat/linux/common/linux_misc.c      Sat May 06 19:56:41 2017 +0000
+++ b/sys/compat/linux/common/linux_misc.c      Sat May 06 21:34:51 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_misc.c,v 1.237 2017/01/28 15:01:01 christos Exp $        */
+/*     $NetBSD: linux_misc.c,v 1.238 2017/05/06 21:34:51 joerg Exp $   */
 
 /*-
  * Copyright (c) 1995, 1998, 1999, 2008 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_misc.c,v 1.237 2017/01/28 15:01:01 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_misc.c,v 1.238 2017/05/06 21:34:51 joerg Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -603,7 +603,7 @@
                }
        }
        vm_map_unlock(map);
-       return uvm_map_protect(map, start, end, prot, FALSE);
+       return uvm_map_protect_user(l, start, end, prot);
 }
 #endif /* USRSTACK */
 
diff -r d7a80ffdbc15 -r cf19e5f5a5c8 sys/kern/exec_subr.c
--- a/sys/kern/exec_subr.c      Sat May 06 19:56:41 2017 +0000
+++ b/sys/kern/exec_subr.c      Sat May 06 21:34:51 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: exec_subr.c,v 1.76 2016/05/22 14:26:09 christos Exp $  */
+/*     $NetBSD: exec_subr.c,v 1.77 2017/05/06 21:34:51 joerg Exp $     */
 
 /*
  * Copyright (c) 1993, 1994, 1996 Christopher G. Demetriou
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: exec_subr.c,v 1.76 2016/05/22 14:26:09 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: exec_subr.c,v 1.77 2017/05/06 21:34:51 joerg Exp $");
 
 #include "opt_pax.h"
 
@@ -180,8 +180,11 @@
                return EINVAL;
 
        prot = cmd->ev_prot;
-       maxprot = UVM_PROT_ALL;
-       PAX_MPROTECT_ADJUST(l, &prot, &maxprot);
+       maxprot = PAX_MPROTECT_MAXPROTECT(l, prot, 0, UVM_PROT_ALL);
+       if ((prot & maxprot) != prot)
+               return EACCES;
+       if ((error = PAX_MPROTECT_VALIDATE(l, prot)))
+               return error;
 
        /*
         * check the file system's opinion about mmapping the file
@@ -260,8 +263,11 @@
                return error;
 
        prot = cmd->ev_prot;
-       maxprot = VM_PROT_ALL;
-       PAX_MPROTECT_ADJUST(l, &prot, &maxprot);
+       maxprot = PAX_MPROTECT_MAXPROTECT(l, prot, 0, UVM_PROT_ALL);
+       if ((prot & maxprot) != prot)
+               return EACCES;
+       if ((error = PAX_MPROTECT_VALIDATE(l, prot)))
+               return error;
 
 #ifdef PMAP_NEED_PROCWR
        /*
@@ -318,8 +324,11 @@
        cmd->ev_len += diff;
 
        prot = cmd->ev_prot;
-       maxprot = UVM_PROT_ALL;
-       PAX_MPROTECT_ADJUST(l, &prot, &maxprot);
+       maxprot = PAX_MPROTECT_MAXPROTECT(l, prot, 0, UVM_PROT_ALL);
+       if ((prot & maxprot) != prot)
+               return EACCES;
+       if ((error = PAX_MPROTECT_VALIDATE(l, prot)))
+               return error;
 
        error = uvm_map(&p->p_vmspace->vm_map, &cmd->ev_addr,
                        round_page(cmd->ev_len), NULL, UVM_UNKNOWN_OFFSET, 0,
diff -r d7a80ffdbc15 -r cf19e5f5a5c8 sys/kern/kern_pax.c
--- a/sys/kern/kern_pax.c       Sat May 06 19:56:41 2017 +0000
+++ b/sys/kern/kern_pax.c       Sat May 06 21:34:51 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_pax.c,v 1.58 2017/02/18 01:29:09 chs Exp $        */
+/*     $NetBSD: kern_pax.c,v 1.59 2017/05/06 21:34:51 joerg Exp $      */
 
 /*
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_pax.c,v 1.58 2017/02/18 01:29:09 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_pax.c,v 1.59 2017/05/06 21:34:51 joerg Exp $");
 
 #include "opt_pax.h"
 
@@ -423,42 +423,48 @@
        return true;
 }
 
-void
-pax_mprotect_adjust(
+vm_prot_t
+pax_mprotect_maxprotect(
 #ifdef PAX_MPROTECT_DEBUG
     const char *file, size_t line,
 #endif
-    struct lwp *l, vm_prot_t *prot, vm_prot_t *maxprot)
+    struct lwp *l, vm_prot_t active, vm_prot_t extra, vm_prot_t maxprot)
 {
        uint32_t flags;
 
        flags = l->l_proc->p_pax;
        if (!pax_flags_active(flags, P_PAX_MPROTECT))
-               return;
+               return maxprot;



Home | Main Index | Thread Index | Old Index