Linux CAN drivers development
 help / color / mirror / Atom feed
* [RFC PATCH v5 1/2] can: skb: enforce CANFD_FDF check in can_is_canfd_skb()
@ 2025-09-09  9:24 Oliver Hartkopp
  2025-09-09  9:24 ` [RFC PATCH v5 2/2] can: reject CAN FD content when disabled on CAN XL interfaces Oliver Hartkopp
  0 siblings, 1 reply; 19+ messages in thread
From: Oliver Hartkopp @ 2025-09-09  9:24 UTC (permalink / raw)
  To: linux-can; +Cc: Oliver Hartkopp

The check in can_is_canfd_skb() is about a length check of skb->len and
the CAN FD data length. As a skb length of CANFD_MTU can potentially be
created with a CAN XL frame with a data length of 60, the length check of
the CAN FD data length is used to detect CAN XL frames via its CANXL_XLF
flag which exceeds valid CAN FD data length values.

To make sure the CANFD_FDF flag can be safely used as a marker for CAN FD
frame skbs the bit is set in can_send() which is used by all PF_CAN
protocols. In the RX path alloc_canfd_skb() sets the CANFD_FDF flag.

The enforced CANFD_FDF check in can_is_canfd_skb() clears up the potential
uncertainty when using the skb->len check with the CANFD_MTU.

Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
---
 include/linux/can/skb.h | 19 +++++++++++++++++--
 net/can/af_can.c        |  2 +-
 net/can/raw.c           |  2 +-
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h
index 1abc25a8d144..09ab4dc83199 100644
--- a/include/linux/can/skb.h
+++ b/include/linux/can/skb.h
@@ -107,18 +107,33 @@ static inline bool can_is_can_skb(const struct sk_buff *skb)
 
 	/* the CAN specific type of skb is identified by its data length */
 	return (skb->len == CAN_MTU && cf->len <= CAN_MAX_DLEN);
 }
 
-static inline bool can_is_canfd_skb(const struct sk_buff *skb)
+static inline bool can_is_canfd_skb_mtu_len(const struct sk_buff *skb)
 {
 	struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
 
-	/* the CAN specific type of skb is identified by its data length */
+	/* The CAN specific type of skb is identified by its data length.
+	 * A CAN XL frame skb might have a skb->len of CANFD_MTU but the
+	 * skb would have the CANXL_XLF bit set (0x80 = 128) in the
+	 * cfd->len field position which would intentionally break the
+	 * CAN FD length check here.
+	 */
 	return (skb->len == CANFD_MTU && cfd->len <= CANFD_MAX_DLEN);
 }
 
+static inline bool can_is_canfd_skb(const struct sk_buff *skb)
+{
+	struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
+
+	if (!can_is_canfd_skb_mtu_len(skb))
+		return false;
+
+	return cfd->flags & CANFD_FDF;
+}
+
 static inline bool can_is_canxl_skb(const struct sk_buff *skb)
 {
 	const struct canxl_frame *cxl = (struct canxl_frame *)skb->data;
 
 	if (skb->len < CANXL_HDR_SIZE + CANXL_MIN_DLEN || skb->len > CANXL_MTU)
diff --git a/net/can/af_can.c b/net/can/af_can.c
index b2387a46794a..7fd2ed510440 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -207,11 +207,11 @@ int can_send(struct sk_buff *skb, int loop)
 
 	if (can_is_canxl_skb(skb)) {
 		skb->protocol = htons(ETH_P_CANXL);
 	} else if (can_is_can_skb(skb)) {
 		skb->protocol = htons(ETH_P_CAN);
-	} else if (can_is_canfd_skb(skb)) {
+	} else if (can_is_canfd_skb_mtu_len(skb)) {
 		struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
 
 		skb->protocol = htons(ETH_P_CANFD);
 
 		/* set CAN FD flag for CAN FD frames by default */
diff --git a/net/can/raw.c b/net/can/raw.c
index 76b867d21def..e5e3952b0e09 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -886,11 +886,11 @@ static unsigned int raw_check_txframe(struct raw_sock *ro, struct sk_buff *skb,
 	/* Classical CAN -> no checks for flags and device capabilities */
 	if (can_is_can_skb(skb))
 		return CAN_MTU;
 
 	/* CAN FD -> needs to be enabled and a CAN FD or CAN XL device */
-	if (ro->fd_frames && can_is_canfd_skb(skb) &&
+	if (ro->fd_frames && can_is_canfd_skb_mtu_len(skb) &&
 	    (mtu == CANFD_MTU || can_is_canxl_dev_mtu(mtu)))
 		return CANFD_MTU;
 
 	/* CAN XL -> needs to be enabled and a CAN XL device */
 	if (ro->xl_frames && can_is_canxl_skb(skb) &&
-- 
2.47.3


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

end of thread, other threads:[~2025-09-20 17:57 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-09  9:24 [RFC PATCH v5 1/2] can: skb: enforce CANFD_FDF check in can_is_canfd_skb() Oliver Hartkopp
2025-09-09  9:24 ` [RFC PATCH v5 2/2] can: reject CAN FD content when disabled on CAN XL interfaces Oliver Hartkopp
2025-09-09 16:36   ` Oliver Hartkopp
2025-09-10  5:13     ` Vincent Mailhol
2025-09-10  7:27       ` Oliver Hartkopp
2025-09-10  7:40         ` Vincent Mailhol
2025-09-10  8:48           ` Oliver Hartkopp
2025-09-10 16:19             ` Vincent Mailhol
2025-09-10 20:12               ` Oliver Hartkopp
2025-09-15 10:55                 ` Vincent Mailhol
2025-09-15 13:59                   ` Vincent Mailhol
2025-09-15 18:08                     ` Oliver Hartkopp
2025-09-15 18:54                       ` Vincent Mailhol
2025-09-16  9:14                         ` Oliver Hartkopp
2025-09-16 13:17                           ` Vincent Mailhol
2025-09-17 21:29                             ` Oliver Hartkopp
2025-09-18  9:18                               ` Vincent Mailhol
2025-09-20 17:38                                 ` Oliver Hartkopp
2025-09-20 17:57                                   ` Vincent Mailhol

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