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/283b47410678
branches: trunk
changeset: 353434:283b47410678
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 24ff5ffcd54c -r 283b47410678 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 24ff5ffcd54c -r 283b47410678 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 24ff5ffcd54c -r 283b47410678 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 24ff5ffcd54c -r 283b47410678 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 24ff5ffcd54c -r 283b47410678 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 24ff5ffcd54c -r 283b47410678 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 24ff5ffcd54c -r 283b47410678 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