Re: [PATCH RFC] nbd: fix resource leak when device is abandoned

Aleksandr Nogikh <[email protected]>
Newsgroups dev.linux.lists.syzbot
Message-ID <CANp29Y41Hp3hg2X-+C=MFRnR+30LFB-mjv9WzbtKHqcUP0B4TQ@mail.gmail.com>
The reasoning went astray since the reproducer crashed as `BUG:
MAX_LOCKDEP_KEYS too low!`. The agent started fixing a completely
different issue.

#syz reject

On Fri, May 29, 2026 at 10:12 PM 'syzbot' via
syzkaller-upstream-moderation
<[email protected]> wrote:
>
> When a user-space process configures an NBD device via netlink but exits
> without explicitly disconnecting it or opening the block device, the NBD
> device and its request queue are leaked. The leaked request queues hold
> dynamically registered lock classes. When this happens repeatedly, it
> exhausts the MAX_LOCKDEP_KEYS limit and triggers a lockdep BUG.
>
> The leak occurs because the initial configuration reference (config_refs)
> is set to 1 during configuration. If the process exits, the sockets are
> closed and the recv_work threads exit, but the initial reference is never
> dropped unless the device is explicitly disconnected or the
> NBD_CFLAG_DESTROY_ON_DISCONNECT flag was set. As a result, the device is
> considered in use and skipped during subsequent device allocations, leading
> to unbounded creation of new devices and request queues.
>
> Fix this by scheduling disconnect_work to tear down the device when all
> sockets are closed and the disk has no openers, even if
> NBD_DESTROY_ON_DISCONNECT is not set. This ensures the initial
> configuration reference is dropped, allowing the device configuration to be
> freed and the device to become eligible for reuse, preventing the resource
> leak and the lockdep crash.
>
> Fixes: e46c7287b1c2 ("nbd: add a basic netlink interface")
> Assisted-by: Gemini:gemini-3.1-pro-preview Gemini:gemini-3-flash-preview syzbot
> Reported-by: [email protected]
> Closes: https://syzkaller.appspot.com/bug?extid=6279b273d888c2017726
> Link: https://syzkaller.appspot.com/ai_job?id=f2b193da-12d6-456c-8401-8680f8682836
> To: "Jens Axboe" <[email protected]>
> To: "Josef Bacik" <[email protected]>
> To: <[email protected]>
> To: <[email protected]>
> Cc: <[email protected]>
>
> ---
> diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
> index fe63f3c55..d31c8e5e3 100644
> --- a/drivers/block/nbd.c
> +++ b/drivers/block/nbd.c
> @@ -124,6 +124,7 @@ struct nbd_device {
>         struct gendisk *disk;
>         struct workqueue_struct *recv_workq;
>         struct work_struct remove_work;
> +       struct work_struct disconnect_work;
>
>         struct list_head list;
>         struct task_struct *task_setup;
> @@ -322,7 +323,15 @@ static void nbd_mark_nsock_dead(struct nbd_device *nbd, struct nbd_sock *nsock,
>                                 set_bit(NBD_RT_DISCONNECTED,
>                                         &nbd->config->runtime_flags);
>                                 dev_info(nbd_to_dev(nbd),
> -                                       "Disconnected due to user request.\n");
> +                                        "Disconnected due to user request.\n");
> +                       }
> +                       if (test_bit(NBD_DESTROY_ON_DISCONNECT, &nbd->flags) ||
> +                           disk_openers(nbd->disk) == 0) {
> +                               if (refcount_inc_not_zero(&nbd->refs)) {
> +                                       if (!queue_work(system_wq,
> +                                                       &nbd->disconnect_work))
> +                                               nbd_put(nbd);
> +                               }
>                         }
>                 }
>         }
> @@ -1904,6 +1913,8 @@ static const struct blk_mq_ops nbd_mq_ops = {
>         .timeout        = nbd_xmit_timeout,
>  };
>
> +static void nbd_disconnect_work(struct work_struct *work);
> +
>  static struct nbd_device *nbd_dev_add(int index, unsigned int refs)
>  {
>         struct queue_limits lim = {
> @@ -1928,6 +1939,7 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs)
>         nbd->tag_set.flags = BLK_MQ_F_BLOCKING;
>         nbd->tag_set.driver_data = nbd;
>         INIT_WORK(&nbd->remove_work, nbd_dev_remove_work);
> +       INIT_WORK(&nbd->disconnect_work, nbd_disconnect_work);
>         nbd->backend = NULL;
>
>         err = blk_mq_alloc_tag_set(&nbd->tag_set);
> @@ -2272,6 +2284,14 @@ static void nbd_disconnect_and_put(struct nbd_device *nbd)
>                 nbd_config_put(nbd);
>  }
>
> +static void nbd_disconnect_work(struct work_struct *work)
> +{
> +       struct nbd_device *nbd =
> +               container_of(work, struct nbd_device, disconnect_work);
> +       nbd_disconnect_and_put(nbd);
> +       nbd_put(nbd);
> +}
> +
>  static int nbd_genl_disconnect(struct sk_buff *skb, struct genl_info *info)
>  {
>         struct nbd_device *nbd;
>
>
> base-commit: e7ae89a0c97ce2b68b0983cd01eda67cf373517d
> --
> This is an AI-generated patch subject to moderation.
> Reply with '#syz upstream' to Sign-off the patch as a human author
> and send it to the upstream kernel mailing lists.
> Reply with '#syz reject' to reject it ('#syz unreject' to undo).
>
> See https://goo.gle/syzbot-ai-patches for information about AI-generated patches.
> You can comment on the patch as usual, syzbot will try to address
> the comments and send a new version of the patch if necessary.
> syzbot engineers can be reached at [email protected].
>
> --
> You received this message because you are subscribed to the Google Groups "syzkaller-upstream-moderation" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
> To view this discussion visit https://groups.google.com/d/msgid/syzkaller-upstream-moderation/a51a0826-f36a-4cef-8945-c9968b232f22%40mail.kernel.org.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.