[PATCH] drm/gem-atomic-helper: Fix fence reference leaks in prepare_fb
From: Ke Chen
Date: Tue Sep 01 2026 - 05:20:35 EST
An atomic commit can set IN_FENCE_FD while disabling a plane, leaving
the new plane state with a fence but no framebuffer. In this case,
drm_gem_plane_helper_prepare_fb() takes an extra reference to
state->fence before checking state->fb and returns without dropping it.
Repeated commits therefore leak one fence reference each and keep the
affected fence objects alive.
dma_resv_get_singleton() also returns a referenced fence through new.
If dma_fence_chain_alloc() fails, ownership of new has not been
transferred to a chain, while the common error path only drops fence.
Take the explicit fence reference after the framebuffer check and drop
new explicitly if allocating the fence chain fails.
Fixes: 1ea28bc5542d ("drm: handle kernel fences in drm_gem_plane_helper_prepare_fb v2")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Ke Chen <Ke.Chen@xxxxxxx>
---
Tested with x86_64, arm64, and arm target-object builds using W=1.
Also checked the x86_64 target object with sparse C=1 and
CF=-D__CHECK_ENDIAN__. Runtime and allocation-failure fault-injection
testing were not performed.
drivers/gpu/drm/drm_gem_atomic_helper.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_gem_atomic_helper.c b/drivers/gpu/drm/drm_gem_atomic_helper.c
index abef865c5f2c9..4c0a23f4b2970 100644
--- a/drivers/gpu/drm/drm_gem_atomic_helper.c
+++ b/drivers/gpu/drm/drm_gem_atomic_helper.c
@@ -114,7 +114,7 @@
int drm_gem_plane_helper_prepare_fb(struct drm_plane *plane,
struct drm_plane_state *state)
{
- struct dma_fence *fence = dma_fence_get(state->fence);
+ struct dma_fence *fence;
enum dma_resv_usage usage;
size_t i;
int ret;
@@ -122,6 +122,8 @@ int drm_gem_plane_helper_prepare_fb(struct drm_plane *plane,
if (!state->fb)
return 0;
+ fence = dma_fence_get(state->fence);
+
/*
* Only add the kernel fences here if there is already a fence set via
* explicit fencing interfaces on the atomic ioctl.
@@ -154,6 +156,7 @@ int drm_gem_plane_helper_prepare_fb(struct drm_plane *plane,
struct dma_fence_chain *chain = dma_fence_chain_alloc();
if (!chain) {
+ dma_fence_put(new);
ret = -ENOMEM;
goto error;
}
base-commit: 20839d02c0cf7437bc508d4c5430538d9dc4f428
--
2.34.1