⬢ DragonFlyBSD Kernel Audit
DF-4533 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/drm_file.c
+++ b/sys/dev/drm/drm_file.c
@@ -370,6 +370,7 @@
 	struct inode *inode = filp->f_data;	/* A Linux inode is a Unix vnode */
 #endif
 	struct drm_file *file_priv = filp->private_data;
+	struct drm_minor *open_minor = file_priv->minor;
 	struct drm_minor *minor = drm_minor_acquire(iminor(inode));
 	struct drm_device *dev = minor->dev;
 
@@ -444,6 +445,14 @@
 
 	drm_minor_release(minor);
 
+	/*
+	 * drm_open() acquired a reference at drm_file.c:325 that it
+	 * intentionally keeps on success (the file owns it; Linux drops
+	 * it in drm_release()).  drm_close() so far dropped only its own
+	 * acquire above, leaking one drm_device kref per open/close.
+	 */
+	drm_minor_release(open_minor);
+
 	return 0;
 }
 EXPORT_SYMBOL(drm_close);