DragonFlyBSD Kernel Audit
DF-1257 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/drm/amd/amdgpu/amdgpu_vm.c b/sys/dev/drm/amd/amdgpu/amdgpu_vm.c
--- a/sys/dev/drm/amd/amdgpu/amdgpu_vm.c
+++ b/sys/dev/drm/amd/amdgpu/amdgpu_vm.c
@@ -2507,9 +2507,16 @@
 
 	/* make sure object fit at this offset */
 	eaddr = saddr + size - 1;
-	if (saddr >= eaddr ||
-	    (bo && offset + size > amdgpu_bo_size(bo)))
+	if (saddr >= eaddr)
 		return -EINVAL;
+	/* DF-1257: 'offset + size' wraps mod 2^64 and bypasses the bound.
+	 * Check the range without an overflowing addition: size must fit in
+	 * the BO, and offset must not run past the end. */
+	if (bo) {
+		uint64_t __bo_sz = amdgpu_bo_size(bo);
+		if (size > __bo_sz || offset > __bo_sz - size)
+			return -EINVAL;
+	}
 
 	saddr /= AMDGPU_GPU_PAGE_SIZE;
 	eaddr /= AMDGPU_GPU_PAGE_SIZE;
@@ -2572,9 +2579,16 @@
 
 	/* make sure object fit at this offset */
 	eaddr = saddr + size - 1;
-	if (saddr >= eaddr ||
-	    (bo && offset + size > amdgpu_bo_size(bo)))
+	if (saddr >= eaddr)
 		return -EINVAL;
+	/* DF-1257: 'offset + size' wraps mod 2^64 and bypasses the bound.
+	 * Check the range without an overflowing addition: size must fit in
+	 * the BO, and offset must not run past the end. */
+	if (bo) {
+		uint64_t __bo_sz = amdgpu_bo_size(bo);
+		if (size > __bo_sz || offset > __bo_sz - size)
+			return -EINVAL;
+	}
 
 	/* Allocate all the needed memory */
 	mapping = kmalloc(sizeof(*mapping), M_DRM, GFP_KERNEL);