From 5d04f86af3af204c50d1e7e6bdff7b34d60d6c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 11 Aug 2026 18:28:04 +0200 Subject: [PATCH] fix(Radio): reject bogus coding rate and length readbacks on RX (#11408) --- src/mesh/RadioLibInterface.cpp | 7 +++++++ src/mesh/RadioLibInterface.h | 34 ++++++++++++++++++++-------------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index d770c19ca..7c45728cc 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -616,6 +616,13 @@ void RadioLibInterface::handleReceiveInterrupt() // read the number of actually received bytes size_t length = iface->getPacketLength(); + // Some drivers report this as a 16 bit value, so a bad readback can overrun radioBuffer in readData() + if (length > sizeof(radioBuffer)) { + LOG_ERROR("Ignore rx packet, bad length %u", (unsigned int)length); + rxBad++; + return; + } + uint32_t rxMsec = getPacketTime(length, true); #ifndef DISABLE_WELCOME_UNSET diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h index 82471e760..014272178 100644 --- a/src/mesh/RadioLibInterface.h +++ b/src/mesh/RadioLibInterface.h @@ -331,23 +331,29 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified template uint32_t computePacketTime(T &lora, uint32_t pl, bool received) { if (received) { - // First get the actual coding rate and CRC status from the received packet - uint8_t rxCR; - bool hasCRC; - lora.getLoRaRxHeaderInfo(&rxCR, &hasCRC); - // Go from raw header value to denominator - if (rxCR < 5) { - rxCR += 4; - } else if (rxCR == 7) { - rxCR = 8; - } - // Received packet configuration must be the same as configured, except for coding rate and CRC DataRate_t dr = getDataRate(); - dr.lora.codingRate = rxCR; - PacketConfig_t pc = getPacketConfig(); - pc.lora.crcEnabled = hasCRC; + + uint8_t rxCR = 0; + bool hasCRC = true; + if (lora.getLoRaRxHeaderInfo(&rxCR, &hasCRC) == RADIOLIB_ERR_NONE) { + // Raw 0 is reserved and >7 is either undefined or an LR2021-only convolutional rate no + // Meshtastic peer can send. calculateTimeOnAir() would multiply by it unchecked. + if (rxCR < 1 || rxCR > 7) { + LOG_WARN("Bogus RX coding rate %d from radio, use configured %d", rxCR, dr.lora.codingRate); + } else { + // Go from raw header value to denominator + if (rxCR < 5) { + rxCR += 4; + } else if (rxCR == 7) { + rxCR = 8; + } + + dr.lora.codingRate = rxCR; + pc.lora.crcEnabled = hasCRC; + } + } return lora.calculateTimeOnAir(modemType, dr, pc, pl) / 1000; }