From cdcb7555cf27d8b6ab8d50298cd98cc6433057b7 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 5 Aug 2024 18:09:41 +0100 Subject: [PATCH] - fixed unbounded recursion in MmsValue_decodeMmsData (LIB61850-452) --- src/mms/inc/mms_value.h | 14 +++++++++++++ src/mms/iso_mms/server/mms_access_result.c | 23 +++++++++++++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/mms/inc/mms_value.h b/src/mms/inc/mms_value.h index 206345c4..05c40ec3 100644 --- a/src/mms/inc/mms_value.h +++ b/src/mms/inc/mms_value.h @@ -1018,6 +1018,20 @@ MmsValue_printToBuffer(const MmsValue* self, char* buffer, int bufferSize); LIB61850_API MmsValue* MmsValue_decodeMmsData(uint8_t* buffer, int bufPos, int bufferLength, int* endBufPos); +/** + * \brief create a new MmsValue instance from a BER encoded MMS Data element (deserialize) with a defined maximum recursion depth + * + * \param buffer the buffer to read from + * \param bufPos the start position of the mms value data in the buffer + * \param bufferLength the length of the buffer + * \param endBufPos the position in the buffer after the read MMS data element (NULL if not required) + * \param maxDepth the maximum recursion depth + * + * \return the MmsValue instance created from the buffer + */ +LIB61850_API MmsValue* +MmsValue_decodeMmsDataMaxRecursion(uint8_t* buffer, int bufPos, int bufferLength, int* endBufPos, int maxDepth); + /** * \brief Serialize the MmsValue instance as BER encoded MMS Data element * diff --git a/src/mms/iso_mms/server/mms_access_result.c b/src/mms/iso_mms/server/mms_access_result.c index 95dcef8a..188719e7 100644 --- a/src/mms/iso_mms/server/mms_access_result.c +++ b/src/mms/iso_mms/server/mms_access_result.c @@ -152,9 +152,14 @@ exit_with_error: return -1; } -MmsValue* -MmsValue_decodeMmsData(uint8_t* buffer, int bufPos, int bufferLength, int* endBufPos) +static MmsValue* +MmsValue_decodeMmsDataRecursive(uint8_t* buffer, int bufPos, int bufferLength, int* endBufPos, int depth, int maxDepth) { + depth++; + + if (depth > maxDepth) + return NULL; + MmsValue* value = NULL; int dataEndBufPos = bufferLength; @@ -206,7 +211,7 @@ MmsValue_decodeMmsData(uint8_t* buffer, int bufPos, int bufferLength, int* endBu int elementBufLength = newBufPos - bufPos + elementLength; - MmsValue* elementValue = MmsValue_decodeMmsData(buffer, bufPos, bufPos + elementBufLength, NULL); + MmsValue* elementValue = MmsValue_decodeMmsDataRecursive(buffer, bufPos, bufPos + elementBufLength, NULL, depth, maxDepth); if (elementValue == NULL) goto exit_with_error; @@ -338,6 +343,18 @@ exit_with_error: return NULL; } +MmsValue* +MmsValue_decodeMmsDataMaxRecursion(uint8_t* buffer, int bufPos, int bufferLength, int* endBufPos, int maxDepth) +{ + return MmsValue_decodeMmsDataRecursive(buffer, bufPos, bufferLength, endBufPos, 0, maxDepth); +} + +MmsValue* +MmsValue_decodeMmsData(uint8_t* buffer, int bufPos, int bufferLength, int* endBufPos) +{ + return MmsValue_decodeMmsDataMaxRecursion(buffer, bufPos, bufferLength, endBufPos, 25); +} + static int MmsValue_getMaxStructSize(MmsValue* self) {