⬢ DragonFlyBSD Kernel Audit
DF-4501 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/radeon/radeon_uvd.c
+++ b/sys/dev/drm/radeon/radeon_uvd.c
@@ -762,7 +762,13 @@
 
 	r = radeon_ib_schedule(rdev, &ib, NULL, false);
 
-	if (fence)
+	/* DF-4501: ib.fence is NULL on every radeon_ib_schedule() error
+	 * path; radeon_fence_ref(NULL) computes &NULL->base (a small
+	 * non-NULL address) which passes dma_fence_get()'s NULL check and
+	 * then kref_get()s at a near-NULL kernel address -> panic.  Only
+	 * hand out a fence when the IB actually scheduled.
+	 */
+	if (!r && fence)
 		*fence = radeon_fence_ref(ib.fence);
 
 	radeon_ib_free(rdev, &ib);