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

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

commit ea02ecbfbd060611addd9e6bef8b08709aae3ad6
Author: mazhuang <[email protected]>
AuthorDate: Thu Oct 29 01:20:19 2026 +0800

    drivers/rpmsg/port_spi: drop rx frames with invalid header length
    
    A DMA transfer completed during a reconnect storm can leave rxhdr
    with a partially-written or line-noise payload. When such a header
    has len < sizeof(struct rpmsg_port_header_s) but a non-zero crc
    field, the subsequent CRC compute in rpmsg_port_spi_crc16() passes
    (len - sizeof(crc)) to crc16xor(), where the subtraction underflows
    to ~4 GiB. crc16xor() then iterates past the SRAM boundary and
    triggers a MemFault that escalates to a HardFault, and all peers
    follow via rptun_check_peer_status() in rptun.c.
    
    Reject such frames at the notify / complete_handler entry, after
    txhdr cleanup and before CRC check, so that neither crc16xor() nor
    the downstream state machine sees a malformed header. The check is
    unconditional: even when CONFIG_RPMSG_PORT_SPI_CRC is disabled,
    a malformed len can still poison txavail and rxq flow control.
    A len larger than the rx queue is rejected for the same reason.
    
    Reproduced by a VTF rpmsg socket test on a trunk build. The
    coredump shows the sensor core crashed in crc16xor+150 with rxhdr =
    {crc=0xaea5, cmd=0xbaae, avail=0x082d, len=0}, and the ap/cp/audio
    cores cascaded in rptun_check_peer_status().
    
    Signed-off-by: mazhuang <[email protected]>
---
 drivers/rpmsg/rpmsg_port_spi.c       | 8 ++++++++
 drivers/rpmsg/rpmsg_port_spi_slave.c | 8 ++++++++
 2 files changed, 16 insertions(+)

diff --git a/drivers/rpmsg/rpmsg_port_spi.c b/drivers/rpmsg/rpmsg_port_spi.c
index e8479a979f0..e53e0967374 100644
--- a/drivers/rpmsg/rpmsg_port_spi.c
+++ b/drivers/rpmsg/rpmsg_port_spi.c
@@ -344,6 +344,14 @@ static void rpmsg_port_spi_complete_handler(FAR void *arg)
       rpspi->shutdown = false;
     }
 
+  if (rpspi->rxhdr->len < sizeof(struct rpmsg_port_header_s) ||
+      rpspi->rxhdr->len > rpspi->port.rxq.len)
+    {
+      rpmsgerr("drop malformed rx: len=%u crc=%u cmd=%u\n",
+               rpspi->rxhdr->len, rpspi->rxhdr->crc, rpspi->rxhdr->cmd);
+      goto out;
+    }
+
   if (rpspi->rxhdr->crc != 0)
     {
       uint16_t crc = rpmsg_port_spi_crc16(rpspi->rxhdr);
diff --git a/drivers/rpmsg/rpmsg_port_spi_slave.c 
b/drivers/rpmsg/rpmsg_port_spi_slave.c
index 94af8d24520..ef3ca9e8774 100644
--- a/drivers/rpmsg/rpmsg_port_spi_slave.c
+++ b/drivers/rpmsg/rpmsg_port_spi_slave.c
@@ -423,6 +423,14 @@ static void rpmsg_port_spi_slave_notify(FAR struct 
spi_slave_dev_s *dev,
       rpspi->shutdown = false;
     }
 
+  if (rpspi->rxhdr->len < sizeof(struct rpmsg_port_header_s) ||
+      rpspi->rxhdr->len > rpspi->port.rxq.len)
+    {
+      rpmsgerr("drop malformed rx: len=%u crc=%u cmd=%u\n",
+               rpspi->rxhdr->len, rpspi->rxhdr->crc, rpspi->rxhdr->cmd);
+      goto out;
+    }
+
   if (rpspi->rxhdr->crc != 0)
     {
       uint16_t crc = rpmsg_port_spi_crc16(rpspi->rxhdr);

Reply via email to