svn commit: r359892 - head/sys/kern

Mark Johnston markj at FreeBSD.org
Mon Apr 13 19:20:39 UTC 2020


Author: markj
Date: Mon Apr 13 19:20:39 2020
New Revision: 359892
URL: https://svnweb.freebsd.org/changeset/base/359892

Log:
  Relax restrictions on private mappings of POSIX shm objects.
  
  When creating a private mapping of a POSIX shared memory object,
  VM_PROT_WRITE should always be included in maxprot regardless of
  permissions on the underlying FD.  Otherwise it is possible to open a
  shm object read-only, map it with MAP_PRIVATE and PROT_WRITE, and
  violate the invariant in vm_map_insert() that (prot & maxprot) == prot.
  
  Reported by:	syzkaller
  Reviewed by:	kevans, kib
  MFC after:	1 week
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D24398

Modified:
  head/sys/kern/uipc_shm.c

Modified: head/sys/kern/uipc_shm.c
==============================================================================
--- head/sys/kern/uipc_shm.c	Mon Apr 13 17:55:31 2020	(r359891)
+++ head/sys/kern/uipc_shm.c	Mon Apr 13 19:20:39 2020	(r359892)
@@ -1136,23 +1136,28 @@ shm_mmap(struct file *fp, vm_map_t map, vm_offset_t *a
 
 	/*
 	 * If FWRITE's set, we can allow VM_PROT_WRITE unless it's a shared
-	 * mapping with a write seal applied.
+	 * mapping with a write seal applied.  Private mappings are always
+	 * writeable.
 	 */
-	if ((fp->f_flag & FWRITE) != 0 && ((flags & MAP_SHARED) == 0 ||
-	    (shmfd->shm_seals & F_SEAL_WRITE) == 0))
+	if ((flags & MAP_SHARED) == 0) {
+		cap_maxprot |= VM_PROT_WRITE;
 		maxprot |= VM_PROT_WRITE;
+		writecnt = false;
+	} else {
+		if ((fp->f_flag & FWRITE) != 0 &&
+		    (shmfd->shm_seals & F_SEAL_WRITE) == 0)
+			maxprot |= VM_PROT_WRITE;
+		writecnt = (prot & VM_PROT_WRITE) != 0;
+		if (writecnt && (shmfd->shm_seals & F_SEAL_WRITE) != 0) {
+			error = EPERM;
+			goto out;
+		}
 
-	writecnt = (flags & MAP_SHARED) != 0 && (prot & VM_PROT_WRITE) != 0;
-
-	if (writecnt && (shmfd->shm_seals & F_SEAL_WRITE) != 0) {
-		error = EPERM;
-		goto out;
-	}
-
-	/* Don't permit shared writable mappings on read-only descriptors. */
-	if (writecnt && (maxprot & VM_PROT_WRITE) == 0) {
-		error = EACCES;
-		goto out;
+		/* Don't permit shared writable mappings on read-only descriptors. */
+		if (writecnt && (maxprot & VM_PROT_WRITE) == 0) {
+			error = EACCES;
+			goto out;
+		}
 	}
 	maxprot &= cap_maxprot;
 


More information about the svn-src-all mailing list