⬢ DragonFlyBSD Kernel Audit
DF-4471 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/drm_crtc_helper.c
+++ b/sys/dev/drm/drm_crtc_helper.c
@@ -181,10 +181,17 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev)
 	drm_for_each_crtc(crtc, dev) {
 		const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 		crtc->enabled = drm_helper_crtc_in_use(crtc);
 		if (!crtc->enabled) {
 			if (crtc_funcs->disable)
 				(*crtc_funcs->disable)(crtc);
 			else
 				(*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
+			/*
+			 * DF-4471: the plane owns one reference on
+			 * primary->fb.  Drop it here and clear old_fb so
+			 * __drm_mode_set_config_internal() does not put it
+			 * a second time (wrapper callers), while direct
+			 * callers (resume / fb helper) stop leaking it.
+			 */
+			if (crtc->primary->fb)
+				drm_framebuffer_put(crtc->primary->fb);
 			crtc->primary->fb = NULL;
+			crtc->primary->old_fb = NULL;
 		}
 	}
 }