diff --git a/src/main/common/streambuf.c b/src/main/common/streambuf.c index 5a766423421..f567135ab66 100644 --- a/src/main/common/streambuf.c +++ b/src/main/common/streambuf.c @@ -24,6 +24,7 @@ sbuf_t *sbufInit(sbuf_t *sbuf, uint8_t *ptr, uint8_t *end) { sbuf->ptr = ptr; sbuf->end = end; + sbuf->overrun = false; return sbuf; } @@ -95,12 +96,16 @@ void sbufWriteStringWithZeroTerminator(sbuf_t *dst, const char *string) uint8_t sbufReadU8(sbuf_t *src) { + if (src->ptr >= src->end) { + src->overrun = true; + return 0; + } return *src->ptr++; } int8_t sbufReadI8(sbuf_t *src) { - return *src->ptr++; + return (int8_t)sbufReadU8(src); } uint16_t sbufReadU16(sbuf_t *src) @@ -216,4 +221,5 @@ void sbufSwitchToReader(sbuf_t *buf, uint8_t *base) { buf->end = buf->ptr; buf->ptr = base; + buf->overrun = false; } diff --git a/src/main/common/streambuf.h b/src/main/common/streambuf.h index a2ac1f681a6..d89bfdc524a 100644 --- a/src/main/common/streambuf.h +++ b/src/main/common/streambuf.h @@ -26,6 +26,7 @@ typedef struct sbuf_s { uint8_t *ptr; // data pointer must be first (sbuff_t* is equivalent to uint8_t **) uint8_t *end; + bool overrun; // sticky: set by an unsafe sbufRead* call that ran past end } sbuf_t; sbuf_t *sbufInit(sbuf_t *sbuf, uint8_t *ptr, uint8_t *end); diff --git a/src/main/fc/fc_msp.c b/src/main/fc/fc_msp.c index 919665397a3..95b1df0d6be 100644 --- a/src/main/fc/fc_msp.c +++ b/src/main/fc/fc_msp.c @@ -2676,6 +2676,10 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src) } } } + + if (src->overrun) { + return MSP_RESULT_ERROR; + } } break; @@ -3124,6 +3128,11 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src) for (unsigned ii = 0; ii < MIN(osdCharacterBytes, sizeof(chr.data)); ii++) { chr.data[ii] = sbufReadU8(src); } + + if (src->overrun) { + return MSP_RESULT_ERROR; + } + displayPort_t *osdDisplayPort = osdGetDisplayPort(); if (osdDisplayPort) { displayWriteFontCharacter(osdDisplayPort, addr, &chr);