From: Shinichiro Kawasaki <shinichiro.kawasaki@wdc.com>
To: Chaitanya Kulkarni <ckulkarnilinux@gmail.com>
Cc: "haris.iqbal@ionos.com" <haris.iqbal@ionos.com>,
"jinpu.wang@ionos.com" <jinpu.wang@ionos.com>,
"yanjun.zhu@linux.dev" <yanjun.zhu@linux.dev>,
"grzegorz.prajsner@ionos.com" <grzegorz.prajsner@ionos.com>,
"axboe@kernel.dk" <axboe@kernel.dk>,
"linux-block@vger.kernel.org" <linux-block@vger.kernel.org>
Subject: Re: [PATCH] rnbd-clt: fix refcount underflow in device unmap path
Date: Tue, 27 Jan 2026 07:06:55 +0000 [thread overview]
Message-ID: <aXhLQmRudk7cSAnT@shinmob> (raw)
In-Reply-To: <20260112231928.68185-1-ckulkarnilinux@gmail.com>
On Jan 12, 2026 / 15:19, Chaitanya Kulkarni wrote:
> During device unmapping (triggered by module unload or explicit unmap),
> a refcount underflow occurs causing a use-after-free warning:
>
> [14747.574913] ------------[ cut here ]------------
> [14747.574916] refcount_t: underflow; use-after-free.
> [14747.574917] WARNING: lib/refcount.c:28 at refcount_warn_saturate+0x55/0x90, CPU#9: kworker/9:1/378
> [14747.574924] Modules linked in: rnbd_client(-) rtrs_client rnbd_server rtrs_server rtrs_core ...
> [14747.574998] CPU: 9 UID: 0 PID: 378 Comm: kworker/9:1 Tainted: G O N 6.19.0-rc3lblk-fnext+ #42 PREEMPT(voluntary)
> [14747.575005] Workqueue: rnbd_clt_wq unmap_device_work [rnbd_client]
> [14747.575010] RIP: 0010:refcount_warn_saturate+0x55/0x90
> [14747.575037] Call Trace:
> [14747.575038] <TASK>
> [14747.575038] rnbd_clt_unmap_device+0x170/0x1d0 [rnbd_client]
> [14747.575044] process_one_work+0x211/0x600
> [14747.575052] worker_thread+0x184/0x330
> [14747.575055] ? __pfx_worker_thread+0x10/0x10
> [14747.575058] kthread+0x10d/0x250
> [14747.575062] ? __pfx_kthread+0x10/0x10
> [14747.575066] ret_from_fork+0x319/0x390
> [14747.575069] ? __pfx_kthread+0x10/0x10
> [14747.575072] ret_from_fork_asm+0x1a/0x30
> [14747.575083] </TASK>
> [14747.575096] ---[ end trace 0000000000000000 ]---
>
> Befor this patch :-
>
> The bug is a double kobject_put() on dev->kobj during device cleanup.
>
> Kobject Lifecycle:
> kobject_init_and_add() sets kobj.kref = 1 (initialization)
> kobject_put() sets kobj.kref = 0 (should be called once)
>
> * Before this patch:
>
> rnbd_clt_unmap_device()
> rnbd_destroy_sysfs()
> kobject_del(&dev->kobj) [remove from sysfs]
> kobject_put(&dev->kobj) PUT #1 (WRONG!)
> kref: 1 to 0
> rnbd_dev_release()
> kfree(dev) [DEVICE FREED!]
>
> rnbd_destroy_gen_disk() [use-after-free!]
>
> rnbd_clt_put_dev()
> refcount_dec_and_test(&dev->refcount)
> kobject_put(&dev->kobj) PUT #2 (UNDERFLOW!)
> kref: 0 to -1 [WARNING!]
>
> The first kobject_put() in rnbd_destroy_sysfs() prematurely frees the
> device via rnbd_dev_release(), then the second kobject_put() in
> rnbd_clt_put_dev() causes refcount underflow.
>
> * After this patch :-
>
> Remove kobject_put() from rnbd_destroy_sysfs(). This function should
> only remove sysfs visibility (kobject_del), not manage object lifetime.
>
> Call Graph (FIXED):
>
> rnbd_clt_unmap_device()
> rnbd_destroy_sysfs()
> kobject_del(&dev->kobj) [remove from sysfs only]
> [kref unchanged: 1]
>
> rnbd_destroy_gen_disk() [device still valid]
>
> rnbd_clt_put_dev()
> refcount_dec_and_test(&dev->refcount)
> kobject_put(&dev->kobj) ONLY PUT (CORRECT!)
> kref: 1 to 0 [BALANCED]
> rnbd_dev_release()
> kfree(dev) [CLEAN DESTRUCTION]
>
> This follows the kernel pattern where sysfs removal (kobject_del) is
> separate from object destruction (kobject_put).
>
> Fixes: 581cf833cac4 ("block: rnbd: add .release to rnbd_dev_ktype")
> Signed-off-by: Chaitanya Kulkarni <ckulkarnilinux@gmail.com>
Recently, blktests introduced the kmemleak feature. With this, I observed that
rnbd/001 and rnbd/002 fail on v6.19-rc6 and v6.19-rc7 kernels with the kmemleak
report as follows:
unreferenced object 0xffff88826c5f8720 (size 8):
comm "check", pid 145048, jiffies 4301507712
hex dump (first 8 bytes):
72 6e 62 64 00 15 b3 a6 rnbd....
backtrace (crc f6c244b4):
__kmalloc_node_track_caller_noprof+0x69d/0x900
kstrdup+0x42/0xc0
kobject_set_name_vargs+0x44/0x110
kobject_init_and_add+0xcf/0x150
rnbd_clt_map_device_store.cold+0x164/0x792 [rnbd_client]
kernfs_fop_write_iter+0x3d6/0x5e0
vfs_write+0x52c/0xf80
ksys_write+0xfb/0x200
do_syscall_64+0x95/0x540
entry_SYSCALL_64_after_hwframe+0x76/0x7e
I bisected and found this commit ec19ed2b3e2a ("rnbd-clt: fix refcount underflow
in device unmap path") is the trigger. When I revert it from v6.19-rc6 tag, the
failure disappeared. I also found that,
- The commit message assumes that rnbd_clt_put_dev() calls kobject_put(),
but such call does not exist in the kernel v6.19-rc6.
- The commit message has the Fixes tag for the commit 581cf833cac4 ("block:
rnbd: add .release to rnbd_dev_ktype"), but that is not in the kernel
v6.19-rc6. Instead, the commit 581cf833cac4 is in block/for-7.0/block branch.
- The commit 581cf833cac4 added the kobject_put() call to rnbd_clt_put_dev()
that the commit ec19ed2b3e2a assumes.
So I think the commit ec19ed2b3e2a was meant for block/for-7.0/block branch.
> ---
> drivers/block/rnbd/rnbd-clt.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c
> index b781e8b99569..619b10f05a80 100644
> --- a/drivers/block/rnbd/rnbd-clt.c
> +++ b/drivers/block/rnbd/rnbd-clt.c
> @@ -1676,7 +1676,6 @@ static void rnbd_destroy_sysfs(struct rnbd_clt_dev *dev,
> /* To avoid deadlock firstly remove itself */
> sysfs_remove_file_self(&dev->kobj, sysfs_self);
> kobject_del(&dev->kobj);
> - kobject_put(&dev->kobj);
As to the current Linus master branch, the hank above was applied as the commit
ec19ed2b3e2a, but the commit 581cf833cac4 is missing. So one more kobject_put()
is missing. It caused the memory leak and the kmemleak feature detected it.
Haris and Jens,
I suggest to pick up 581cf833cac4 ("block: rnbd: add .release to
rnbd_dev_ktype") to v6.19-rc8 to fix the kmemleak issue on the Linus master
branch. I applied 581cf833cac4 on top of v6.18-rc7 kernel, and confirmed the
kmemleak failure disappears.
next prev parent reply other threads:[~2026-01-27 7:07 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-12 23:19 [PATCH] rnbd-clt: fix refcount underflow in device unmap path Chaitanya Kulkarni
2026-01-14 8:40 ` Jinpu Wang
2026-01-15 1:58 ` Chaitanya Kulkarni
2026-01-15 5:39 ` Jinpu Wang
2026-01-15 14:20 ` Jens Axboe
2026-01-15 14:22 ` Jens Axboe
2026-01-27 7:06 ` Shinichiro Kawasaki [this message]
2026-01-28 0:21 ` Chaitanya Kulkarni
2026-01-28 4:16 ` Jens Axboe
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=aXhLQmRudk7cSAnT@shinmob \
--to=shinichiro.kawasaki@wdc.com \
--cc=axboe@kernel.dk \
--cc=ckulkarnilinux@gmail.com \
--cc=grzegorz.prajsner@ionos.com \
--cc=haris.iqbal@ionos.com \
--cc=jinpu.wang@ionos.com \
--cc=linux-block@vger.kernel.org \
--cc=yanjun.zhu@linux.dev \
/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