Linux CAN drivers development
 help / color / mirror / Atom feed
* [PATCH net] can: can327: Fix out-of-bounds write in can327_parse_frame()
@ 2026-08-18 21:50 Baul Lee
  2026-08-18 22:11 ` Max Staudt
  2026-08-19  5:52 ` Marc Kleine-Budde
  0 siblings, 2 replies; 3+ messages in thread
From: Baul Lee @ 2026-08-18 21:50 UTC (permalink / raw)
  To: max, mkl, mailhol; +Cc: linux-can, linux-kernel, federico.kirschbaum

can327_parse_frame() assigns the CAN payload length from the DLC nibble
of the adapter's ASCII frame line, hex_to_bin(elm->rxbuf[datastart - 2]),
without validating it. A standard-format line only has to satisfy
rxbuf[3] == ' ' and rxbuf[5] == ' ', so the DLC nibble rxbuf[4] can be a
space, for which hex_to_bin() returns -1, and that becomes 255 in the u8
frame->len. A hex nibble of 9 to f is not rejected either, while
CAN_MAX_DLEN is 8.

frame->data[] is the 8-byte payload of the 16-byte struct can_frame
returned by alloc_can_skb(), so the data-nibble loop writes up to 255
device-controlled bytes, 247 of them past the frame and over the
trailing skb_shared_info. The length check before the loop only requires
the line to be frame->len * 3 + datastart bytes, which a long enough
line of hex and spaces satisfies. Freeing the corrupted skb then faults:

  pc : skb_release_data+0xf4/0x200
  Call trace:
   skb_release_data+0xf4/0x200 (P)
   sk_skb_reason_drop+0x40/0xa4
   can_rcv+0x6c/0xbc
   __netif_receive_skb_one_core+0x40/0x4c
   can327_ldisc_rx+0xc8/0x140
   tty_ldisc_receive_buf+0x48/0x60
   flush_to_ldisc+0xdc/0x1b0
  Kernel panic - not syncing: Oops: Fatal exception in interrupt

Reject the line when the nibble is not a hex digit or exceeds
CAN_MAX_DLEN, as the parser already does for other malformed lines.

Attaching the N_CAN327 line discipline requires CAP_NET_ADMIN, but the
frame lines then come from the ELM327 device, so a malicious adapter
reaches this path with device-controlled data.

Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>

Fixes: 43da2f07622f ("can: can327: CAN/ldisc driver for ELM327 based OBD-II adapters")
Signed-off-by: Baul Lee <baul.lee@xbow.com>
---
 drivers/net/can/can327.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
index 90f5e35f3c8f..c76a6378d4d6 100644
--- a/drivers/net/can/can327.c
+++ b/drivers/net/can/can327.c
@@ -395,6 +395,7 @@ static int can327_parse_frame(struct can327 *elm, size_t len)
 	struct sk_buff *skb;
 	int hexlen;
 	int datastart;
+	int dlc;
 	int i;
 
 	lockdep_assert_held(&elm->lock);
@@ -460,7 +461,13 @@ static int can327_parse_frame(struct can327 *elm, size_t len)
 	 */
 
 	/* Read CAN data length */
-	frame->len = (hex_to_bin(elm->rxbuf[datastart - 2]) << 0);
+	dlc = hex_to_bin(elm->rxbuf[datastart - 2]);
+	if (dlc < 0 || dlc > CAN_MAX_DLEN) {
+		/* Not a hex digit, or more than CAN_MAX_DLEN bytes. */
+		kfree_skb(skb);
+		return -ENODATA;
+	}
+	frame->len = dlc;
 
 	/* Read CAN ID */
 	if (frame->can_id & CAN_EFF_FLAG) {
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH net] can: can327: Fix out-of-bounds write in can327_parse_frame()
  2026-08-18 21:50 [PATCH net] can: can327: Fix out-of-bounds write in can327_parse_frame() Baul Lee
@ 2026-08-18 22:11 ` Max Staudt
  2026-08-19  5:52 ` Marc Kleine-Budde
  1 sibling, 0 replies; 3+ messages in thread
From: Max Staudt @ 2026-08-18 22:11 UTC (permalink / raw)
  To: Baul Lee, mkl, mailhol; +Cc: linux-can, linux-kernel, federico.kirschbaum

Baul, thank you so much finding and patching this!

This should *really* go into the -stable trees as well. Can you please 
amend the commit to include the following three lines and then re-send it?


Fixes: 43da2f07622f ("can: can327: CAN/ldisc driver for ELM327 based 
OBD-II adapters")
Cc: stable@vger.kernel.org
Reviewed-by: Max Staudt <max@enpas.org>



Thank you!

Max


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH net] can: can327: Fix out-of-bounds write in can327_parse_frame()
  2026-08-18 21:50 [PATCH net] can: can327: Fix out-of-bounds write in can327_parse_frame() Baul Lee
  2026-08-18 22:11 ` Max Staudt
@ 2026-08-19  5:52 ` Marc Kleine-Budde
  1 sibling, 0 replies; 3+ messages in thread
From: Marc Kleine-Budde @ 2026-08-19  5:52 UTC (permalink / raw)
  To: Baul Lee; +Cc: max, mailhol, linux-can, linux-kernel, federico.kirschbaum

[-- Attachment #1: Type: text/plain, Size: 2136 bytes --]

On 19.08.2026 06:50:29, Baul Lee wrote:
> can327_parse_frame() assigns the CAN payload length from the DLC nibble
> of the adapter's ASCII frame line, hex_to_bin(elm->rxbuf[datastart - 2]),
> without validating it. A standard-format line only has to satisfy
> rxbuf[3] == ' ' and rxbuf[5] == ' ', so the DLC nibble rxbuf[4] can be a
> space, for which hex_to_bin() returns -1, and that becomes 255 in the u8
> frame->len. A hex nibble of 9 to f is not rejected either, while
> CAN_MAX_DLEN is 8.
>
> frame->data[] is the 8-byte payload of the 16-byte struct can_frame
> returned by alloc_can_skb(), so the data-nibble loop writes up to 255
> device-controlled bytes, 247 of them past the frame and over the
> trailing skb_shared_info. The length check before the loop only requires
> the line to be frame->len * 3 + datastart bytes, which a long enough
> line of hex and spaces satisfies. Freeing the corrupted skb then faults:
>
>   pc : skb_release_data+0xf4/0x200
>   Call trace:
>    skb_release_data+0xf4/0x200 (P)
>    sk_skb_reason_drop+0x40/0xa4
>    can_rcv+0x6c/0xbc
>    __netif_receive_skb_one_core+0x40/0x4c
>    can327_ldisc_rx+0xc8/0x140
>    tty_ldisc_receive_buf+0x48/0x60
>    flush_to_ldisc+0xdc/0x1b0
>   Kernel panic - not syncing: Oops: Fatal exception in interrupt
>
> Reject the line when the nibble is not a hex digit or exceeds
> CAN_MAX_DLEN, as the parser already does for other malformed lines.
>
> Attaching the N_CAN327 line discipline requires CAP_NET_ADMIN, but the
> frame lines then come from the ELM327 device, so a malicious adapter
> reaches this path with device-controlled data.
>
> Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>

Assuming XBOW is some kind of LLM/Agent/..., you can convert this into:

Assisted-by: AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2]

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-08-19  5:52 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-18 21:50 [PATCH net] can: can327: Fix out-of-bounds write in can327_parse_frame() Baul Lee
2026-08-18 22:11 ` Max Staudt
2026-08-19  5:52 ` Marc Kleine-Budde

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox