All of lore.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.