From: Vincent Mailhol <mailhol@kernel.org>
To: Marc Kleine-Budde <mkl@pengutronix.de>,
Oliver Hartkopp <socketcan@hartkopp.net>
Cc: "Arunachalam Santhanam" <arunachalam.santhanam@in.bosch.com>,
"Akshay Bhat" <akshay.bhat@timesys.com>,
"Wolfgang Grandegger" <wg@grandegger.com>,
"Chen-Yu Tsai" <wens@csie.org>,
"Jernej Skrabec" <jernej.skrabec@gmail.com>,
"Samuel Holland" <samuel@sholland.org>,
"Maxime Ripard" <mripard@kernel.org>,
"Gerhard Bertelsmann" <info@gerhard-bertelsmann.de>,
"Yasushi SHOJI" <yashi@spacecubics.com>,
"Remigiusz Kołłątaj" <remigiusz.kollataj@mobica.com>,
linux-can@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-sunxi@lists.linux.dev,
"Vincent Mailhol" <mailhol@kernel.org>
Subject: [PATCH 2/4] can: hi311x: populate ndo_change_mtu() to prevent buffer overflow
Date: Thu, 18 Sep 2025 18:00:25 +0900 [thread overview]
Message-ID: <20250918-can-fix-mtu-v1-2-0d1cada9393b@kernel.org> (raw)
In-Reply-To: <20250918-can-fix-mtu-v1-0-0d1cada9393b@kernel.org>
Sending an PF_PACKET allows to bypass the CAN framework logic and to
directly reach the xmit() function of a CAN driver. The only check
which is performed by the PF_PACKET framework is to make sure that
skb->len fits the interface's MTU.
Unfortunately, because the sun4i_can driver does not populate its
net_device_ops->ndo_change_mtu(), it is possible for an attacker to
configure an invalid MTU by doing, for example:
$ ip link set can0 mtu 9999
After doing so, the attacker could open a PF_PACKET socket using the
ETH_P_CANXL protocol:
socket(PF_PACKET, SOCK_RAW, htons(ETH_P_CANXL))
to inject a malicious CAN XL frames. For example:
struct canxl_frame frame = {
.flags = 0xff,
.len = 2048,
};
The CAN drivers' xmit() function are calling can_dev_dropped_skb() to
check that the skb is valid, unfortunately under above conditions, the
malicious packet is able to go through can_dev_dropped_skb() checks:
1. the skb->protocol is set to ETH_P_CANXL which is valid (the
function does not check the actual device capabilities).
2. the length is a valid CAN XL length.
And so, hi3110_hard_start_xmit() receives a CAN XL frame which it is
not able to correctly handle and will thus misinterpret it as a CAN
frame. The driver will consume frame->len as-is with no further
checks.
This can result in a buffer overflow later on in hi3110_hw_tx() on
this line:
memcpy(buf + HI3110_FIFO_EXT_DATA_OFF,
frame->data, frame->len);
Here, frame->len corresponds to the flags field of the CAN XL frame.
In our previous example, we set canxl_frame->flags to 0xff. Because
the maximum expected length is 8, a buffer overflow of 247 bytes
occurs!
Populate net_device_ops->ndo_change_mtu() to ensure that the
interface's MTU can not be set to anything bigger than CAN_MTU. By
fixing the root cause, this prevents the buffer overflow.
Fixes: 57e83fb9b746 ("can: hi311x: Add Holt HI-311x CAN driver")
Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
---
drivers/net/can/spi/hi311x.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
index 09ae218315d73d49c2ec4280707911966fce1c31..6441ff3b4198718e8e662daa3022f06a2405f322 100644
--- a/drivers/net/can/spi/hi311x.c
+++ b/drivers/net/can/spi/hi311x.c
@@ -812,6 +812,7 @@ static const struct net_device_ops hi3110_netdev_ops = {
.ndo_open = hi3110_open,
.ndo_stop = hi3110_stop,
.ndo_start_xmit = hi3110_hard_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops hi3110_ethtool_ops = {
--
2.49.1
next prev parent reply other threads:[~2025-09-18 9:01 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-18 9:00 [PATCH 0/4] can: " Vincent Mailhol
2025-09-18 9:00 ` [PATCH 1/4] can: etas_es58x: " Vincent Mailhol
2025-09-18 9:00 ` Vincent Mailhol [this message]
2025-09-18 9:00 ` [PATCH 3/4] can: sun4i_can: " Vincent Mailhol
2025-09-18 9:00 ` [PATCH 4/4] can: mcba_usb: " Vincent Mailhol
2025-09-19 17:04 ` [PATCH 0/4] can: " Marc Kleine-Budde
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=20250918-can-fix-mtu-v1-2-0d1cada9393b@kernel.org \
--to=mailhol@kernel.org \
--cc=akshay.bhat@timesys.com \
--cc=arunachalam.santhanam@in.bosch.com \
--cc=info@gerhard-bertelsmann.de \
--cc=jernej.skrabec@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-can@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sunxi@lists.linux.dev \
--cc=mkl@pengutronix.de \
--cc=mripard@kernel.org \
--cc=remigiusz.kollataj@mobica.com \
--cc=samuel@sholland.org \
--cc=socketcan@hartkopp.net \
--cc=wens@csie.org \
--cc=wg@grandegger.com \
--cc=yashi@spacecubics.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
all inboxes | Powered by JetHome®