This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch releases/13.0
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/releases/13.0 by this push:
new 269cc0dc151 drivers/can/ctucanfd_pci: Stack Overflow When Malformed
CAN Data Is Received
269cc0dc151 is described below
commit 269cc0dc151688d24bd15716d36b99aac0d4a050
Author: Catalin Visinescu <[email protected]>
AuthorDate: Sun Jun 14 10:39:01 2026 -0400
drivers/can/ctucanfd_pci: Stack Overflow When Malformed CAN Data Is Received
A malformed packet can trigger memory corruption in the kernel leading to a
system crash or potentially arbitrary code execution in the kernel.
The CAN driver for the CTU CAN FD IP Core connected to the NuttX device
via a PCI / PCI Express (PCIe) bus shows a lack of consideration for
malformed data, assuming the CAN frames are always correct.
Ensure `frame->fmt.rwcnt` is 21 or less before it is used in the `for` loop.
A similar change was done in ctucanfd_sock_recv().
Tested locally, builds fine.
Signed-off-by: Catalin Visinescu <[email protected]>
---
drivers/can/ctucanfd_pci.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/can/ctucanfd_pci.c b/drivers/can/ctucanfd_pci.c
index 647a9bce493..62382c3cbbb 100644
--- a/drivers/can/ctucanfd_pci.c
+++ b/drivers/can/ctucanfd_pci.c
@@ -760,6 +760,14 @@ static void ctucanfd_chardev_receive(FAR struct
ctucanfd_can_s *priv)
buff[0] = ctucanfd_getreg(priv, CTUCANFD_RXDATA);
+ /* buff[0] populated the frame->fmt.rwcnt. Check before use. */
+
+ if (frame->fmt.rwcnt > sizeof(buff) / sizeof(buff[0]))
+ {
+ canerr("ERROR: CAN read/write count is too large. Dropped\n");
+ return;
+ }
+
/* Read the rest of data */
for (i = 0; i < frame->fmt.rwcnt; i++)
@@ -1249,6 +1257,14 @@ static FAR netpkt_t *ctucanfd_sock_recv(FAR struct
netdev_lowerhalf_s *dev)
buff[0] = ctucanfd_getreg(priv, CTUCANFD_RXDATA);
+ /* buff[0] populated the frame->fmt.rwcnt. Check before use. */
+
+ if (frame->fmt.rwcnt > sizeof(buff) / sizeof(buff[0]))
+ {
+ canerr("ERROR: CAN read/write count is too large. Dropped\n");
+ return NULL;
+ }
+
/* Read the rest of data */
for (i = 0; i < rxframe->fmt.rwcnt; i++)