fix(crsf_rc): guard against packet_size underflow in CRSF parser

When a CRSF frame arrives with packet_size < 2 (PACKET_SIZE_TYPE_SIZE),
the subtraction `packet_size - PACKET_SIZE_TYPE_SIZE` underflows the
uint32_t working_segment_size to 0xFFFFFFFF. The subsequent overflow
check also wraps and fails to catch it. Since working_segment_size is
static, the parser is permanently stalled — no further CRSF messages
can be processed until reboot.

Validate packet_size >= PACKET_SIZE_TYPE_SIZE early, before any
subtraction, protecting both the known variable-length and unknown
packet branches in a single check.

Supersedes #26782 which only guarded the unknown-packet branch.
This commit is contained in:
Jacob Dahl
2026-03-17 21:14:42 -08:00
committed by Ramon Roche
parent 3038ac9b7d
commit 05cc1687a5
+12
View File
@@ -393,6 +393,18 @@ bool CrsfParser_TryParseCrsfPacket(CrsfPacket_t *const new_packet, CrsfParserSta
QueueBuffer_Peek(&rx_queue, working_index++, &packet_size);
QueueBuffer_Peek(&rx_queue, working_index++, &packet_type);
// Discard packets with packet_size too small to contain type + CRC.
// Without this guard, (packet_size - PACKET_SIZE_TYPE_SIZE) underflows
// the uint32_t working_segment_size, permanently stalling the parser.
if (packet_size < PACKET_SIZE_TYPE_SIZE) {
parser_statistics->invalid_unknown_packet_sizes++;
parser_state = PARSER_STATE_HEADER;
working_segment_size = HEADER_SIZE;
working_index = 0;
buffer_count = QueueBuffer_Count(&rx_queue);
continue;
}
working_descriptor = FindCrsfDescriptor((enum CRSF_PACKET_TYPE)packet_type);
// If we know what this packet is...