From: Simon Horman <horms@kernel.org>
To: netdev-bot+sashiko@kernel.org
Cc: tristmd@gmail.com, david@ixit.cz, davem@davemloft.net,
edumazet@kernel.org, kuba@kernel.org, pabeni@redhat.com,
linville@tuxdriver.com, sameo@linux.intel.com,
oe-linux-nfc@lists.linux.dev, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
tristan@talencesecurity.com
Subject: Re: [PATCH net] nfc: llcp: use timer_shutdown_sync to prevent timer rearm
Date: Thu, 29 Oct 2026 15:46:40 +0000 [thread overview]
Message-ID: <20261029154640.GJ257209@horms.kernel.org> (raw)
In-Reply-To: <179308777133.3134.14547624262445573198@kernel.org>
On Tue, Oct 27, 2026 at 07:56:11AM +0000, netdev-bot+sashiko@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential
> issue(s) to consider.
>
> Critical: 0 · High: 1 · Medium: 0 · Low: 0
>
> If you believe none of the issues are legitimate, please reply to each
> issue of Medium severity or higher and explain why the AI is wrong.
> If any of them are legitimate and you plan to respin, please let patchwork
> know by including "pw-bot: cr" as a separate line at the end of your reply
> (one such reply per series is enough).
>
> - [High] The fix is incomplete.
>
> --
>
> nfc: llcp: use timer_shutdown_sync to prevent timer rearm
>
> This commit switches link_timer and sdreq_timer in local_cleanup() from
> timer_delete_sync() to timer_shutdown_sync(). The goal is to stop the
> associated work items from re-arming the timers while cancel_work_sync()
> runs, so that no deferred work runs after kfree(local).
>
> > diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
> > index 74bf817007cf2..a098d72a15ba8 100644
> > --- a/net/nfc/llcp_core.c
> > +++ b/net/nfc/llcp_core.c
> > @@ -173,14 +173,14 @@ static struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
> > static void local_cleanup(struct nfc_llcp_local *local)
> > {
> > nfc_llcp_socket_release(local, false, ENXIO);
> > - timer_delete_sync(&local->link_timer);
> > + timer_shutdown_sync(&local->link_timer);
> > skb_queue_purge(&local->tx_queue);
> > cancel_work_sync(&local->tx_work);
> > cancel_work_sync(&local->rx_work);
>
> [Severity: High]
> Does this fully close the use-after-free described in the commit message?
> The timers can no longer be re-armed. But tx_work, rx_work, timeout_work
> and sdreq_timeout_work still use cancel_work_sync(), and that does not
> stop them from being queued again afterwards.
>
> tx_work is cancelled before rx_work, and nfc_llcp_rx_work() always queues
> tx_work:
>
> net/nfc/llcp_core.c:nfc_llcp_rx_work() {
> ...
> nfc_llcp_rx_skb(local, skb);
>
> schedule_work(&local->tx_work);
> ...
> }
>
> Suppose rx_work is running when local_cleanup() reaches
> cancel_work_sync(&local->rx_work). That cancel waits for it, and in the
> meantime rx_work queues tx_work again. local_cleanup() then returns and
> local_release_work() does:
>
> local_cleanup(local);
> kfree(local);
>
> Can nfc_llcp_tx_work() then run on the freed local? It would touch
> local->tx_queue, call nfc_data_exchange(local->dev, ...) and call
> mod_timer(&local->link_timer). The pending tx_work work_struct inside the
> freed object would also still be linked on system_wq.
>
> Here is one way rx_work can be running during the final cleanup:
>
> nfc_llcp_data_received()
> nfc_llcp_find_local() /* takes a reference */
> nfc_llcp_unregister_device()
> nfc_llcp_remove_local()
> local_cleanup()
> nfc_llcp_local_put()
> __nfc_llcp_recv()
> schedule_work(&local->rx_work) /* system_wq */
> nfc_llcp_local_put() /* last ref, queues release_work on llcp_wq */
>
> After this, rx_work and release_work run at the same time on different
> workqueues.
>
> Digital drivers can reach this. nfc_digital_unregister_device() calls
> nfc_unregister_device() before cancel_work_sync(&ddev->cmd_complete_work).
> That lets
> digital_tg_recv_dep_req()->nfc_tm_data_received()->nfc_llcp_data_received()
> overlap with LLCP teardown. nfc_tm_data_received() checks dep_link_up but
> not shutting_down.
>
> There is a related path. nfc_llcp_tx_work() passes the raw local pointer
> to nfc_data_exchange() as the context for nfc_llcp_recv(), and it takes no
> reference:
>
> ret = nfc_data_exchange(local->dev, local->target_idx,
> skb, nfc_llcp_recv, local);
>
> For digital devices, this completion runs from cmd_complete_work, which is
> only cancelled after nfc_unregister_device(). A late completion goes
> through nfc_llcp_recv()->__nfc_llcp_recv(), which writes local->rx_pending
> and calls schedule_work(&local->rx_work). The local it touches may already
> have been through local_cleanup(), or may already be freed.
>
> Would disable_work_sync() work for the LLCP work items, or at least
> disabling rx_work before tx_work? That would match what
> timer_shutdown_sync() does for the timers.
This does seem to be a legitimate concern.
--
pw-bot: changes-requested
prev parent reply other threads:[~2026-10-29 15:46 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-23 19:54 [PATCH net] nfc: llcp: use timer_shutdown_sync to prevent timer rearm Tristan Madani
2026-10-23 19:55 ` netdev-bot+sinfo
2026-10-25 22:27 ` Tristan Madani
2026-10-25 22:28 ` Tristan Madani
2026-10-27 7:56 ` netdev-bot+sashiko
2026-10-29 15:46 ` 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=20261029154640.GJ257209@horms.kernel.org \
--to=horms@kernel.org \
--cc=davem@davemloft.net \
--cc=david@ixit.cz \
--cc=edumazet@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=netdev-bot+sashiko@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=oe-linux-nfc@lists.linux.dev \
--cc=pabeni@redhat.com \
--cc=sameo@linux.intel.com \
--cc=stable@vger.kernel.org \
--cc=tristan@talencesecurity.com \
--cc=tristmd@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox