This is an automated email from the ASF dual-hosted git repository.

jerpelea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 9e6397cb27a9941fde787414b02f9cb1df39aeaa
Author: p-szafonimateusz <[email protected]>
AuthorDate: Wed Oct 28 15:11:28 2026 +0100

    drivers/can: Limit received classic CAN frames to 8 data bytes.
    
    kvaser_pci.c and the classic path of ctucanfd_pci.c copied as many
    data bytes into struct can_frame as the received DLC says.  A classic
    CAN frame carries at most 8 data bytes, also with DLC 9..15, so a
    received DLC above 8 wrote past the 8-byte data array (ctucanfd), or
    would once can_dlc2bytes() maps DLC 9..15 to the CAN FD lengths for
    SocketCAN builds (kvaser).
    
    Limit the DLC of received classic frames to CAN_MAX_DLEN, as Linux
    can_cc_dlc2len() does, and copy only that many bytes.
    
    Assisted-by: Claude:claude-opus-5-5
    Signed-off-by: p-szafonimateusz <[email protected]>
---
 drivers/can/ctucanfd_pci.c | 8 +++++---
 drivers/can/kvaser_pci.c   | 8 +++++---
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/can/ctucanfd_pci.c b/drivers/can/ctucanfd_pci.c
index 67f81323265..1b51f4d32a0 100644
--- a/drivers/can/ctucanfd_pci.c
+++ b/drivers/can/ctucanfd_pci.c
@@ -1420,9 +1420,11 @@ static FAR netpkt_t *ctucanfd_sock_recv(FAR struct 
netdev_lowerhalf_s *dev)
       netpkt_setdatalen(dev, pkt, sizeof(struct can_frame));
       frame = (FAR struct can_frame *)netpkt_getdata(dev, pkt);
 
-      /* Get the DLC */
+      /* Get the DLC.  A classic frame carries at most 8 data bytes, also
+       * with DLC 9..15.
+       */
 
-      frame->can_dlc = rxframe->fmt.dlc;
+      frame->can_dlc = MIN(rxframe->fmt.dlc, CAN_MAX_DLEN);
 
 #ifdef CONFIG_NET_CAN_EXTID
       /* Get the CAN identifier. */
@@ -1458,7 +1460,7 @@ static FAR netpkt_t *ctucanfd_sock_recv(FAR struct 
netdev_lowerhalf_s *dev)
 
       /* Get data */
 
-      for (i = 0; i < rxframe->fmt.dlc; i++)
+      for (i = 0; i < frame->can_dlc; i++)
         {
           frame->data[i] = rxframe->data[i];
         }
diff --git a/drivers/can/kvaser_pci.c b/drivers/can/kvaser_pci.c
index d33a44b93d2..e4836a2e132 100644
--- a/drivers/can/kvaser_pci.c
+++ b/drivers/can/kvaser_pci.c
@@ -1253,9 +1253,11 @@ static FAR netpkt_t *kvaser_sock_recv(FAR struct 
netdev_lowerhalf_s *dev)
 
   regval = kvaser_getreg_sja(priv, SJA1000_DATA_0_REG);
 
-  /* Get the DLC */
+  /* Get the DLC.  A classic frame carries at most 8 data bytes, also with
+   * DLC 9..15.
+   */
 
-  frame->can_dlc = (regval & SJA1000_FI_DLC_MASK);
+  frame->can_dlc = MIN(regval & SJA1000_FI_DLC_MASK, CAN_MAX_DLEN);
 
   /* Get the CAN identifier. */
 
@@ -1303,7 +1305,7 @@ static FAR netpkt_t *kvaser_sock_recv(FAR struct 
netdev_lowerhalf_s *dev)
 
   /* Get data */
 
-  for (i = 0; i < can_dlc2bytes(frame->can_dlc); i++)
+  for (i = 0; i < frame->can_dlc; i++)
     {
       frame->data[i] = kvaser_getreg_sja(priv, dreg + i);
     }

Reply via email to