⬢ DragonFlyBSD Kernel Audit
DF-5193 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/drm_scatter.c
+++ b/sys/dev/drm/drm_scatter.c
@@ -122,18 +122,25 @@ int drm_legacy_sg_free(struct drm_device *dev, void *data,
 	if (!drm_core_check_feature(dev, DRIVER_SG))
 		return -EOPNOTSUPP;
 
+	DRM_LOCK(dev);
 	entry = dev->sg;
-	dev->sg = NULL;
 
-	if (!entry || entry->vaddr != request->handle)
+	/*
+	 * DF-5193: validate the handle BEFORE clearing dev->sg.  The old
+	 * clear-first order orphaned the whole drm_sg_mem (KVA range, busaddr
+	 * array, entry) on a handle mismatch, and let a subsequent SG_ALLOC
+	 * install a second allocation on top of the leaked one.
+	 */
+	if (!entry || entry->vaddr != request->handle) {
+		DRM_UNLOCK(dev);
 		return -EINVAL;
+	}
+	dev->sg = NULL;
+	DRM_UNLOCK(dev);
 
 	DRM_DEBUG("free 0x%jx\n", (uintmax_t)entry->vaddr);
 
 	drm_sg_cleanup(entry);
 
 	return 0;