Re: [PATCH v2] drm: Fix drm_pending_vblank_event leak in error path for out_fence_ptr

Melissa Wen <[email protected]>
Newsgroups org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>

On 29/07/2026 08:10, Thadeu Lima de Souza Cascardo wrote:
> When an out_fence_ptr is provided but DRM_MODE_PAGE_FLIP_EVENT is not
> set, a drm_pending_vblank_event will be allocated. If later, there is an
> allocation failure or another failure at setup_out_fence(), that event
> will not have base.fence set and it will not be released at
> complete_signaling().
>
> Release the event and set crtc_state->event to NULL just like in the
> DRM_MODE_PAGE_FLIP_EVENT case when there is a failure at
> drm_event_reserve_init(). That is, prepare_signaling() releases the
> event and there is nothing to be done at complete_signaling(). Use
> drm_event_cancel_free() as that will also undo drm_event_reserve_init()
> in case it has been called.
Hey,

Nice catch!
> Reported-by: [email protected]

Take this with a grain of salt: I think checkpatch will complain about 
reporter
as just an email. I usually use:
`Reported-by: Sashiko <[email protected]>` but not 100% sure.
> Closes: https://sashiko.dev/#/patchset/20260727-drm_crtc_atomic_commit_leak-v1-1-23d9948a9d7c@igalia.com?part=1
> Fixes: 92c715fca907 ("drm/atomic: Fix double free in drm_atomic_state_default_clear")
> Signed-off-by: Thadeu Lima de Souza Cascardo <[email protected]>
> ---
> Changes in v2:
> - Fix UAF when DRM_MODE_PAGE_FLIP_EVENT is used.
> - Link to v1: https://patch.msgid.link/20260728-drm_pending_vblank_event_leak-v1-1-08429b920b16@igalia.com
> ---
>   drivers/gpu/drm/drm_atomic_uapi.c | 13 +++++++++++--
>   1 file changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index 1050dddadb17..aed6040182eb 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -1464,11 +1464,15 @@ static int prepare_signaling(struct drm_device *dev,
>   		if (fence_ptr) {
>   			struct dma_fence *fence;
>   			struct drm_out_fence_state *f;
> +			struct drm_pending_vblank_event *e = crtc_state->event;
>   
>   			f = krealloc(*fence_state, sizeof(**fence_state) *
>   				     (*num_fences + 1), GFP_KERNEL);
> -			if (!f)
> +			if (!f) {
> +				drm_event_cancel_free(dev, &e->base);
> +				crtc_state->event = NULL;
>   				return -ENOMEM;
> +			}
>   
>   			memset(&f[*num_fences], 0, sizeof(*f));
>   
> @@ -1476,12 +1480,17 @@ static int prepare_signaling(struct drm_device *dev,
>   			*fence_state = f;
>   
>   			fence = drm_crtc_create_fence(crtc);
> -			if (!fence)
> +			if (!fence) {
> +				drm_event_cancel_free(dev, &e->base);
> +				crtc_state->event = NULL;
>   				return -ENOMEM;
> +			}
>   
>   			ret = setup_out_fence(&f[(*num_fences)++], fence);
>   			if (ret) {
>   				dma_fence_put(fence);
> +				drm_event_cancel_free(dev, &e->base);
> +				crtc_state->event = NULL;

How about to goto a single error handle instead of repeating those three 
lines
three times? I think it'd be better for maintenance, but the fix looks 
correct as is:

Reviewed-by: Melissa Wen <[email protected]>

>   				return ret;
>   			}
>   
>
> ---
> base-commit: df0311845915442ab75d03ee89fb443b444c1370
> change-id: 20260728-drm_pending_vblank_event_leak-a36cedb296ba
>
> Best regards,
> --
> Thadeu Lima de Souza Cascardo <[email protected]>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.