From cef95ff6997bfe8e6054ec939b6351a59912dd6f Mon Sep 17 00:00:00 2001 From: Ray Morris Date: Tue, 25 Aug 2026 08:16:07 -0500 Subject: [PATCH 1/2] Guard MSP2_SENSOR_* receivers against short payloads mspProcessSensorCommand computed the incoming payload size but discarded it, letting GPS/compass/baro/airspeed/opflow/rangefinder receivers cast an unchecked pointer to a fixed-size struct. A short-but-CRC-valid frame let stale bytes from the shared MSP input buffer be read as real sensor data. Thread dataSize through to each receiver and reject any frame that isn't exactly the expected size, matching the pattern already used by MSP2_SENSOR_HEADTRACKER. --- src/main/drivers/barometer/barometer_msp.c | 6 +++++- src/main/drivers/barometer/barometer_msp.h | 2 +- src/main/drivers/compass/compass_msp.c | 6 +++++- src/main/drivers/compass/compass_msp.h | 2 +- src/main/drivers/pitotmeter/pitotmeter_msp.c | 6 +++++- src/main/drivers/pitotmeter/pitotmeter_msp.h | 2 +- src/main/fc/fc_msp.c | 13 ++++++------- src/main/io/gps.h | 2 +- src/main/io/gps_msp.c | 6 +++++- src/main/io/opflow.h | 2 +- src/main/io/opflow_msp.c | 6 +++++- src/main/io/rangefinder.h | 2 +- src/main/io/rangefinder_msp.c | 6 +++++- 13 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/main/drivers/barometer/barometer_msp.c b/src/main/drivers/barometer/barometer_msp.c index 5c5db4ca3f5..5b32a4fe4cc 100644 --- a/src/main/drivers/barometer/barometer_msp.c +++ b/src/main/drivers/barometer/barometer_msp.c @@ -78,8 +78,12 @@ static bool mspBaroCalculate(baroDev_t * baro, int32_t *pressure, int32_t *tempe return true; } -void mspBaroReceiveNewData(uint8_t * bufferPtr) +void mspBaroReceiveNewData(uint8_t * bufferPtr, unsigned int dataSize) { + if (dataSize != sizeof(mspSensorBaroDataMessage_t)) { + return; + } + const mspSensorBaroDataMessage_t * pkt = (const mspSensorBaroDataMessage_t *)bufferPtr; mspBaroPressure = pkt->pressurePa; diff --git a/src/main/drivers/barometer/barometer_msp.h b/src/main/drivers/barometer/barometer_msp.h index dcf979be53a..cdcbdfb7332 100644 --- a/src/main/drivers/barometer/barometer_msp.h +++ b/src/main/drivers/barometer/barometer_msp.h @@ -26,4 +26,4 @@ struct baroDev_s; bool mspBaroDetect(struct baroDev_s *baro); -void mspBaroReceiveNewData(uint8_t * bufferPtr); \ No newline at end of file +void mspBaroReceiveNewData(uint8_t * bufferPtr, unsigned int dataSize); \ No newline at end of file diff --git a/src/main/drivers/compass/compass_msp.c b/src/main/drivers/compass/compass_msp.c index d0b2ffc6278..cb5564dd0fe 100644 --- a/src/main/drivers/compass/compass_msp.c +++ b/src/main/drivers/compass/compass_msp.c @@ -58,8 +58,12 @@ static bool mspMagInit(magDev_t *magDev) return true; } -void mspMagReceiveNewData(uint8_t * bufferPtr) +void mspMagReceiveNewData(uint8_t * bufferPtr, unsigned int dataSize) { + if (dataSize != sizeof(mspSensorCompassDataMessage_t)) { + return; + } + const mspSensorCompassDataMessage_t * pkt = (const mspSensorCompassDataMessage_t *)bufferPtr; mspMagData[X] = (float) pkt->magX; diff --git a/src/main/drivers/compass/compass_msp.h b/src/main/drivers/compass/compass_msp.h index 529e0c1df07..39869160f05 100644 --- a/src/main/drivers/compass/compass_msp.h +++ b/src/main/drivers/compass/compass_msp.h @@ -25,4 +25,4 @@ #pragma once bool mspMagDetect(struct magDev_s *mag); -void mspMagReceiveNewData(uint8_t * bufferPtr); +void mspMagReceiveNewData(uint8_t * bufferPtr, unsigned int dataSize); diff --git a/src/main/drivers/pitotmeter/pitotmeter_msp.c b/src/main/drivers/pitotmeter/pitotmeter_msp.c index f0a8e82768a..0ab8fc2a6a3 100644 --- a/src/main/drivers/pitotmeter/pitotmeter_msp.c +++ b/src/main/drivers/pitotmeter/pitotmeter_msp.c @@ -72,8 +72,12 @@ static void mspPitotCalculate(pitotDev_t *pitot, float *pressure, float *tempera } } -void mspPitotmeterReceiveNewData(uint8_t * bufferPtr) +void mspPitotmeterReceiveNewData(uint8_t * bufferPtr, unsigned int dataSize) { + if (dataSize != sizeof(mspSensorAirspeedDataMessage_t)) { + return; + } + const mspSensorAirspeedDataMessage_t * pkt = (const mspSensorAirspeedDataMessage_t *)bufferPtr; mspPitotPressure = pkt->diffPressurePa; diff --git a/src/main/drivers/pitotmeter/pitotmeter_msp.h b/src/main/drivers/pitotmeter/pitotmeter_msp.h index 3e1fabec61d..3bf6ec6c2c4 100644 --- a/src/main/drivers/pitotmeter/pitotmeter_msp.h +++ b/src/main/drivers/pitotmeter/pitotmeter_msp.h @@ -26,4 +26,4 @@ struct pitotDev_s; bool mspPitotmeterDetect(struct pitotDev_s *pitot); -void mspPitotmeterReceiveNewData(uint8_t * bufferPtr); \ No newline at end of file +void mspPitotmeterReceiveNewData(uint8_t * bufferPtr, unsigned int dataSize); \ No newline at end of file diff --git a/src/main/fc/fc_msp.c b/src/main/fc/fc_msp.c index 961d1737c95..64dc38bc685 100644 --- a/src/main/fc/fc_msp.c +++ b/src/main/fc/fc_msp.c @@ -4642,42 +4642,41 @@ bool mspFCProcessInOutCommand(uint16_t cmdMSP, sbuf_t *dst, sbuf_t *src, mspResu static mspResult_e mspProcessSensorCommand(uint16_t cmdMSP, sbuf_t *src) { int dataSize = sbufBytesRemaining(src); - UNUSED(dataSize); switch (cmdMSP) { #if defined(USE_RANGEFINDER_MSP) case MSP2_SENSOR_RANGEFINDER: - mspRangefinderReceiveNewData(sbufPtr(src)); + mspRangefinderReceiveNewData(sbufPtr(src), dataSize); break; #endif #if defined(USE_OPFLOW_MSP) case MSP2_SENSOR_OPTIC_FLOW: - mspOpflowReceiveNewData(sbufPtr(src)); + mspOpflowReceiveNewData(sbufPtr(src), dataSize); break; #endif #if defined(USE_GPS_PROTO_MSP) case MSP2_SENSOR_GPS: - mspGPSReceiveNewData(sbufPtr(src)); + mspGPSReceiveNewData(sbufPtr(src), dataSize); break; #endif #if defined(USE_MAG_MSP) case MSP2_SENSOR_COMPASS: - mspMagReceiveNewData(sbufPtr(src)); + mspMagReceiveNewData(sbufPtr(src), dataSize); break; #endif #if defined(USE_BARO_MSP) case MSP2_SENSOR_BAROMETER: - mspBaroReceiveNewData(sbufPtr(src)); + mspBaroReceiveNewData(sbufPtr(src), dataSize); break; #endif #if defined(USE_PITOT_MSP) case MSP2_SENSOR_AIRSPEED: - mspPitotmeterReceiveNewData(sbufPtr(src)); + mspPitotmeterReceiveNewData(sbufPtr(src), dataSize); break; #endif diff --git a/src/main/io/gps.h b/src/main/io/gps.h index c14db4a7630..3f8d9a8f64e 100755 --- a/src/main/io/gps.h +++ b/src/main/io/gps.h @@ -170,7 +170,7 @@ bool isGPSHealthy(void); bool isGPSHeadingValid(void); struct serialPort_s; void gpsEnablePassthrough(struct serialPort_s *gpsPassthroughPort); -void mspGPSReceiveNewData(const uint8_t * bufferPtr); +void mspGPSReceiveNewData(const uint8_t * bufferPtr, unsigned int dataSize); const char *getGpsHwVersion(void); uint8_t getGpsProtoMajorVersion(void); diff --git a/src/main/io/gps_msp.c b/src/main/io/gps_msp.c index 1fd4b1cf15e..12cb3e658ff 100644 --- a/src/main/io/gps_msp.c +++ b/src/main/io/gps_msp.c @@ -77,8 +77,12 @@ static uint8_t gpsMapFixType(uint8_t mspFixType) return GPS_NO_FIX; } -void mspGPSReceiveNewData(const uint8_t * bufferPtr) +void mspGPSReceiveNewData(const uint8_t * bufferPtr, unsigned int dataSize) { + if (dataSize != sizeof(mspSensorGpsDataMessage_t)) { + return; + } + const mspSensorGpsDataMessage_t * pkt = (const mspSensorGpsDataMessage_t *)bufferPtr; gpsSolDRV.fixType = gpsMapFixType(pkt->fixType); diff --git a/src/main/io/opflow.h b/src/main/io/opflow.h index e8042c28181..88351c6d3b9 100755 --- a/src/main/io/opflow.h +++ b/src/main/io/opflow.h @@ -32,4 +32,4 @@ extern virtualOpflowVTable_t opflowCxofVtable; extern virtualOpflowVTable_t opflowMSPVtable; -void mspOpflowReceiveNewData(uint8_t * bufferPtr); \ No newline at end of file +void mspOpflowReceiveNewData(uint8_t * bufferPtr, unsigned int dataSize); \ No newline at end of file diff --git a/src/main/io/opflow_msp.c b/src/main/io/opflow_msp.c index 778ebccca4a..7d63a3d801d 100644 --- a/src/main/io/opflow_msp.c +++ b/src/main/io/opflow_msp.c @@ -71,8 +71,12 @@ static bool mspOpflowUpdate(opflowData_t * data) return false; } -void mspOpflowReceiveNewData(uint8_t * bufferPtr) +void mspOpflowReceiveNewData(uint8_t * bufferPtr, unsigned int dataSize) { + if (dataSize != sizeof(mspSensorOpflowDataMessage_t)) { + return; + } + const timeUs_t currentTimeUs = micros(); const mspSensorOpflowDataMessage_t * pkt = (const mspSensorOpflowDataMessage_t *)bufferPtr; diff --git a/src/main/io/rangefinder.h b/src/main/io/rangefinder.h index fd51aeb44aa..ac9b21c0a3f 100644 --- a/src/main/io/rangefinder.h +++ b/src/main/io/rangefinder.h @@ -35,5 +35,5 @@ extern virtualRangefinderVTable_t rangefinderUSD1Vtable; extern virtualRangefinderVTable_t rangefinderNanoradarVtable; //NRA15/NRA24 extern virtualRangefinderVTable_t rangefinderFakeVtable; -void mspRangefinderReceiveNewData(uint8_t * bufferPtr); +void mspRangefinderReceiveNewData(uint8_t * bufferPtr, unsigned int dataSize); void fakeRangefindersSetData(int32_t data); \ No newline at end of file diff --git a/src/main/io/rangefinder_msp.c b/src/main/io/rangefinder_msp.c index 5c7f728f2f6..5bbcb55d52f 100644 --- a/src/main/io/rangefinder_msp.c +++ b/src/main/io/rangefinder_msp.c @@ -72,8 +72,12 @@ static int32_t mspRangefinderGetDistance(void) } } -void mspRangefinderReceiveNewData(uint8_t * bufferPtr) +void mspRangefinderReceiveNewData(uint8_t * bufferPtr, unsigned int dataSize) { + if (dataSize != sizeof(mspSensorRangefinderDataMessage_t)) { + return; + } + const mspSensorRangefinderDataMessage_t * pkt = (const mspSensorRangefinderDataMessage_t *)bufferPtr; sensorData = pkt->distanceMm / 10; From 4621536792502301bcb60752a026783104180033 Mon Sep 17 00:00:00 2001 From: Ray Morris Date: Sat, 29 Aug 2026 13:57:23 -0500 Subject: [PATCH 2/2] Accept longer MSP2_SENSOR_* payloads from newer senders Under the forward-compat policy (MSP payloads only gain fields at the end), a longer message from a newer sender must be accepted: apply the known leading fields and ignore the trailing bytes. Relax all seven receiver guards (GPS, compass, baro, airspeed, opflow, rangefinder, headtracker) from exact-size `dataSize != sizeof(...)` to minimum-size `dataSize < sizeof(...)`, so truncated frames are still rejected while longer frames are accepted. --- src/main/drivers/barometer/barometer_msp.c | 2 +- src/main/drivers/compass/compass_msp.c | 2 +- src/main/drivers/pitotmeter/pitotmeter_msp.c | 2 +- src/main/io/gps_msp.c | 2 +- src/main/io/headtracker_msp.c | 2 +- src/main/io/opflow_msp.c | 2 +- src/main/io/rangefinder_msp.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/drivers/barometer/barometer_msp.c b/src/main/drivers/barometer/barometer_msp.c index 5b32a4fe4cc..462d5a15b43 100644 --- a/src/main/drivers/barometer/barometer_msp.c +++ b/src/main/drivers/barometer/barometer_msp.c @@ -80,7 +80,7 @@ static bool mspBaroCalculate(baroDev_t * baro, int32_t *pressure, int32_t *tempe void mspBaroReceiveNewData(uint8_t * bufferPtr, unsigned int dataSize) { - if (dataSize != sizeof(mspSensorBaroDataMessage_t)) { + if (dataSize < sizeof(mspSensorBaroDataMessage_t)) { return; } diff --git a/src/main/drivers/compass/compass_msp.c b/src/main/drivers/compass/compass_msp.c index cb5564dd0fe..7e97b00b355 100644 --- a/src/main/drivers/compass/compass_msp.c +++ b/src/main/drivers/compass/compass_msp.c @@ -60,7 +60,7 @@ static bool mspMagInit(magDev_t *magDev) void mspMagReceiveNewData(uint8_t * bufferPtr, unsigned int dataSize) { - if (dataSize != sizeof(mspSensorCompassDataMessage_t)) { + if (dataSize < sizeof(mspSensorCompassDataMessage_t)) { return; } diff --git a/src/main/drivers/pitotmeter/pitotmeter_msp.c b/src/main/drivers/pitotmeter/pitotmeter_msp.c index 0ab8fc2a6a3..8f7d1e0e686 100644 --- a/src/main/drivers/pitotmeter/pitotmeter_msp.c +++ b/src/main/drivers/pitotmeter/pitotmeter_msp.c @@ -74,7 +74,7 @@ static void mspPitotCalculate(pitotDev_t *pitot, float *pressure, float *tempera void mspPitotmeterReceiveNewData(uint8_t * bufferPtr, unsigned int dataSize) { - if (dataSize != sizeof(mspSensorAirspeedDataMessage_t)) { + if (dataSize < sizeof(mspSensorAirspeedDataMessage_t)) { return; } diff --git a/src/main/io/gps_msp.c b/src/main/io/gps_msp.c index 12cb3e658ff..222e2651e7f 100644 --- a/src/main/io/gps_msp.c +++ b/src/main/io/gps_msp.c @@ -79,7 +79,7 @@ static uint8_t gpsMapFixType(uint8_t mspFixType) void mspGPSReceiveNewData(const uint8_t * bufferPtr, unsigned int dataSize) { - if (dataSize != sizeof(mspSensorGpsDataMessage_t)) { + if (dataSize < sizeof(mspSensorGpsDataMessage_t)) { return; } diff --git a/src/main/io/headtracker_msp.c b/src/main/io/headtracker_msp.c index e53fd3ab207..0f444e00845 100644 --- a/src/main/io/headtracker_msp.c +++ b/src/main/io/headtracker_msp.c @@ -55,7 +55,7 @@ void mspHeadTrackerInit(void) void mspHeadTrackerReceiverNewData(uint8_t *data, unsigned int dataSize) { - if(dataSize != sizeof(headtrackerMspMessage_t)) { + if(dataSize < sizeof(headtrackerMspMessage_t)) { SD(fprintf(stderr, "[headTracker]: invalid data size %d\n", dataSize)); static int errorCount = 0; DEBUG_SET(DEBUG_HEADTRACKING, 7, errorCount++); diff --git a/src/main/io/opflow_msp.c b/src/main/io/opflow_msp.c index 7d63a3d801d..c085c35bc96 100644 --- a/src/main/io/opflow_msp.c +++ b/src/main/io/opflow_msp.c @@ -73,7 +73,7 @@ static bool mspOpflowUpdate(opflowData_t * data) void mspOpflowReceiveNewData(uint8_t * bufferPtr, unsigned int dataSize) { - if (dataSize != sizeof(mspSensorOpflowDataMessage_t)) { + if (dataSize < sizeof(mspSensorOpflowDataMessage_t)) { return; } diff --git a/src/main/io/rangefinder_msp.c b/src/main/io/rangefinder_msp.c index 5bbcb55d52f..ec84fc4c741 100644 --- a/src/main/io/rangefinder_msp.c +++ b/src/main/io/rangefinder_msp.c @@ -74,7 +74,7 @@ static int32_t mspRangefinderGetDistance(void) void mspRangefinderReceiveNewData(uint8_t * bufferPtr, unsigned int dataSize) { - if (dataSize != sizeof(mspSensorRangefinderDataMessage_t)) { + if (dataSize < sizeof(mspSensorRangefinderDataMessage_t)) { return; }