public inbox for linux-block@vger.kernel.org
 help / color / mirror / Atom feed
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.

  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