Re: [BUG] firewire: core-cdev: refcount leak in iso_resource_work during resource cleanup

Takashi Sakamoto <[email protected]> Wed, 1 Apr 2026 15:57:41 +0900
Newsgroups gmane.linux.kernel.firewire.devel
Message-ID <[email protected]>
Hi,

On Tue, Mar 31, 2026 at 03:48:18PM -0400, Dingisoul wrote:
> Hi Kernel maintainers,
> 
> We found a possible refcount leak in iso_resource_work.
> 
> When an iso_resource is being freed in iso_resource_work,
> cancel_delayed_work is called. If this call successfully 
> cancels a pending work item, the client reference acquired
> when that work was scheduled is never released.
> 
> static void schedule_iso_resource(struct iso_resource *r,
>                                    unsigned long delay)
> {
>     client_get(r->client); // 1. Reference taken
>     if (!queue_delayed_work(fw_workqueue, &r->work, delay))
>         client_put(r->client);
> }
> 
> 
> static void iso_resource_work(struct work_struct *work)
> {
>     struct iso_resource *r = from_work(r, work, work.work);
>     if (free) {
>         cancel_delayed_work(&r->work); // 2. Potential leak
>         kfree(r->e_alloc);
>         kfree(r->e_dealloc);
>         kfree(r);
>     }
> }

We could see the "client_put()" at the line after "out" label.

$ git show v6.19:drivers/firewire/core-cdev.c | cat -n
      ...
1317  static void iso_resource_work(struct work_struct *work)
1318  {
          ...
1321      struct client *client = r->client;
          ...
	  (no return statements)
          ...
1401      if (free) {
1402          cancel_delayed_work(&r->work);
1403          kfree(r->e_alloc);
1404          kfree(r->e_dealloc);
1405          kfree(r);
1406      }
1407   out:
1408      client_put(client);
1409  }

I guess the above lines are not necessarily friendly to any of your
tools. I would be glad to receive any patches or ideas inspired by your
testing mindset.


Thanks

Takashi Sakamoto