⬢ DragonFlyBSD Kernel Audit
DF-2398 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/agp/agp.c
+++ b/sys/dev/agp/agp.c
@@ -516,16 +516,21 @@
 		return EINVAL;
 	}
 	
-	/* Do some sanity checks first. */
-	if (offset < 0
-	    || (offset & (AGP_PAGE_SIZE - 1)) != 0
-	    || offset + mem->am_size > AGP_GET_APERTURE(dev)) {
-		device_printf(dev, "binding memory at bad offset %#x,%#x,%#x\n",
-			      (int) offset, (int)mem->am_size,
-			      (int)AGP_GET_APERTURE(dev));
-		kprintf("Check BIOS's aperature size vs X\n");
-		lockmgr(&sc->as_lock, LK_RELEASE);
-		return EINVAL;
+	/* Do some sanity checks first.  Subtractive form so
+	 * offset + am_size cannot wrap around 64 bits (DF-2398). */
+	{
+		u_int32_t aperture = AGP_GET_APERTURE(dev);
+
+		if ((offset & (AGP_PAGE_SIZE - 1)) != 0
+		    || mem->am_size > aperture
+		    || offset > aperture - mem->am_size) {
+			device_printf(dev, "binding memory at bad offset %#jx,%#x,%#x\n",
+				      (uintmax_t)offset, (int)mem->am_size,
+				      (int)aperture);
+			kprintf("Check BIOS's aperature size vs X\n");
+			lockmgr(&sc->as_lock, LK_RELEASE);
+			return EINVAL;
+		}
 	}
 
 	/*