All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Fan Wu" <fanwu01@zju.edu.cn>
Cc: "Marc Kleine-Budde" <mkl@pengutronix.de>,
	"Vincent Mailhol" <mailhol@kernel.org>,
	linux-can@vger.kernel.org,
	"Oliver Hartkopp" <socketcan@hartkopp.net>,
	"Oleksij Rempel" <o.rempel@pengutronix.de>
Subject: Re: [PATCH net v2] can: esd_usb: kill anchored URBs before freeing netdevs
Date: Fri, 10 Jul 2026 16:43:06 +0000	[thread overview]
Message-ID: <20260710164307.1C4171F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260709164159.497640-1-fanwu01@zju.edu.cn>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Missing bounds check on `dev->net_count` derived from untrusted USB device input leads to an out-of-bounds array write.
- [High] A zero-length message from the USB device causes an infinite loop in the RX completion handler.
- [High] Missing NULL check for `dev->nets[i]` array elements allows a malicious USB device to trigger a NULL pointer dereference.
- [High] Missing bounds validation on the URB buffer length allows an attacker-controlled USB device to trigger out-of-bounds heap memory reads.
--

--- Patch [1]: [PATCH net v2] can: esd_usb: kill anchored URBs before freeing netdevs ---
commit 61e5cb7cf9d6a05752ca57498b34f59417480dc7
Author: Fan Wu <fanwu01@zju.edu.cn>

can: esd_usb: kill anchored URBs before freeing netdevs

This patch reorders the teardown sequence in esd_usb_disconnect() to unregister
netdevs, unlink all URBs, and then free the netdevs. This resolves an issue
where the URB unlinking process accesses a freed netdev structure.

> diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c
> index d257440fa01ff..f41d4a0d140f7 100644
> --- a/drivers/net/can/usb/esd_usb.c
> +++ b/drivers/net/can/usb/esd_usb.c
> @@ -1390,10 +1390,13 @@ static void esd_usb_disconnect(struct usb_interface *intf)
>  				netdev = dev->nets[i]->netdev;
>  				netdev_info(netdev, "unregister\n");
>  				unregister_netdev(netdev);
> -				free_candev(netdev);
>  			}
>  		}
>  		unlink_all_urbs(dev);
> +		for (i = 0; i < dev->net_count; i++) {
> +			if (dev->nets[i])
> +				free_candev(dev->nets[i]->netdev);
> +		}
>  		kfree(dev);
>  	}
>  }

[Severity: High]
This is a pre-existing issue, but does this code in esd_usb_probe() allow a
regression where a USB device triggers an out-of-bounds heap write?

In esd_usb_probe():

	err = esd_usb_wait_msg(dev, msg);
	if (err < 0) {
		dev_err(&intf->dev, "no version message answer\n");
		goto free_msg;
	}

	dev->net_count = (int)msg->version_reply.nets;

[ ... ]

	/* do per device probing */
	for (i = 0; i < dev->net_count; i++)
		esd_usb_probe_one_net(intf, i);

If a USB device provides a version_reply.nets value up to 255, the driver
assigns it to dev->net_count without checking it against ESD_USB_MAX_NETS (2).

The initialization loop then iterates dev->net_count times, calling
esd_usb_probe_one_net():

	dev->nets[index] = priv;

Could this write past the bounds of the dev->nets array into adjacent memory?

[Severity: High]
This isn't a bug introduced by this patch, but does the RX completion handler
contain a regression leading to an infinite loop if a zero-length message is
received?

In esd_usb_read_bulk_callback():

	while (pos < urb->actual_length) {
		union esd_usb_msg *msg;

		msg = (union esd_usb_msg *)(urb->transfer_buffer + pos);

[ ... ]

		pos += msg->hdr.len * sizeof(u32); /* convert to # of bytes */

If a USB device provides a message with msg->hdr.len == 0, pos does not
increase.

The loop condition pos < urb->actual_length would remain true forever, causing
the loop to spin indefinitely.

[Severity: High]
This is a pre-existing issue, but does esd_usb_read_bulk_callback() dereference
a NULL pointer if a previous interface registration failed?

In esd_usb_probe(), if registering a netdev fails in esd_usb_probe_one_net()
due to memory exhaustion, it returns an error:

	for (i = 0; i < dev->net_count; i++)
		esd_usb_probe_one_net(intf, i);

The error is ignored and dev->nets[i] remains NULL.

Later in esd_usb_read_bulk_callback():

		case ESD_USB_CMD_CAN_RX:
			if (msg->rx.net >= dev->net_count) {
				dev_err(dev->udev->dev.parent, "format error\n");
				break;
			}

			esd_usb_rx_can_msg(dev->nets[msg->rx.net], msg);
			break;

If a USB device sends an ESD_USB_CMD_CAN_RX packet specifying the failed
interface's index, it passes the dev->net_count check.

Does the lack of a NULL check before passing the pointer to esd_usb_rx_can_msg()
cause a crash here?

[Severity: High]
This isn't a bug introduced by this patch, but does esd_usb_read_bulk_callback()
read past the URB buffer bounds?

In esd_usb_read_bulk_callback():

	while (pos < urb->actual_length) {
		union esd_usb_msg *msg;

		msg = (union esd_usb_msg *)(urb->transfer_buffer + pos);

		switch (msg->hdr.cmd) {

The code accesses the message fields before checking if the message size fits
within urb->actual_length.

Additionally, if the message length validation is missing, could this lead to an
out-of-bounds heap memory read in esd_usb_rx_can_msg()?

	memcpy(cfd->data, msg->rx.data_fd, len);

If msg->rx.data_fd falls near the end of the urb->transfer_buffer, this could
copy adjacent heap memory into the CAN frame, leaking memory contents.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260709164159.497640-1-fanwu01@zju.edu.cn?part=1

  reply	other threads:[~2026-07-10 16:43 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-09 10:46 [PATCH net] can: esd_usb: kill anchored URBs before freeing netdevs Fan Wu
2026-07-09 15:17 ` Jagielski, Jedrzej
2026-07-09 16:41 ` [PATCH net v2] " Fan Wu
2026-07-10 16:43   ` sashiko-bot [this message]
2026-07-10 10:47 ` [PATCH net] " sashiko-bot

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=20260710164307.1C4171F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=fanwu01@zju.edu.cn \
    --cc=linux-can@vger.kernel.org \
    --cc=mailhol@kernel.org \
    --cc=mkl@pengutronix.de \
    --cc=o.rempel@pengutronix.de \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=socketcan@hartkopp.net \
    /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.