Module Name:    src
Committed By:   riastradh
Date:           Wed Jul  6 01:16:36 UTC 2022

Modified Files:
        src/sys/uvm: uvm_device.c

Log Message:
mmap(2): Guarantee two's-complement wraparound for D_NEGOFFSAFE.

XXX Not sure this should be allowed at all, but this way we don't
change the semantics of the existing code which was written under
essentially the assumption of -fwrapv.


To generate a diff of this commit:
cvs rdiff -u -r1.76 -r1.77 src/sys/uvm/uvm_device.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/uvm/uvm_device.c
diff -u src/sys/uvm/uvm_device.c:1.76 src/sys/uvm/uvm_device.c:1.77
--- src/sys/uvm/uvm_device.c:1.76	Wed Jul  6 01:15:51 2022
+++ src/sys/uvm/uvm_device.c	Wed Jul  6 01:16:36 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_device.c,v 1.76 2022/07/06 01:15:51 riastradh Exp $	*/
+/*	$NetBSD: uvm_device.c,v 1.77 2022/07/06 01:16:36 riastradh Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_device.c,v 1.76 2022/07/06 01:15:51 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_device.c,v 1.77 2022/07/06 01:16:36 riastradh Exp $");
 
 #include "opt_uvmhist.h"
 
@@ -152,13 +152,29 @@ udv_attach(dev_t device, vm_prot_t acces
 	 * XXX assumes VM_PROT_* == PROT_*
 	 * XXX clobbers off and size, but nothing else here needs them.
 	 */
-
-	while (size != 0) {
-		if (cdev_mmap(device, off, accessprot) == -1) {
-			return (NULL);
+	do {
+		KASSERTMSG((off % PAGE_SIZE) == 0, "off=%jd", (intmax_t)off);
+		KASSERTMSG(size >= PAGE_SIZE, "size=%"PRIuVSIZE, size);
+		if (cdev_mmap(device, off, accessprot) == -1)
+			return NULL;
+		KASSERT(off <= __type_max(voff_t) - PAGE_SIZE ||
+		    (cdev->d_flag & D_NEGOFFSAFE) != 0);
+		if (__predict_false(off > __type_max(voff_t) - PAGE_SIZE)) {
+			/*
+			 * off += PAGE_SIZE, with two's-complement
+			 * wraparound, or
+			 *
+			 *	off += PAGE_SIZE - 2*(VOFF_MAX + 1).
+			 */
+			CTASSERT(PAGE_SIZE >= 2);
+			off -= __type_max(voff_t);
+			off += PAGE_SIZE - 2;
+			off -= __type_max(voff_t);
+		} else {
+			off += PAGE_SIZE;
 		}
-		off += PAGE_SIZE; size -= PAGE_SIZE;
-	}
+		size -= PAGE_SIZE;
+	} while (size != 0);
 
 	/*
 	 * keep looping until we get it

Reply via email to