Commit ec19ed2b3e2a for kernel

commit ec19ed2b3e2af8ec5380400cdee9cb6560144506
Author: Chaitanya Kulkarni <ckulkarnilinux@gmail.com>
Date:   Mon Jan 12 15:19:28 2026 -0800

    rnbd-clt: fix refcount underflow in device unmap path

    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>
    Acked-by: Jack Wang <jinpu.wang@ionos.com>
    Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>

diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c
index d1c354636315..8194a970f002 100644
--- a/drivers/block/rnbd/rnbd-clt.c
+++ b/drivers/block/rnbd/rnbd-clt.c
@@ -1662,7 +1662,6 @@ static void 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);
 	}
 }