All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Marc Kleine-Budde" <mkl@pengutronix.de>
Cc: "Marc Kleine-Budde" <mkl@pengutronix.de>,
	linux-can@vger.kernel.org,
	"Oleksij Rempel" <o.rempel@pengutronix.de>,
	"Vincent Mailhol" <mailhol@kernel.org>,
	"Oliver Hartkopp" <socketcan@hartkopp.net>
Subject: Re: [PATCH net 10/20] can: peak_usb: add bounds check for USB channel index
Date: Thu, 30 Jul 2026 10:29:51 +0000	[thread overview]
Message-ID: <20260730102952.3DF481F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260729102802.505168-11-mkl@pengutronix.de>

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

Pre-existing issues:
- [High] Unvalidated CAN payload length from the USB packet causes a heap buffer overflow when copying data into the SKB and reading from the URB buffer.
- [High] Inadequate bounds checking allows a NULL pointer dereference of uninitialized channel device pointers.
- [High] Race condition during probe exposes the network interface before driver initialization is complete, leading to a NULL pointer dereference.
--

--- Patch [10]: [PATCH net 10/20] can: peak_usb: add bounds check for USB channel index ---
commit bda9ca94a61ede6bd59945cb6b8e4a5d2a8b5017
Author: James Gao <jamesgao5@outlook.com>

can: peak_usb: add bounds check for USB channel index

The channel control index ctrl_idx is derived from rx->len which comes
directly from a device USB payload. The mask 0x0f allows values 0-15, but
the array size of usb_if->dev[] is only 2. Values 2-15 cause heap
out-of-bounds read, eventually causing kernel panic in the IRQ context.

Link: https://patch.msgid.link/TYWPR01MB8559DBAAAA6A7F410400329CF0012@TYWPR01MB8559.jpnprd01.prod.outlook.com

> diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
> index aefcded8e12a8..b6be8c19e537f 100644
> --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
> +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
> @@ -534,12 +534,18 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if,
>  				      struct pcan_usb_pro_rxmsg *rx)
>  {
>  	const unsigned int ctrl_idx = (rx->len >> 4) & 0x0f;
> -	struct peak_usb_device *dev = usb_if->dev[ctrl_idx];
> -	struct net_device *netdev = dev->netdev;
> +	struct peak_usb_device *dev;
> +	struct net_device *netdev;
>  	struct can_frame *can_frame;
>  	struct sk_buff *skb;
>  	struct skb_shared_hwtstamps *hwts;
>  
> +	if (ctrl_idx >= ARRAY_SIZE(usb_if->dev))
> +		return -EINVAL;
> +
> +	dev = usb_if->dev[ctrl_idx];
> +	netdev = dev->netdev;

[Severity: High]
This isn't a bug introduced by this patch, but does checking against
ARRAY_SIZE() fully protect against NULL pointer dereferences here?

If a single-channel adapter is used, usb_if->dev[1] might be left
uninitialized (NULL). If a device sends URBs for channel 1, wouldn't it
bypass the ARRAY_SIZE() check and cause a kernel panic when dereferencing
dev->netdev?

There appears to be an identical inadequate bounds check in the FD variant
of the driver at pcan_usb_fd_decode_canmsg().

[Severity: High]
This is a pre-existing issue, but does this code overflow can_frame->data[]
when copying the payload?

Looking further down in pcan_usb_pro_handle_canmsg():

    can_frame->len = rx->len & 0x0f;
    ...
    } else {
        memcpy(can_frame->data, rx->data, can_frame->len);
    }

Since rx->len & 0x0f allows values up to 15, and can_frame->data[] is only an
8-byte array, could a malicious device send an oversized payload length and
overflow can_frame->data[]?

> +
>  	skb = alloc_can_skb(netdev, &can_frame);
>  	if (!skb)
>  		return -ENOMEM;

[ ... ]

> @@ -573,14 +579,20 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if,
>  {
>  	const u16 raw_status = le16_to_cpu(er->status);
>  	const unsigned int ctrl_idx = (er->channel >> 4) & 0x0f;
> -	struct peak_usb_device *dev = usb_if->dev[ctrl_idx];
> -	struct net_device *netdev = dev->netdev;
> +	struct peak_usb_device *dev;
> +	struct net_device *netdev;
>  	struct can_frame *can_frame;
>  	enum can_state new_state = CAN_STATE_ERROR_ACTIVE;
>  	u8 err_mask = 0;
>  	struct sk_buff *skb;
>  	struct skb_shared_hwtstamps *hwts;
>  
> +	if (ctrl_idx >= ARRAY_SIZE(usb_if->dev))
> +		return -EINVAL;
> +
> +	dev = usb_if->dev[ctrl_idx];
> +	netdev = dev->netdev;
> +
>  	/* nothing should be sent while in BUS_OFF state */
>  	if (dev->can.state == CAN_STATE_BUS_OFF)
>  		return 0;

[Severity: High]
This is a pre-existing issue, but is there a race condition during probe
that could expose the network interface before driver initialization is
complete?

In peak_usb_create_dev(), register_candev() is called before the interface
is fully initialized:

drivers/net/can/usb/peak_usb/pcan_usb_core.c:peak_usb_create_dev() {
    ...
    err = register_candev(netdev);
    ...
}

If userspace immediately brings the interface up (e.g., via udev),
pcan_usb_pro_start() is called and dereferences pdev->usb_if:

drivers/net/can/usb/peak_usb/pcan_usb_pro.c:pcan_usb_pro_start() {
    ...
    if (pdev->usb_if->dev_opened_count == 0) {
    ...
}

Since pdev->usb_if is only allocated and assigned later in
pcan_usb_pro_init(), wouldn't this cause a NULL pointer dereference?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260729102802.505168-1-mkl@pengutronix.de?part=10

  reply	other threads:[~2026-07-30 10:29 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-29 10:12 [PATCH net 0/20] pull-request: can 2026-07-29 Marc Kleine-Budde
2026-07-29 10:12 ` [PATCH net 01/20] can: j1939: use netdevice_tracker for j1939_{priv,session,ecu} tracking Marc Kleine-Budde
2026-07-30 10:29   ` sashiko-bot
2026-07-30 13:20   ` patchwork-bot+netdevbpf
2026-07-29 10:12 ` [PATCH net 02/20] can: j1939: transport: j1939_session_fresh_new(): initialize receive buffer Marc Kleine-Budde
2026-07-29 10:12 ` [PATCH net 03/20] can: isotp: fix timer drain order, wakeup handling and tx_gen ordering Marc Kleine-Budde
2026-07-30 10:29   ` sashiko-bot
2026-07-30 12:28     ` Oliver Hartkopp
2026-07-29 10:12 ` [PATCH net 04/20] can: isotp: check register_netdevice_notifier() error in module init Marc Kleine-Budde
2026-07-29 10:12 ` [PATCH net 05/20] can: ctucanfd: unmap BAR0 using base address Marc Kleine-Budde
2026-07-29 10:12 ` [PATCH net 06/20] can: ctucanfd: mark error-active controller status valid Marc Kleine-Budde
2026-07-30 10:29   ` sashiko-bot
2026-07-30 11:14     ` Marc Kleine-Budde
2026-07-29 10:12 ` [PATCH net 07/20] can: ctucanfd: handle bus error interrupts Marc Kleine-Budde
2026-07-30 10:29   ` sashiko-bot
2026-07-30 11:18     ` Marc Kleine-Budde
2026-07-29 10:12 ` [PATCH net 08/20] can: ctucanfd: use self-test mode for PRESUME_ACK Marc Kleine-Budde
2026-07-30 10:29   ` sashiko-bot
2026-07-30 11:25     ` Marc Kleine-Budde
2026-07-29 10:12 ` [PATCH net 09/20] can: ctucanfd: add missing MODULE_DEVICE_TABLE() Marc Kleine-Budde
2026-07-29 10:12 ` [PATCH net 10/20] can: peak_usb: add bounds check for USB channel index Marc Kleine-Budde
2026-07-30 10:29   ` sashiko-bot [this message]
2026-07-29 10:12 ` [PATCH net 11/20] can: peak_usb: peak_usb_start(): fix double free of transfer buffer on URB submit error Marc Kleine-Budde
2026-07-30 10:29   ` sashiko-bot
2026-07-29 10:12 ` [PATCH net 12/20] can: peak_usb: validate uCAN receive record lengths Marc Kleine-Budde
2026-07-30 10:29   ` sashiko-bot
2026-07-29 10:12 ` [PATCH net 13/20] can: kvaser_usb: kvaser_usb_hydra_get_busparams(): fix memory leak in kvaser_usb_hydra_get_busparams() Marc Kleine-Budde
2026-07-29 10:12 ` [PATCH net 14/20] can: kvaser_usb_leaf: kvaser_usb_leaf_wait_cmd(): validate received command extents Marc Kleine-Budde
2026-07-30 10:29   ` sashiko-bot
2026-07-29 10:12 ` [PATCH net 15/20] can: rcar_canfd: change the initializing flow for clocks and resets Marc Kleine-Budde
2026-07-30 10:29   ` sashiko-bot
2026-07-29 10:12 ` [PATCH net 16/20] can: softing: fw_parse(): validate firmware record spans Marc Kleine-Budde
2026-07-30 10:29   ` sashiko-bot
2026-07-29 10:12 ` [PATCH net 17/20] can: c_can: c_can_chip_config(): keep controller in init mode until bittiming is configured Marc Kleine-Budde
2026-07-30 10:30   ` sashiko-bot
2026-07-29 10:12 ` [PATCH net 18/20] can: gs_usb: gs_usb_receive_bulk_callback(): resubmit URB on skb allocation failure Marc Kleine-Budde
2026-07-29 10:12 ` [PATCH net 19/20] can: etas_es58x: es58x_read_bulk_callback(): fix RX buffer leak on URB resubmit failure Marc Kleine-Budde
2026-07-29 10:13 ` [PATCH net 20/20] can: ems_usb: validate CPC message lengths Marc Kleine-Budde
2026-07-30 10:30   ` 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=20260730102952.3DF481F00A3A@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --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.