Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] Race condition in nouveau_fence_context_del between cancel_work_sync and nvif_event_dtor leads to use-after-free of fctx.
- [High] Missing cancel_work_sync for irq_work in nouveau_connector_destroy leads to use-after-free of the connector.
--
--- Patch [1]: [PATCH v4 1/3] drm/nouveau: unsubscribe the channel-kill event before the fence context ---
commit 4ae9b89defb4e27bc74c023fe090b6ae974e3378
Author: Marek Czernohous <[email protected]>
drm/nouveau: unsubscribe the channel-kill event before the fence context
nouveau_channel_del() tears the fence context down first and only drops
the channel-kill subscription later, which can cause a use-after-free
if a kill event is delivered in that window. This patch drops the
subscription before anything it depends on is torn down.
> diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c
> index 598513f604493..f142f63105966 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_chan.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c
> @@ -90,6 +90,14 @@ nouveau_channel_del(struct nouveau_channel **pchan)
> {
> struct nouveau_channel *chan = *pchan;
> if (chan) {
> + /*
> + * Drop the kill-event subscription first. Its handler
> + * dereferences chan->fence, which the fence context teardown
> + * below frees, so leaving it armed across the teardown leaves
> + * a window for a use-after-free.
> + */
> + nvif_event_dtor(&chan->kill);
> +
> if (chan->fence)
> nouveau_fence(chan->cli->drm)->context_del(chan);
>
[ ... ]
> @@ -100,7 +108,6 @@ nouveau_channel_del(struct nouveau_channel **pchan)
> nvif_object_dtor(&chan->nvsw);
> nvif_object_dtor(&chan->gart);
> nvif_object_dtor(&chan->vram);
> - nvif_event_dtor(&chan->kill);
> nvif_object_dtor(&chan->user);
> nvif_mem_dtor(&chan->mem_userd);
> nouveau_vma_del(&chan->sema.vma);
[Severity: High]
This isn't a bug introduced by this patch, but looking at similar teardown
paths, is there a race condition in nouveau_fence_context_del() between
cancel_work_sync() and nvif_event_dtor()?
drivers/gpu/drm/nouveau/nouveau_fence.c:nouveau_fence_context_del() {
...
cancel_work_sync(&fctx->uevent_work);
nouveau_fence_context_kill(fctx, 0);
nvif_event_dtor(&fctx->event);
...
}
If a hardware interrupt fires in the narrow window after cancel_work_sync()
but before nvif_event_dtor(), could the event handler schedule the work
again?
The work would remain pending on the workqueue while fctx is subsequently
freed, leading to a use-after-free when the work executes.
[Severity: High]
This is another pre-existing issue in a similar teardown path, but is there a
missing cancel_work_sync() for irq_work in nouveau_connector_destroy()?
drivers/gpu/drm/nouveau/nouveau_connector.c:nouveau_connector_destroy() {
...
nvif_event_dtor(&nv_connector->irq);
nvif_event_dtor(&nv_connector->hpd);
kfree(nv_connector->edid);
drm_connector_unregister(connector);
...
}
When a connector is destroyed, it calls nvif_event_dtor() to unregister the
hardware event, but does not appear to call cancel_work_sync() for
nv_connector->irq_work.
If an IRQ fires right before the event is destroyed, the handler schedules
irq_work:
drivers/gpu/drm/nouveau/nouveau_connector.c:nouveau_connector_irq() {
...
schedule_work(&nv_connector->irq_work);
return NVIF_EVENT_KEEP;
}
Because the work is never canceled, will it eventually execute on freed
memory after the connector has been freed?
--
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
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.