All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vincent Mailhol <mailhol@kernel.org>
To: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Oleksij Rempel <o.rempel@pengutronix.de>,
	linux-can@vger.kernel.org,
	Oliver Hartkopp <socketcan@hartkopp.net>,
	sashiko-bot@kernel.org
Subject: Re: CAN-XL frame to not CAN-XL enabled interface
Date: Fri, 31 Jul 2026 14:55:21 +0200	[thread overview]
Message-ID: <345456c4-907e-4d2f-bb24-4023d2898c94@kernel.org> (raw)
In-Reply-To: <20260731-agile-electric-cockatrice-295bb8-mkl@pengutronix.de>

On 31/07/2026 at 13:02, Marc Kleine-Budde wrote:
> Vincent,
> 
> does the current code check if you send a CAN XL frame to a CAN XL
> enabled interface?
> 
> On 31.07.2026 10:54:02, sashiko-bot@kernel.org wrote:
>> This is a pre-existing issue, but does this code properly handle CAN XL frames?
>>
>> If an ETH_P_CANXL frame is sent via AF_PACKET, can_dev_dropped_skb() currently
>> lacks a check to drop CAN XL frames for devices that don't support CAN XL.
>> When such a frame enters rkcanfd_start_xmit(), can_is_canfd_skb() returns
>> false, causing the driver to treat it as a Classic CAN frame.
> 
>> Sashiko AI review · https://sashiko.dev/#/patchset/20260731-master-v5-0-5b27029dee20@qq.com?part=1

The logic is for checking an ETH_P_CANXL frame is:

  - When sending a packet (even with PF_PACKET) the only check which
    is performed is to check that the skb len is not above
    net_device->mtu. So, if the device is not CAN XL capable, anything
    about CANFD_MTU (72 bytes) is dropped.

  - In the driver, can_dev_dropped_skb() calls
    can_dropped_invalid_skb() which then call can_is_canxl_skb() which
    validate that the skb length is within the range

      [CANXL_HDR_SIZE + CANXL_MIN_DLEN, skb->len > CANXL_MTU]

    that is to say 13 and 2060. But we already establish that the
    maximum length is 72 at this time.

So, yes, it seems that an ETH_P_CANXL frame with a length between 13
and 72 will pass the can_dev_dropped_skb() check. And because
CANXL_XLF must be set at this point, the driver sees a can_frame->len
of at least 128 bytes (and up to 255).

Until now, I was convinced in my mind that can_is_canxl_skb() rejected
frames with a length below CANXL_MIN_MTU which would have prevented
the issue. And I wrote the implementation under this false assumption
without double checking.


Here is a potential fix:

---8<---
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 6d0710d6f571..88dec0f91d71 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -152,6 +152,7 @@ static inline bool can_dev_in_xl_only_mode(struct can_priv *priv)
 /* drop skb if it does not contain a valid CAN frame for sending */
 static inline bool can_dev_dropped_skb(struct net_device *dev, struct sk_buff *skb)
 {
+       const struct canxl_frame *cxl = (struct canxl_frame *)skb->data;
        struct can_priv *priv = netdev_priv(dev);
        u32 silent_mode = priv->ctrlmode & (CAN_CTRLMODE_LISTENONLY |
                                            CAN_CTRLMODE_RESTRICTED);
@@ -167,6 +168,11 @@ static inline bool can_dev_dropped_skb(struct net_device *dev, struct sk_buff *s
                goto invalid_skb;
        }
 
+       if (!(priv->ctrlmode & CAN_CTRLMODE_XL) && cxl->flags & CANXL_XLF) {
+               netdev_info_once(dev, "CAN XL is disabled, dropping skb\n");
+               goto invalid_skb;
+       }
+
        if (can_dev_in_xl_only_mode(priv) && !can_is_canxl_skb(skb)) {
                netdev_info_once(dev,
                                 "Error signaling is disabled, dropping skb\n");
---8<---

The cxl->flags & CANXL_XLF doesn't catch everything by itself, but
once we know that this flag is off, can_is_canxl_skb() will reject the
frame later on. So this should be the minimum fix
(can_dev_dropped_skb() is an inline function in the hot path, so any
trick is welcome here, I think).

Does this make sense?


Yours sincerely,
Vincent Mailhol


  reply	other threads:[~2026-07-31 12:55 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-31 11:02 CAN-XL frame to not CAN-XL enabled interface Marc Kleine-Budde
2026-07-31 12:55 ` Vincent Mailhol [this message]
2026-07-31 13:28   ` Vincent Mailhol
2026-07-31 13:42     ` Oliver Hartkopp

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=345456c4-907e-4d2f-bb24-4023d2898c94@kernel.org \
    --to=mailhol@kernel.org \
    --cc=linux-can@vger.kernel.org \
    --cc=mkl@pengutronix.de \
    --cc=o.rempel@pengutronix.de \
    --cc=sashiko-bot@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.