public inbox for drm-ai-reviews@public-inbox.freedesktop.org
 help / color / mirror / Atom feed
* [PATCH drm] drm/gem: fix race between change_handle and handle_delete
@ 2026-05-26  8:53 Zhenghang Xiao
  2026-05-27  4:13 ` Claude review: " Claude Code Review Bot
  2026-05-27  4:13 ` Claude Code Review Bot
  0 siblings, 2 replies; 3+ messages in thread
From: Zhenghang Xiao @ 2026-05-26  8:53 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann
  Cc: dri-devel, Zhenghang Xiao

drm_gem_change_handle_ioctl leaves the old handle live in the IDR
during the window between spin_unlock(table_lock) and the final
spin_lock(table_lock). A concurrent drm_gem_handle_delete on the old
handle succeeds in this window, decrements handle_count to 0, and frees
the GEM object while the new handle's IDR entry still references it.

NULL the old handle's IDR entry before dropping table_lock so that any
concurrent GEM_CLOSE on the old handle sees NULL and returns -EINVAL.
Restore the old entry on the prime-bookkeeping error path.

Fixes: 5e28b7b94408 ("drm: Set old handle to NULL before prime swap in change_handle")
Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
---
 drivers/gpu/drm/drm_gem.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 8afab57fc055..189b990cc78e 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -1065,6 +1065,7 @@ int drm_gem_change_handle_ioctl(struct drm_device *dev, void *data,
 	       goto out_unlock;
        }
 
+	idr_replace(&file_priv->object_idr, NULL, args->handle);
 	spin_unlock(&file_priv->table_lock);
 
 	if (obj->dma_buf) {
@@ -1073,6 +1074,7 @@ int drm_gem_change_handle_ioctl(struct drm_device *dev, void *data,
 		if (ret < 0) {
 			spin_lock(&file_priv->table_lock);
 			idr_remove(&file_priv->object_idr, handle);
+			idr_replace(&file_priv->object_idr, obj, args->handle);
 			spin_unlock(&file_priv->table_lock);
 			goto out_unlock;
 		}
-- 
2.50.1 (Apple Git-155)


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Claude review: drm/gem: fix race between change_handle and handle_delete
  2026-05-26  8:53 [PATCH drm] drm/gem: fix race between change_handle and handle_delete Zhenghang Xiao
@ 2026-05-27  4:13 ` Claude Code Review Bot
  2026-05-27  4:13 ` Claude Code Review Bot
  1 sibling, 0 replies; 3+ messages in thread
From: Claude Code Review Bot @ 2026-05-27  4:13 UTC (permalink / raw)
  To: dri-devel-reviews

Overall Series Review

Subject: drm/gem: fix race between change_handle and handle_delete
Author: Zhenghang Xiao <kipreyyy@gmail.com>
Patches: 1
Reviewed: 2026-05-27T14:13:41.988454

---

This is a single patch fixing a race condition in `drm_gem_change_handle_ioctl` where a concurrent `drm_gem_handle_delete` on the old handle can succeed during the window between allocating the new handle and removing the old one, leading to incorrect `handle_count` and potential use-after-free via `drm_gem_object_release_handle`.

The race analysis in the commit message is correct and the fix approach — NULLing the old handle's IDR entry before dropping `table_lock` — is sound. However, the patch is based on a tree that includes commit `5e28b7b94408` which is not present in the current drm-next tree. The code structure in drm-next is different (the `spin_unlock` after `idr_alloc` happens immediately at line 1047, not after the error check as the patch context implies). The patch does not apply cleanly and would need to be rebased.

There are also a few correctness concerns with the error-path restoration and a remaining race window that the patch doesn't address.

---
Generated by Claude Code Patch Reviewer

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Claude review: drm/gem: fix race between change_handle and handle_delete
  2026-05-26  8:53 [PATCH drm] drm/gem: fix race between change_handle and handle_delete Zhenghang Xiao
  2026-05-27  4:13 ` Claude review: " Claude Code Review Bot
@ 2026-05-27  4:13 ` Claude Code Review Bot
  1 sibling, 0 replies; 3+ messages in thread
From: Claude Code Review Bot @ 2026-05-27  4:13 UTC (permalink / raw)
  To: dri-devel-reviews

Patch Review

**Race analysis: correct.** In the current drm-next code at `drm_gem.c:1044-1069`, after `idr_alloc` at line 1045 creates the new handle and `spin_unlock` at line 1047 drops the lock, both the old handle (`args->handle`) and the new handle (`handle`) point to the same `obj` in the IDR. A concurrent `drm_gem_handle_delete(args->handle)` during this window would:

1. Successfully `idr_replace(NULL, args->handle)` — getting back `obj`
2. Call `drm_gem_object_release_handle(args->handle, obj, filp)` — decrementing `handle_count`
3. `idr_remove(args->handle)`

This leaves the new handle live in the IDR but with `handle_count` decremented, which is wrong.

**Fix approach: correct.** NULLing the old handle via `idr_replace` before dropping the spinlock ensures concurrent `drm_gem_handle_delete` sees NULL and returns `-EINVAL` (see `drm_gem.c:407-410`):

```c
obj = idr_replace(&filp->object_idr, NULL, handle);
...
if (IS_ERR_OR_NULL(obj))
    return -EINVAL;
```

**Issue 1 — Patch does not apply to drm-next.** The patch context shows `spin_unlock` coming *after* the `idr_alloc` error check (`goto out_unlock`), implying the lock is held continuously from `idr_alloc` through to the new `idr_replace`. But drm-next releases the lock immediately after `idr_alloc` at line 1047, before the error check at line 1049. The Fixes tag references `5e28b7b94408 ("drm: Set old handle to NULL before prime swap in change_handle")` which presumably restructured this locking — but that commit is not in the current drm-next tree. This patch needs to be rebased against the correct base.

**Issue 2 — Unchecked `idr_replace` return value.** The added line:

```c
idr_replace(&file_priv->object_idr, NULL, args->handle);
```

does not check the return value. If a concurrent `drm_gem_handle_delete(args->handle)` ran between `drm_gem_object_lookup` (line 1033, which releases `table_lock` internally) and the later `spin_lock(table_lock)` (line 1044), the old handle could already be removed from the IDR, and `idr_replace` would return `ERR_PTR(-ENOENT)`. While this is silently ignored and doesn't crash, it means the function proceeds to create the new handle even though the old handle is already gone — leaving `handle_count` in an inconsistent state (new handle created without incrementing, old handle's decrement already happened via the concurrent delete). This is a pre-existing race between `drm_gem_object_lookup` and `table_lock`, but worth noting since the patch doesn't close it.

**Issue 3 — Error-path restoration correctness.** The error-path addition:

```c
spin_lock(&file_priv->table_lock);
idr_remove(&file_priv->object_idr, handle);
idr_replace(&file_priv->object_idr, obj, args->handle);
spin_unlock(&file_priv->table_lock);
```

is safe: because the old handle was NULLed while holding `table_lock`, any concurrent `drm_gem_handle_delete(args->handle)` would see NULL from its own `idr_replace` and return `-EINVAL` without removing the IDR entry. So the entry for `args->handle` still exists (just NULLed) and can be restored. This logic is correct.

**Minor — commit message vs Fixes tag clarity.** The Fixes tag says this patch fixes `5e28b7b94408`, but the commit message says the race exists in `drm_gem_change_handle_ioctl` generally. The race window between `idr_alloc` and `idr_remove` of the old handle exists in the drm-next code too (without `5e28b7b94408`). It would be helpful to clarify whether this is fixing a regression introduced by `5e28b7b94408` or the underlying race that `5e28b7b94408` failed to fully fix.

---
Generated by Claude Code Patch Reviewer

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-05-27  4:13 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-26  8:53 [PATCH drm] drm/gem: fix race between change_handle and handle_delete Zhenghang Xiao
2026-05-27  4:13 ` Claude review: " Claude Code Review Bot
2026-05-27  4:13 ` Claude Code Review Bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox