Netdev List
 help / color / mirror / Atom feed
From: Simon Horman <horms@kernel.org>
To: dddddd@hust.edu.cn
Cc: Simon Horman <horms@kernel.org>,
	netdev@vger.kernel.org, david@ixit.cz, error27@gmail.com,
	krzk@kernel.org, kees@kernel.org, kuba@kernel.org,
	sameo@linux.intel.com, michael.thalmeier@hale.at,
	dzm91@hust.edu.cn, hust-os-kernel-patches@googlegroups.com
Subject: Re: [PATCH net] nfc: pn533: fix use-after-free in pn533_recv_frame
Date: Tue,  7 Jul 2026 19:06:52 +0100	[thread overview]
Message-ID: <20260707180649.1434511-4-horms@kernel.org> (raw)
In-Reply-To: <20260627131345.1548407-1-dddddd@hust.edu.cn>

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://sashiko.dev
---
nfc: pn533: fix use-after-free in pn533_recv_frame

This commit adds a spinlock cmd_state_lock to serialize access to dev->cmd 
in pn533_recv_frame() and the command completion worker. It aims to prevent 
a use-after-free when a command is detached and freed while being 
concurrently received.

> diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c
> index d7bdbc82e2ba2..921e93a5f16f5 100644
> --- a/drivers/nfc/pn533/pn533.c
> +++ b/drivers/nfc/pn533/pn533.c

[ ... ]

> @@ -458,10 +477,10 @@ static int __pn533_send_async(struct pn533 *dev, u8 cmd_code,
>  	mutex_lock(&dev->cmd_lock);
>  
>  	if (!dev->cmd_pending) {
> -		dev->cmd = cmd;
> +		pn533_set_current_cmd(dev, cmd);
>  		rc = dev->phy_ops->send_frame(dev, req);
>  		if (rc) {
> -			dev->cmd = NULL;
> +			pn533_set_current_cmd(dev, NULL);

[Severity: High]
This is a pre-existing issue, but if dev->phy_ops->send_frame() fails, it
jumps to the error label and frees cmd. If a concurrent receive scheduled 
the complete work, could that work also free cmd, causing a double free?

>  			goto error;
>  		}

[ ... ]

> @@ -569,10 +588,10 @@ static void pn533_wq_cmd(struct work_struct *work)
>  
>  	mutex_unlock(&dev->cmd_lock);
>  
> -	dev->cmd = cmd;
> +	pn533_set_current_cmd(dev, cmd);
>  	rc = dev->phy_ops->send_frame(dev, cmd->req);
>  	if (rc < 0) {
> -		dev->cmd = NULL;
> +		pn533_set_current_cmd(dev, NULL);

[Severity: High]
This isn't a bug introduced by this patch, but if dev->phy_ops->send_frame() 
fails in pn533_wq_cmd(), cmd is freed. Does a race condition exist here 
similar to __pn533_send_async(), where concurrent complete work could also 
free cmd?

[Severity: High]
Additionally, this is also a pre-existing issue, but does this error path 
drop the command without calling complete_cb and without clearing 
dev->cmd_pending? Could this leave the command queue permanently hung 
upon transient bus errors?

>  		dev_kfree_skb(cmd->req);
>  		kfree(cmd);
>  		return;
>  	}

[ ... ]

> @@ -2165,6 +2184,15 @@ static int pn533_data_exchange_complete(struct pn533 *dev, void *_arg,
>   */
>  void pn533_recv_frame(struct pn533 *dev, struct sk_buff *skb, int status)
>  {
> +	unsigned long flags;
> +
> +	/*
> +	 * Hold cmd_state_lock across the whole receive path so the current
> +	 * command cannot be freed by pn533_send_async_complete() between the
> +	 * dev->cmd check and the stores into it.
> +	 */
> +	spin_lock_irqsave(&dev->cmd_state_lock, flags);
> +
>  	if (!dev->cmd)
>  		goto sched_wq;

[Severity: Medium]
This isn't a bug introduced by this patch, but if there is no active command 
(!dev->cmd), this jumps to sched_wq without freeing the skb. Does this leak 
the skb if an unexpected frame arrives?

>  
>  	dev->cmd->status = status;

[ ... ]

> @@ -2182,6 +2210,7 @@ void pn533_recv_frame(struct pn533 *dev, struct sk_buff *skb, int status)
>  
>  	if (pn533_rx_frame_is_ack(skb->data)) {
>  		dev_dbg(dev->dev, "%s: Received ACK frame\n", __func__);
> +		spin_unlock_irqrestore(&dev->cmd_state_lock, flags);
>  		dev_kfree_skb(skb);
>  		return;
>  	}

[Severity: High]
This is a pre-existing issue, but does pn533_rx_frame_is_ack() safely read 
from skb->data here? Since there doesn't appear to be a check for skb->len 
before calling it, could this result in an out-of-bounds read if a malformed 
or short frame is received?

      reply	other threads:[~2026-07-08 11:09 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-27 13:13 [PATCH net] nfc: pn533: fix use-after-free in pn533_recv_frame Yinhao Hu
2026-07-07 18:06 ` 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=20260707180649.1434511-4-horms@kernel.org \
    --to=horms@kernel.org \
    --cc=david@ixit.cz \
    --cc=dddddd@hust.edu.cn \
    --cc=dzm91@hust.edu.cn \
    --cc=error27@gmail.com \
    --cc=hust-os-kernel-patches@googlegroups.com \
    --cc=kees@kernel.org \
    --cc=krzk@kernel.org \
    --cc=kuba@kernel.org \
    --cc=michael.thalmeier@hale.at \
    --cc=netdev@vger.kernel.org \
    --cc=sameo@linux.intel.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