From: Sureshkumar S <ssureshmsd7@gmail.com>
To: Marc Kleine-Budde <mkl@pengutronix.de>,
Vincent Mailhol <mailhol@kernel.org>
Cc: Oliver Hartkopp <socketcan@hartkopp.net>,
linux-can@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org,
Sureshkumar S <ssureshmsd7@gmail.com>
Subject: [PATCH net 1/2] can: bittiming: fix divide-by-zero in can_calc_bittiming()
Date: Mon, 3 Aug 2026 09:14:25 +0000 [thread overview]
Message-ID: <20260803091426.29050-2-ssureshmsd7@gmail.com> (raw)
In-Reply-To: <20260803091426.29050-1-ssureshmsd7@gmail.com>
can_calc_bittiming() scans the possible time segment combinations and
computes the prescaler for each of them as:
brp = priv->clock.freq / (tsegall * bt->bitrate)
bt->bitrate is supplied by userspace via IFLA_CAN_BITTIMING and
tsegall * bt->bitrate is a 32 bit multiplication, so the product wraps
to zero as soon as bt->bitrate carries enough factors of two for the
tsegall values walked by the loop. The division then faults:
Oops: divide error: 0000 [#1] SMP KASAN NOPTI
RIP: 0010:can_calc_bittiming+0x32e/0xcc0
Call Trace:
can_changelink+0x8ba/0x2060
__rtnl_newlink+0x1013/0x18a0
rtnl_newlink+0x6b/0xa0
rtnetlink_rcv_msg+0x6f9/0xb70
netlink_rcv_skb+0x11f/0x350
netlink_unicast+0x5f5/0x860
netlink_sendmsg+0x70a/0xba0
This does not require an absurd bitrate. With the segment limits of a
typical controller tsegall reaches 256, so a bitrate of 16777216 is
already enough to wrap the product, and that value is below the
20 Mbit/s CAN XL data bitrate ceiling. Any CAN driver providing a
bittiming_const is affected; reproduced on dummy_can. Triggering it
needs CAP_NET_ADMIN in the netns owning the device.
priv->bitrate_max cannot guard against this: it is populated from the
optional "max-bitrate" device tree property, so it is zero for most
drivers, and can_changelink() only consults it after can_get_bittiming()
has already returned.
Compute the product with mul_u32_u32(), as can_fixup_bittiming() already
does for bt->brp * NSEC_PER_SEC, and divide with div64_u64(). div_u64()
cannot be used here because its divisor is a u32, which would truncate
the product back to the faulting value.
Fixes: 39549eef3587 ("can: CAN Network device driver and Netlink interface")
Signed-off-by: Sureshkumar S <ssureshmsd7@gmail.com>
---
drivers/net/can/dev/calc_bittiming.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/dev/calc_bittiming.c b/drivers/net/can/dev/calc_bittiming.c
index 42498e9d3f38..4809f5e0c96e 100644
--- a/drivers/net/can/dev/calc_bittiming.c
+++ b/drivers/net/can/dev/calc_bittiming.c
@@ -119,8 +119,12 @@ int can_calc_bittiming(const struct net_device *dev, struct can_bittiming *bt,
tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) {
tsegall = CAN_SYNC_SEG + tseg / 2;
- /* Compute all possible tseg choices (tseg=tseg1+tseg2) */
- brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2;
+ /* Compute all possible tseg choices (tseg=tseg1+tseg2).
+ * A 32 bit tsegall * bt->bitrate can wrap to zero for large
+ * userspace bitrates, so compute the product in 64 bit.
+ */
+ brp = div64_u64(priv->clock.freq,
+ mul_u32_u32(tsegall, bt->bitrate)) + tseg % 2;
/* choose brp step which is possible in system */
brp = (brp / btc->brp_inc) * btc->brp_inc;
--
2.43.0
next prev parent reply other threads:[~2026-08-03 9:14 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-03 9:14 [PATCH net 0/2] can: bittiming: fix two defects in the userspace bitrate conversion Sureshkumar S
2026-08-03 9:14 ` Sureshkumar S [this message]
2026-08-04 9:15 ` [PATCH net 1/2] can: bittiming: fix divide-by-zero in can_calc_bittiming() sashiko-bot
2026-08-03 9:14 ` [PATCH net 2/2] can: bittiming: fix bitrate error calculation on unsigned operands Sureshkumar S
2026-08-04 9:15 ` 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=20260803091426.29050-2-ssureshmsd7@gmail.com \
--to=ssureshmsd7@gmail.com \
--cc=linux-can@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mailhol@kernel.org \
--cc=mkl@pengutronix.de \
--cc=netdev@vger.kernel.org \
--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.