Page MenuHomeFreeBSD

D18880.id58576.diff
No OneTemporary

D18880.id58576.diff

Index: lib/libc/sys/mmap.2
===================================================================
--- lib/libc/sys/mmap.2
+++ lib/libc/sys/mmap.2
@@ -28,7 +28,7 @@
.\" @(#)mmap.2 8.4 (Berkeley) 5/11/95
.\" $FreeBSD$
.\"
-.Dd June 22, 2017
+.Dd June 13, 2019
.Dt MMAP 2
.Os
.Sh NAME
@@ -113,6 +113,22 @@
Pages may be executed.
.El
.Pp
+In addition to these protection flags,
+.Fx
+provides the ability to set the maximum protection of a region allocated by
+.Nm
+and later altered by
+.Xr mprotect 2 .
+This is accomplished by
+.Em or Ns 'ing
+one or more
+.Dv PROT_
+value wrapped in the
+.Dv PROT_MAX()
+macro into the
+.Fa prot
+argument.
+.Pp
The
.Fa flags
argument specifies the type of the mapped object, mapping options and
Index: lib/libc/sys/mprotect.2
===================================================================
--- lib/libc/sys/mprotect.2
+++ lib/libc/sys/mprotect.2
@@ -28,7 +28,7 @@
.\" @(#)mprotect.2 8.1 (Berkeley) 6/9/93
.\" $FreeBSD$
.\"
-.Dd August 3, 2016
+.Dd June 13, 2019
.Dt MPROTECT 2
.Os
.Sh NAME
@@ -65,6 +65,22 @@
.It Dv PROT_EXEC
The pages can be executed.
.El
+.Pp
+In addition to these protection flags,
+.Fx
+provides the ability to set the maximum protection of a region
+(e.g., prevents
+.Nm
+from upgrading the permissions).
+This is accomplished by
+.Em or Ns 'ing
+one or more
+.Dv PROT_
+value wrapped in the
+.Dv PROT_MAX()
+macro into the
+.Fa prot
+argument.
.Sh RETURN VALUES
.Rv -std mprotect
.Sh ERRORS
Index: sys/sys/mman.h
===================================================================
--- sys/sys/mman.h
+++ sys/sys/mman.h
@@ -55,6 +55,14 @@
#define PROT_READ 0x01 /* pages can be read */
#define PROT_WRITE 0x02 /* pages can be written */
#define PROT_EXEC 0x04 /* pages can be executed */
+#if __BSD_VISIBLE
+#define _PROT_ALL (PROT_READ | PROT_WRITE | PROT_EXEC)
+#define PROT_EXTRACT(prot) ((prot) & _PROT_ALL)
+
+#define _PROT_MAX_SHIFT 16
+#define PROT_MAX(prot) ((prot) << _PROT_MAX_SHIFT)
+#define PROT_MAX_EXTRACT(prot) (((prot) >> _PROT_MAX_SHIFT) & _PROT_ALL)
+#endif
/*
* Flags contain sharing type and options.
Index: sys/vm/vm_mmap.c
===================================================================
--- sys/vm/vm_mmap.c
+++ sys/vm/vm_mmap.c
@@ -103,6 +103,9 @@
static int mincore_mapped = 1;
SYSCTL_INT(_vm, OID_AUTO, mincore_mapped, CTLFLAG_RWTUN, &mincore_mapped, 0,
"mincore reports mappings, not residency");
+static int imply_prot_max = 0;
+SYSCTL_INT(_vm, OID_AUTO, imply_prot_max, CTLFLAG_RWTUN, &mincore_mapped, 0,
+ "Imply maximum page permissions in mmap() when none are specified.");
#ifdef MAP_32BIT
#define MAP_32BIT_MAX_ADDR ((vm_offset_t)1 << 31)
@@ -187,9 +190,20 @@
vm_offset_t addr;
vm_size_t pageoff;
vm_prot_t cap_maxprot;
- int align, error;
+ int align, error, max_prot;
cap_rights_t rights;
+ max_prot = PROT_MAX_EXTRACT(prot);
+ prot = PROT_MAX(prot);
+ /*
+ * Always honor PROT_MAX if set. If not, default to all
+ * permissions unless we're implying maximum permissions.
+ *
+ * XXX: should be tunable per process and ABI.
+ */
+ if (max_prot == 0)
+ max_prot = imply_prot_max ? prot : _PROT_ALL;
+
vms = td->td_proc->p_vmspace;
fp = NULL;
AUDIT_ARG_FD(fd);
@@ -332,7 +346,7 @@
* This relies on VM_PROT_* matching PROT_*.
*/
error = vm_mmap_object(&vms->vm_map, &addr, size, prot,
- VM_PROT_ALL, flags, NULL, pos, FALSE, td);
+ max_prot, flags, NULL, pos, FALSE, td);
} else {
/*
* Mapping file, get fp for validation and don't let the
@@ -360,7 +374,7 @@
/* This relies on VM_PROT_* matching PROT_*. */
error = fo_mmap(fp, &vms->vm_map, &addr, size, prot,
- cap_maxprot, flags, pos, td);
+ max_prot & cap_maxprot, flags, pos, td);
}
if (error == 0)
@@ -591,8 +605,10 @@
{
vm_offset_t addr;
vm_size_t pageoff;
+ int vm_error, max_prot;
addr = addr0;
+ max_prot = PROT_MAX_EXTRACT(prot);
prot = (prot & VM_PROT_ALL);
pageoff = (addr & PAGE_MASK);
addr -= pageoff;
@@ -607,8 +623,19 @@
if (addr + size < addr)
return (EINVAL);
- switch (vm_map_protect(&td->td_proc->p_vmspace->vm_map, addr,
- addr + size, prot, FALSE)) {
+ if (max_prot != 0) {
+ if ((max_prot & prot) != prot)
+ return (EINVAL);
+ vm_error = vm_map_protect(&td->td_proc->p_vmspace->vm_map,
+ addr, addr + size, max_prot, TRUE);
+ if (vm_error != KERN_SUCCESS)
+ goto error_out;
+ }
+ vm_error = vm_map_protect(&td->td_proc->p_vmspace->vm_map, addr,
+ addr + size, prot, FALSE);
+
+error_out:
+ switch (vm_error) {
case KERN_SUCCESS:
return (0);
case KERN_PROTECTION_FAILURE:

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 27, 9:50 PM (16 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24317973
Default Alt Text
D18880.id58576.diff (4 KB)

Event Timeline