]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/ttm: fix NULL deref in ttm_bo_flush_all_fences() after fence ops detach
authorSebastian Brzezinka <sebastian.brzezinka@intel.com>
Tue, 3 Mar 2026 12:26:42 +0000 (13:26 +0100)
committerChristian König <christian.koenig@amd.com>
Thu, 5 Mar 2026 07:51:35 +0000 (08:51 +0100)
Since commit 541c8f2468b9 ("dma-buf: detach fence ops on signal v3"),
fence->ops may be set to NULL via RCU when a fence signals and has no
release/wait ops. ttm_bo_flush_all_fences() was not updated to handle
this and directly dereferences fence->ops->signaled, leading to a NULL
pointer dereference crash:

```
BUG: kernel NULL pointer dereference, address: 0000000000000018
RIP: 0010:ttm_bo_release+0x1bc/0x330 [ttm]
```

Since dma_fence_enable_sw_signaling() already handles the signaled case
internally (it checks DMA_FENCE_FLAG_SIGNALED_BIT before doing anything),
the ops->signaled pre-check is redundant. Simply remove it and call
dma_fence_enable_sw_signaling() unconditionally for each fence.

Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15759
Fixes: 541c8f2468b9 ("dma-buf: detach fence ops on signal v3")
Cc: Christian König <christian.koenig@amd.com>
Signed-off-by: Sebastian Brzezinka <sebastian.brzezinka@intel.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
Signed-off-by: Christian König <christian.koenig@amd.com>
Link: https://lore.kernel.org/r/1c2f34351b6fb70ab576aeac07987542a4d480b2.1772540459.git.sebastian.brzezinka@intel.com
drivers/gpu/drm/ttm/ttm_bo.c

index acb9197db8798659da178186115c2912b84f64e6..0485ad00a3df60992bd689d831c4d0040e8bb94c 100644 (file)
@@ -222,10 +222,8 @@ static void ttm_bo_flush_all_fences(struct ttm_buffer_object *bo)
        struct dma_fence *fence;
 
        dma_resv_iter_begin(&cursor, resv, DMA_RESV_USAGE_BOOKKEEP);
-       dma_resv_for_each_fence_unlocked(&cursor, fence) {
-               if (!fence->ops->signaled)
-                       dma_fence_enable_sw_signaling(fence);
-       }
+       dma_resv_for_each_fence_unlocked(&cursor, fence)
+               dma_fence_enable_sw_signaling(fence);
        dma_resv_iter_end(&cursor);
 }