From: Claude Code Review Bot <claude-review@example.com>
To: dri-devel-reviews@example.com
Subject: Claude review: misc: fastrpc: Add reference counting for fastrpc_user structure
Date: Fri, 27 Feb 2026 11:57:24 +1000 [thread overview]
Message-ID: <review-patch1-20260226151121.818852-1-anandu.e@oss.qualcomm.com> (raw)
In-Reply-To: <20260226151121.818852-1-anandu.e@oss.qualcomm.com>
Patch Review
**kref_init placement is after the user becomes visible (BUG)**
In `fastrpc_device_open()`, the patch places `kref_init()` **after** `list_add_tail()`:
```c
spin_lock_irqsave(&cctx->lock, flags);
list_add_tail(&fl->user, &cctx->users);
spin_unlock_irqrestore(&cctx->lock, flags);
+ kref_init(&fl->refcount);
```
At this point `fl` is already visible on `cctx->users`. If `fastrpc_rpmsg_remove()` runs on another CPU between `list_add_tail()` and `kref_init()`, it will iterate `cctx->users` and could operate on this user with a zero refcount (from `kzalloc` zero-init). The `kref_init()` should be placed alongside the other initialization calls (near `spin_lock_init`, `mutex_init`, etc.) **before** the user is linked into any list:
```c
fl->is_secure_dev = fdevice->secure;
+ kref_init(&fl->refcount);
fl->sctx = fastrpc_session_alloc(fl);
...
list_add_tail(&fl->user, &cctx->users);
```
**fastrpc_user_free only does partial cleanup — by design, but deserves a comment**
```c
+static void fastrpc_user_free(struct kref *ref)
+{
+ struct fastrpc_user *fl = container_of(ref, struct fastrpc_user, refcount);
+
+ fastrpc_channel_ctx_put(fl->cctx);
+ mutex_destroy(&fl->mutex);
+ kfree(fl);
+}
```
This only frees the struct, the mutex, and the cctx reference. All heavyweight cleanup (session free, DSP process release, pending context teardown, map/mmap cleanup) remains in `fastrpc_device_release()`. This is correct — the refcount only extends the *lifetime of the struct* past device release, not the logical ownership. But a brief comment in `fastrpc_user_free()` noting this would help future readers understand that this is intentional and that full teardown is done in `fastrpc_device_release()`.
**Channel context reference accounting is correct**
I verified there is no double-put of `cctx`. The references are:
| Get | Put |
|-----|-----|
| `fastrpc_device_open()` → `fastrpc_channel_ctx_get(cctx)` | `fastrpc_user_free()` → `fastrpc_channel_ctx_put(fl->cctx)` |
| `fastrpc_context_alloc()` → `fastrpc_channel_ctx_get(cctx)` | `fastrpc_context_free()` → `fastrpc_channel_ctx_put(cctx)` (existing, line 524) |
In `fastrpc_context_free()`, the new `fastrpc_user_put(fl)` is called before the existing `fastrpc_channel_ctx_put(cctx)`:
```c
+ /* Release the reference taken in fastrpc_context_alloc() */
+ fastrpc_user_put(fl);
fastrpc_channel_ctx_put(cctx);
```
Even if `fastrpc_user_put()` triggers `fastrpc_user_free()` (which puts the *user's* cctx ref), the *context's* cctx ref still keeps `cctx` alive for the next line. This ordering is safe.
**Error path in fastrpc_context_alloc is correct**
```c
+ fastrpc_user_put(user);
fastrpc_channel_ctx_put(cctx);
```
The error path correctly balances the `fastrpc_user_get(user)` taken earlier in the function.
**fastrpc_buf_free safety during workqueue-deferred context_free**
The key UAF scenario the patch addresses: `fastrpc_buf_free()` at `fastrpc.c:417` dereferences `buf->fl->cctx`. In the patched code, when `fastrpc_context_free()` is called from the workqueue, `fastrpc_buf_free(ctx->buf)` runs *before* `fastrpc_user_put(fl)`, so the user struct is guaranteed alive. This is correct.
**Minor: redundant comment on struct member**
```c
+ /* Reference count */
+ struct kref refcount;
```
The `kref` type already implies reference counting. This comment adds no information. Consider dropping it to match the style of `struct kref refcount` used elsewhere in the same file (e.g., in `fastrpc_channel_ctx`).
**Summary of required changes:**
1. **Must fix:** Move `kref_init(&fl->refcount)` before `list_add_tail()` in `fastrpc_device_open()` to close the race window.
2. **Nice to have:** Add a comment in `fastrpc_user_free()` clarifying that full teardown is in `fastrpc_device_release()`, and this only extends struct lifetime.
---
Generated by Claude Code Patch Reviewer
next prev parent reply other threads:[~2026-02-27 1:57 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-26 15:11 [PATCH v1] misc: fastrpc: Add reference counting for fastrpc_user structure Anandu Krishnan E
2026-02-26 17:50 ` Bjorn Andersson
2026-02-27 1:57 ` Claude Code Review Bot [this message]
2026-02-27 1:57 ` Claude review: " Claude Code Review Bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=review-patch1-20260226151121.818852-1-anandu.e@oss.qualcomm.com \
--to=claude-review@example.com \
--cc=dri-devel-reviews@example.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox