From 11acd4a26eca9898debdcd145579d42fd45d74e3 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Thu, 11 Jun 2026 18:00:38 -0700 Subject: [PATCH] [posix] fix SPI platform driver sanity check boundaries (#13236) This commit corrects the SPI frame sanity checks in the POSIX platform driver (`spi_interface.cpp`). Previously, the sanity checks compared `mSpiSlaveDataLen` and `slaveAcceptLen` against `kMaxFrameSize` (8192). However, `mSpiSlaveDataLen` is the payload size, which excludes the 5-byte SPI frame header. If the slave advertised a data length of exactly `kMaxFrameSize` (8192), it would pass the sanity check, but the subsequent `DoSpiTransfer` would request a transfer length of `kMaxFrameSize + kSpiFrameHeaderSize + alignment` (e.g. 8213 bytes). This would cause an out-of-bounds read on `mSpiTxFrameBuffer` which is sized `kMaxFrameSize + kSpiAlignAllowanceMax` (8208 bytes). This commit updates the sanity checks to use `kMaxFrameSize - kSpiFrameHeaderSize` as the maximum allowed payload length, ensuring that worst-case transfers always fit within the tx buffer allocation. --- src/posix/platform/spi_interface.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/posix/platform/spi_interface.cpp b/src/posix/platform/spi_interface.cpp index 6c992b873..90ea3a968 100644 --- a/src/posix/platform/spi_interface.cpp +++ b/src/posix/platform/spi_interface.cpp @@ -412,8 +412,9 @@ otError SpiInterface::PushPullSpi(void) txFrame.SetHeaderAcceptLen(0); txFrame.SetHeaderDataLen(0); - // Sanity check. - if (mSpiSlaveDataLen > kMaxFrameSize) + // Sanity check. The header `data_len` carries the payload length only + // (it excludes header size), so the largest valid value is the MTU. + if (mSpiSlaveDataLen > kMaxFrameSize - kSpiFrameHeaderSize) { mSpiSlaveDataLen = 0; } @@ -517,7 +518,8 @@ otError SpiInterface::PushPullSpi(void) slaveAcceptLen = rxFrame.GetHeaderAcceptLen(); mSpiSlaveDataLen = rxFrame.GetHeaderDataLen(); - if (!rxFrame.IsValid() || (slaveAcceptLen > kMaxFrameSize) || (mSpiSlaveDataLen > kMaxFrameSize)) + if (!rxFrame.IsValid() || (slaveAcceptLen > kMaxFrameSize - kSpiFrameHeaderSize) || + (mSpiSlaveDataLen > kMaxFrameSize - kSpiFrameHeaderSize)) { mInterfaceMetrics.mTransferredGarbageFrameCount++; mSpiTxRefusedCount++;