Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915/panic: fix panic structure allocation memory leak

Separating the panic allocation from framebuffer allocation in commit
729c5f7ffa83 ("drm/{i915,xe}/panic: move framebuffer allocation where it
belongs") failed to deallocate the panic structure anywhere.

The fix is two-fold. First, free the panic structure in
intel_user_framebuffer_destroy() in the general case. Second, move the
panic allocation later to intel_framebuffer_init() to not leak the panic
structure in error paths (if any, now or later) between
intel_framebuffer_alloc() and intel_framebuffer_init().

v2: Rebase

Fixes: 729c5f7ffa83 ("drm/{i915,xe}/panic: move framebuffer allocation where it belongs")
Cc: Jocelyn Falempe <jfalempe@redhat.com>
Cc: Maarten Lankhorst <dev@lankhorst.se>
Reported-by: Michał Grzelak <michal.grzelak@intel.com>
Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Tested-by: Michał Grzelak <michal.grzelak@intel.com> # v1
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://lore.kernel.org/r/20251015095135.2183415-1-jani.nikula@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
(cherry picked from commit 8f8ef09fcf6a3b00369bfc704e8f68d7474eca94)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

authored by

Jani Nikula and committed by
Rodrigo Vivi
789e46fb 211ddde0

+13 -12
+13 -12
drivers/gpu/drm/i915/display/intel_fb.c
··· 2117 2117 2118 2118 intel_frontbuffer_put(intel_fb->frontbuffer); 2119 2119 2120 + kfree(intel_fb->panic); 2120 2121 kfree(intel_fb); 2121 2122 } 2122 2123 ··· 2216 2215 struct intel_display *display = to_intel_display(obj->dev); 2217 2216 struct drm_framebuffer *fb = &intel_fb->base; 2218 2217 u32 max_stride; 2219 - int ret = -EINVAL; 2218 + int ret; 2220 2219 int i; 2220 + 2221 + intel_fb->panic = intel_panic_alloc(); 2222 + if (!intel_fb->panic) 2223 + return -ENOMEM; 2221 2224 2222 2225 /* 2223 2226 * intel_frontbuffer_get() must be done before 2224 2227 * intel_fb_bo_framebuffer_init() to avoid set_tiling vs. addfb race. 2225 2228 */ 2226 2229 intel_fb->frontbuffer = intel_frontbuffer_get(obj); 2227 - if (!intel_fb->frontbuffer) 2228 - return -ENOMEM; 2230 + if (!intel_fb->frontbuffer) { 2231 + ret = -ENOMEM; 2232 + goto err_free_panic; 2233 + } 2229 2234 2230 2235 ret = intel_fb_bo_framebuffer_init(fb, obj, mode_cmd); 2231 2236 if (ret) ··· 2330 2323 intel_fb_bo_framebuffer_fini(obj); 2331 2324 err_frontbuffer_put: 2332 2325 intel_frontbuffer_put(intel_fb->frontbuffer); 2326 + err_free_panic: 2327 + kfree(intel_fb->panic); 2328 + 2333 2329 return ret; 2334 2330 } 2335 2331 ··· 2359 2349 struct intel_framebuffer *intel_framebuffer_alloc(void) 2360 2350 { 2361 2351 struct intel_framebuffer *intel_fb; 2362 - struct intel_panic *panic; 2363 2352 2364 2353 intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); 2365 2354 if (!intel_fb) 2366 2355 return NULL; 2367 - 2368 - panic = intel_panic_alloc(); 2369 - if (!panic) { 2370 - kfree(intel_fb); 2371 - return NULL; 2372 - } 2373 - 2374 - intel_fb->panic = panic; 2375 2356 2376 2357 return intel_fb; 2377 2358 }