From 605f80fe813f354fe4f31c57a499c832c5c0da9a Mon Sep 17 00:00:00 2001 From: Mike German Date: Mon, 6 Jul 2026 21:31:06 -0400 Subject: [PATCH] fix: validate optData length in FCP_Get_OptData to prevent buffer overflow FCP_Get_OptData() read the optional-data length byte straight from the received frame and memcpy'd that many bytes into the caller's optData buffer without checking it against the actual frame length. A malformed or corrupted unencrypted frame (the length byte is attacker/noise controlled and unauthenticated) could therefore declare up to 255 bytes and overrun the caller's buffer while parsing an incoming RF frame. FCP_Get_OptData_Length() already guards this exact case and returns ERR_LENGTH_MISMATCH. Apply the same check in FCP_Get_OptData() before the memcpy. Valid frames are unaffected (the declared length equals the bytes present); malformed frames now return ERR_LENGTH_MISMATCH instead of overflowing. Verified on a host build (identity-AES stub) under AddressSanitizer: encrypted and unencrypted round-trips still decode correctly, and a frame with a length byte of 200 into an 8-byte buffer now returns -4 instead of triggering an overflow. Signed-off-by: Mike German --- src/FOSSA-Comms.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/FOSSA-Comms.cpp b/src/FOSSA-Comms.cpp index b87215b..8dda65f 100644 --- a/src/FOSSA-Comms.cpp +++ b/src/FOSSA-Comms.cpp @@ -184,6 +184,14 @@ int16_t FCP_Get_OptData(char* callsign, uint8_t* frame, uint8_t frameLen, uint8_ uint8_t optDataLen = *framePtr; framePtr += 1; + // check that the declared length matches the number of bytes actually + // present in the frame, otherwise a malformed length byte would cause + // the memcpy below to overrun the caller's optData buffer (same check + // as FCP_Get_OptData_Length) + if(optDataLen != (uint8_t)(frameLen - strlen(callsign) - 2)) { + return(ERR_LENGTH_MISMATCH); + } + // get optional data memcpy(optData, framePtr, optDataLen); framePtr += optDataLen;