All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Horman <horms@kernel.org>
To: bestswngs@gmail.com
Cc: Simon Horman <horms@kernel.org>,
	david@ixit.cz, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, oe-linux-nfc@lists.linux.dev,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	xmei5@asu.edu
Subject: Re: [PATCH net v2] nfc: digital: fix use-after-free in nfc_digital_unregister_device()
Date: Tue, 28 Jul 2026 13:10:43 +0100	[thread overview]
Message-ID: <20260728121043.896478-1-horms@kernel.org> (raw)
In-Reply-To: <20260723174450.1015153-2-bestswngs@gmail.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260723174450.1015153-2-bestswngs@gmail.com?part=1
---
Subject: nfc: digital: fix use-after-free in nfc_digital_unregister_device()

This patch replaces cancel_work_sync() with disable_work_sync() on
cmd_work and cmd_complete_work in nfc_digital_unregister_device() so
that re-arming schedule_work() calls become no-ops before the cmd_queue
is freed.

> diff --git a/net/nfc/digital_core.c b/net/nfc/digital_core.c
> index 7cb1e6aaae90..6def5132a4a6 100644
> --- a/net/nfc/digital_core.c
> +++ b/net/nfc/digital_core.c
> @@ -843,8 +843,8 @@ void nfc_digital_unregister_device(struct nfc_digital_dev *ddev)
>  	mutex_unlock(&ddev->poll_lock);
>  
>  	cancel_delayed_work_sync(&ddev->poll_work);
> -	cancel_work_sync(&ddev->cmd_work);
> -	cancel_work_sync(&ddev->cmd_complete_work);
> +	disable_work_sync(&ddev->cmd_work);
> +	disable_work_sync(&ddev->cmd_complete_work);

[High]
Does this fully close the use-after-free window, or only the workqueue
re-arm portion of it?

Once digital_wq_cmd() has handed a command to the driver via
ops->in_send_cmd(..., digital_send_cmd_complete, cmd), the driver
retains a raw pointer to that digital_cmd in its own async machinery
(for nfcsim this is dev->recv_work / dev->arg, for real drivers it is
URB completions, timers, etc.).

disable_work_sync() on cmd_work and cmd_complete_work waits only for
those two work items; it does not synchronize the driver's async
completion path.  When that completion later fires it calls back into
digital_send_cmd_complete():

    static void digital_send_cmd_complete(struct nfc_digital_dev *ddev,
                                          void *arg, struct sk_buff *resp)
    {
            struct digital_cmd *cmd = arg;

            cmd->resp = resp;

            schedule_work(&ddev->cmd_complete_work);
    }

The subsequent schedule_work() is correctly a no-op after
disable_work_sync(), but the cmd->resp = resp store happens first, on
a digital_cmd that the cleanup loop in nfc_digital_unregister_device()
may already have kfree()'d.

The same reproducer described in the commit message applies: in
nfcsim_device_free(), nfc_digital_unregister_device() runs before
cancel_work_sync(&dev->recv_work) and before dev->up = false, so a
pending dev->recv_work blocked in wait_event can wake up after the
queue has been freed and call dev->cb(ddev, dev->arg, skb) with
dev->arg pointing at a freed digital_cmd.

Elsewhere in this file the pattern for stopping in-flight commands
before touching the queue calls digital_abort_cmd(ddev) (see
digital_stop_poll(), digital_dep_link_down(), and
digital_deactivate_target()), which asks the driver to abort its
outstanding commands.  Would an equivalent digital_abort_cmd(ddev) in
nfc_digital_unregister_device(), before the list_for_each_entry_safe()
kfree loop, be needed here as well?

The commit message states:

    Once both works are disabled no work can run, and the cleanup
    loop frees the queue with no work able to reach a freed command.

Is that description accurate given that the driver's completion
callback reaches the digital_cmd directly through the arg pointer
rather than through cmd_work or cmd_complete_work?

This residual issue is pre-existing rather than introduced by the
patch, but it seems relevant to the completeness of the fix as
described.

      reply	other threads:[~2026-07-28 12:11 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-23 17:44 [PATCH net v2] nfc: digital: fix use-after-free in nfc_digital_unregister_device() Weiming Shi
2026-07-28 12:10 ` Simon Horman [this message]

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=20260728121043.896478-1-horms@kernel.org \
    --to=horms@kernel.org \
    --cc=bestswngs@gmail.com \
    --cc=davem@davemloft.net \
    --cc=david@ixit.cz \
    --cc=edumazet@google.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=oe-linux-nfc@lists.linux.dev \
    --cc=pabeni@redhat.com \
    --cc=xmei5@asu.edu \
    /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.