From f60ff65fc4013c21fb92cf3ca4337ccaca2b3e22 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Wed, 16 Mar 2022 09:00:59 +0100 Subject: [PATCH] - improved MmsValue handling; fixed MmsValue(OCTET-STRIG) maximum size problem (LIB61850-150) --- src/goose/goose_receiver.c | 4 +- src/mms/inc_private/mms_value_internal.h | 2 +- src/mms/iso_mms/client/mms_client_read.c | 2 +- src/mms/iso_mms/common/mms_common_msg.c | 162 +++++++++++++-------- src/mms/iso_mms/common/mms_value.c | 76 ++++++++-- src/mms/iso_mms/server/mms_access_result.c | 2 +- 6 files changed, 169 insertions(+), 79 deletions(-) diff --git a/src/goose/goose_receiver.c b/src/goose/goose_receiver.c index 017b1c00..98d6c396 100644 --- a/src/goose/goose_receiver.c +++ b/src/goose/goose_receiver.c @@ -273,7 +273,7 @@ parseAllData(uint8_t* buffer, int allDataLength, MmsValue* dataSetValues) case 0x89: /* octet string */ if (MmsValue_getType(value) == MMS_OCTET_STRING) { - if (elementLength <= value->value.octetString.maxSize) { + if (elementLength <= abs(value->value.octetString.maxSize)) { value->value.octetString.size = elementLength; memcpy(value->value.octetString.buf, buffer + bufPos, elementLength); } @@ -286,7 +286,7 @@ parseAllData(uint8_t* buffer, int allDataLength, MmsValue* dataSetValues) uint8_t* oldBuf = value->value.octetString.buf; value->value.octetString.buf = newBuf; - value->value.octetString.maxSize = elementLength; + value->value.octetString.maxSize = -elementLength; value->value.octetString.size = elementLength; GLOBAL_FREEMEM(oldBuf); diff --git a/src/mms/inc_private/mms_value_internal.h b/src/mms/inc_private/mms_value_internal.h index ebbc1672..7fbeb2d7 100644 --- a/src/mms/inc_private/mms_value_internal.h +++ b/src/mms/inc_private/mms_value_internal.h @@ -45,7 +45,7 @@ struct ATTRIBUTE_PACKED sMmsValue { } floatingPoint; struct { uint16_t size; - uint16_t maxSize; + int maxSize; uint8_t* buf; } octetString; struct { diff --git a/src/mms/iso_mms/client/mms_client_read.c b/src/mms/iso_mms/client/mms_client_read.c index 28490040..829675bb 100644 --- a/src/mms/iso_mms/client/mms_client_read.c +++ b/src/mms/iso_mms/client/mms_client_read.c @@ -331,7 +331,7 @@ mmsClient_parseListOfAccessResults(AccessResult_t** accessResultList, int listSi if (size >= 0) { value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); value->type = MMS_OCTET_STRING; - value->value.octetString.maxSize = size; + value->value.octetString.maxSize = -size; value->value.octetString.size = size; value->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(size); memcpy(value->value.octetString.buf, accessResultList[i]->choice.octetstring.buf, size); diff --git a/src/mms/iso_mms/common/mms_common_msg.c b/src/mms/iso_mms/common/mms_common_msg.c index 1e4178d2..eefd408f 100644 --- a/src/mms/iso_mms/common/mms_common_msg.c +++ b/src/mms/iso_mms/common/mms_common_msg.c @@ -192,20 +192,22 @@ mmsMsg_parseDataElement(Data_t* dataElement) if (componentCount > 0) { value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); - value->type = MMS_ARRAY; - value->value.structure.size = componentCount; - value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*)); - - int i; - - for (i = 0; i < componentCount; i++) { - value->value.structure.components[i] = - mmsMsg_parseDataElement(dataElement->choice.array->list.array[i]); - - if (value->value.structure.components[i] == NULL) { - MmsValue_delete(value); - value = NULL; - break; + if (value) { + value->type = MMS_ARRAY; + value->value.structure.size = componentCount; + value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*)); + + int i; + + for (i = 0; i < componentCount; i++) { + value->value.structure.components[i] = + mmsMsg_parseDataElement(dataElement->choice.array->list.array[i]); + + if (value->value.structure.components[i] == NULL) { + MmsValue_delete(value); + value = NULL; + break; + } } } } @@ -222,20 +224,22 @@ mmsMsg_parseDataElement(Data_t* dataElement) if (componentCount > 0) { value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); - value->type = MMS_STRUCTURE; - value->value.structure.size = componentCount; - value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*)); + if (value) { + value->type = MMS_STRUCTURE; + value->value.structure.size = componentCount; + value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*)); - int i; + int i; - for (i = 0; i < componentCount; i++) { - value->value.structure.components[i] = - mmsMsg_parseDataElement(dataElement->choice.structure->list.array[i]); + for (i = 0; i < componentCount; i++) { + value->value.structure.components[i] = + mmsMsg_parseDataElement(dataElement->choice.structure->list.array[i]); - if (value->value.structure.components[i] == NULL) { - MmsValue_delete(value); - value = NULL; - break; + if (value->value.structure.components[i] == NULL) { + MmsValue_delete(value); + value = NULL; + break; + } } } } @@ -251,7 +255,8 @@ mmsMsg_parseDataElement(Data_t* dataElement) Asn1PrimitiveValue* berInteger = BerInteger_createFromBuffer( dataElement->choice.integer.buf, dataElement->choice.integer.size); - value = MmsValue_newIntegerFromBerInteger(berInteger); + if (berInteger) + value = MmsValue_newIntegerFromBerInteger(berInteger); } else { if (DEBUG_MMS_CLIENT) @@ -264,7 +269,8 @@ mmsMsg_parseDataElement(Data_t* dataElement) Asn1PrimitiveValue* berInteger = BerInteger_createFromBuffer( dataElement->choice.Unsigned.buf, dataElement->choice.Unsigned.size); - value = MmsValue_newUnsignedFromBerInteger(berInteger); + if (berInteger) + value = MmsValue_newUnsignedFromBerInteger(berInteger); } else { if (DEBUG_MMS_CLIENT) @@ -297,20 +303,32 @@ mmsMsg_parseDataElement(Data_t* dataElement) if ((bitSize > 0) && (maxSize >= bitSize)) { value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); - value->type = MMS_BIT_STRING; + if (value) { + + value->type = MMS_BIT_STRING; - value->value.bitString.size = bitSize; + value->value.bitString.size = bitSize; - value->value.bitString.buf = (uint8_t*) GLOBAL_MALLOC(size); - memcpy(value->value.bitString.buf, - dataElement->choice.bitstring.buf, size); + value->value.bitString.buf = (uint8_t*) GLOBAL_MALLOC(size); + + if (value->value.bitString.buf) { + memcpy(value->value.bitString.buf, + dataElement->choice.bitstring.buf, size); + } + else { + GLOBAL_FREEMEM(value); + value = 0; + } + } } else if (bitSize == 0) { value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); - value->type = MMS_BIT_STRING; - value->value.bitString.size = 0; - value->value.bitString.buf = NULL; + if (value) { + value->type = MMS_BIT_STRING; + value->value.bitString.size = 0; + value->value.bitString.buf = NULL; + } } else { if (DEBUG_MMS_CLIENT) @@ -329,35 +347,41 @@ mmsMsg_parseDataElement(Data_t* dataElement) if (size == 5) { /* FLOAT32 */ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); - value->type = MMS_FLOAT; - value->value.floatingPoint.formatWidth = 32; - value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0]; + if (value) { + value->type = MMS_FLOAT; + + value->value.floatingPoint.formatWidth = 32; + value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0]; - uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1); + uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1); #if (ORDER_LITTLE_ENDIAN == 1) - memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 4); + memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 4); #else - memcpy(value->value.floatingPoint.buf, floatBuf, 4); + memcpy(value->value.floatingPoint.buf, floatBuf, 4); #endif + } } if (size == 9) { /* FLOAT64 */ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); - value->type = MMS_FLOAT; - value->value.floatingPoint.formatWidth = 64; - value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0]; + if (value) { + value->type = MMS_FLOAT; - uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1); + value->value.floatingPoint.formatWidth = 64; + value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0]; + + uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1); #if (ORDER_LITTLE_ENDIAN == 1) - memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 8); + memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 8); #else - memcpy(value->value.floatingPoint.buf, floatBuf, 8); + memcpy(value->value.floatingPoint.buf, floatBuf, 8); #endif + } } } else if (dataElement->present == Data_PR_utctime) { @@ -366,8 +390,11 @@ mmsMsg_parseDataElement(Data_t* dataElement) if (size == 8) { value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); - value->type = MMS_UTC_TIME; - memcpy(value->value.utcTime, dataElement->choice.utctime.buf, 8); + + if (value) { + value->type = MMS_UTC_TIME; + memcpy(value->value.utcTime, dataElement->choice.utctime.buf, 8); + } } else { if (DEBUG_MMS_CLIENT) @@ -378,12 +405,28 @@ mmsMsg_parseDataElement(Data_t* dataElement) if (dataElement->choice.octetstring.size >= 0) { value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); - value->type = MMS_OCTET_STRING; - int size = dataElement->choice.octetstring.size; - value->value.octetString.size = size; - value->value.octetString.maxSize = size; - value->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(size); - memcpy(value->value.octetString.buf, dataElement->choice.octetstring.buf, size); + + if (value) { + value->type = MMS_OCTET_STRING; + int size = dataElement->choice.octetstring.size; + + value->value.octetString.size = size; + + if (size > 0) + value->value.octetString.maxSize = -size; + else + value->value.octetString.maxSize = -8; + + value->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(abs(value->value.octetString.maxSize)); + + if (value->value.octetString.buf) { + memcpy(value->value.octetString.buf, dataElement->choice.octetstring.buf, size); + } + else { + GLOBAL_FREEMEM(value); + value = NULL; + } + } } } @@ -392,9 +435,12 @@ mmsMsg_parseDataElement(Data_t* dataElement) if ((size == 4) || (size == 6)) { value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); - value->type = MMS_BINARY_TIME; - value->value.binaryTime.size = size; - memcpy(value->value.binaryTime.buf, dataElement->choice.binarytime.buf, size); + + if (value) { + value->type = MMS_BINARY_TIME; + value->value.binaryTime.size = size; + memcpy(value->value.binaryTime.buf, dataElement->choice.binarytime.buf, size); + } } else { if (DEBUG_MMS_CLIENT) diff --git a/src/mms/iso_mms/common/mms_value.c b/src/mms/iso_mms/common/mms_value.c index f04670b6..53d6563c 100644 --- a/src/mms/iso_mms/common/mms_value.c +++ b/src/mms/iso_mms/common/mms_value.c @@ -240,9 +240,11 @@ MmsValue_update(MmsValue* self, const MmsValue* update) if (updateStructuredComponent(self, update) == false) return false; break; + case MMS_BOOLEAN: self->value.boolean = update->value.boolean; break; + case MMS_FLOAT: if (self->value.floatingPoint.formatWidth == update->value.floatingPoint.formatWidth) { self->value.floatingPoint.exponentWidth = update->value.floatingPoint.exponentWidth; @@ -252,6 +254,7 @@ MmsValue_update(MmsValue* self, const MmsValue* update) else return false; break; + case MMS_INTEGER: case MMS_UNSIGNED: if (BerInteger_setFromBerInteger(self->value.integer, update->value.integer)) @@ -259,9 +262,11 @@ MmsValue_update(MmsValue* self, const MmsValue* update) else return false; break; + case MMS_UTC_TIME: memcpy(self->value.utcTime, update->value.utcTime, 8); break; + case MMS_BIT_STRING: if (self->value.bitString.size == update->value.bitString.size) memcpy(self->value.bitString.buf, update->value.bitString.buf, bitStringByteSize(self)); @@ -278,40 +283,55 @@ MmsValue_update(MmsValue* self, const MmsValue* update) else return false; break; + case MMS_OCTET_STRING: { int size = update->value.octetString.size; - if (size > self->value.octetString.maxSize) { + if ((self->value.octetString.maxSize < 0) && (size > abs(self->value.octetString.maxSize))) { + GLOBAL_FREEMEM(self->value.octetString.buf); self->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(size); if (self->value.octetString.buf == NULL) return false; - self->value.octetString.maxSize = size; + if (self->value.octetString.maxSize < 0) + self->value.octetString.maxSize = -size; + else + self->value.octetString.maxSize = size; } - memcpy(self->value.octetString.buf, update->value.octetString.buf, size); + if (size <= abs(self->value.octetString.maxSize)) { + memcpy(self->value.octetString.buf, update->value.octetString.buf, size); - self->value.octetString.size = size; + self->value.octetString.size = size; + } + else { + return false; + } } break; + case MMS_VISIBLE_STRING: MmsValue_setVisibleString(self, update->value.visibleString.buf); break; + case MMS_STRING: MmsValue_setMmsString(self, update->value.visibleString.buf); break; + case MMS_BINARY_TIME: self->value.binaryTime.size = update->value.binaryTime.size; memcpy(self->value.binaryTime.buf, update->value.binaryTime.buf, update->value.binaryTime.size); break; + default: return false; break; } + return true; } else @@ -1046,7 +1066,7 @@ MmsValue_getSizeInMemory(const MmsValue* self) break; case MMS_OCTET_STRING: - memorySize += MemoryAllocator_getAlignedSize(self->value.octetString.maxSize); + memorySize += MemoryAllocator_getAlignedSize(abs(self->value.octetString.maxSize)); break; case MMS_STRING: @@ -1106,8 +1126,8 @@ MmsValue_cloneToBuffer(const MmsValue* self, uint8_t* destinationAddress) case MMS_OCTET_STRING: newValue->value.octetString.buf = destinationAddress; - memcpy(destinationAddress, self->value.octetString.buf, self->value.octetString.maxSize); - destinationAddress += MemoryAllocator_getAlignedSize(self->value.octetString.maxSize); + memcpy(destinationAddress, self->value.octetString.buf, abs(self->value.octetString.maxSize)); + destinationAddress += MemoryAllocator_getAlignedSize(abs(self->value.octetString.maxSize)); break; case MMS_STRING: @@ -1201,7 +1221,15 @@ MmsValue_clone(const MmsValue* self) newValue->value.bitString.size = self->value.bitString.size; size = bitStringByteSize(self); newValue->value.bitString.buf = (uint8_t*) GLOBAL_MALLOC(size); - memcpy(newValue->value.bitString.buf, self->value.bitString.buf, size); + + if (newValue->value.bitString.buf) { + memcpy(newValue->value.bitString.buf, self->value.bitString.buf, size); + } + else { + GLOBAL_FREEMEM(newValue); + newValue = NULL; + } + break; case MMS_BOOLEAN: @@ -1212,8 +1240,16 @@ MmsValue_clone(const MmsValue* self) size = self->value.octetString.size; newValue->value.octetString.size = size; newValue->value.octetString.maxSize = self->value.octetString.maxSize; - newValue->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(self->value.octetString.maxSize); - memcpy(newValue->value.octetString.buf, self->value.octetString.buf, size); + newValue->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(abs(self->value.octetString.maxSize)); + + if (newValue->value.octetString.buf) { + memcpy(newValue->value.octetString.buf, self->value.octetString.buf, size); + } + else { + GLOBAL_FREEMEM(newValue); + newValue = NULL; + } + break; case MMS_UTC_TIME: @@ -1229,8 +1265,16 @@ MmsValue_clone(const MmsValue* self) case MMS_STRING: size = self->value.visibleString.size; newValue->value.visibleString.buf = (char*) GLOBAL_MALLOC(size + 1); - newValue->value.visibleString.size = size; - strcpy(newValue->value.visibleString.buf, self->value.visibleString.buf); + + if (newValue->value.visibleString.buf) { + newValue->value.visibleString.size = size; + strcpy(newValue->value.visibleString.buf, self->value.visibleString.buf); + } + else { + GLOBAL_FREEMEM(newValue); + newValue = NULL; + } + break; case MMS_DATA_ACCESS_ERROR: @@ -1409,7 +1453,7 @@ MmsValue_newOctetString(int size, int maxSize) self->type = MMS_OCTET_STRING; self->value.octetString.size = size; self->value.octetString.maxSize = maxSize; - self->value.octetString.buf = (uint8_t*) GLOBAL_CALLOC(1, maxSize); + self->value.octetString.buf = (uint8_t*) GLOBAL_CALLOC(1, abs(maxSize)); if (self->value.octetString.buf == NULL) { GLOBAL_FREEMEM(self); @@ -1423,7 +1467,7 @@ MmsValue_newOctetString(int size, int maxSize) void MmsValue_setOctetString(MmsValue* self, const uint8_t* buf, int size) { - if (size <= self->value.octetString.maxSize) { + if (size <= abs(self->value.octetString.maxSize)) { memcpy(self->value.octetString.buf, buf, size); self->value.octetString.size = size; } @@ -1432,7 +1476,7 @@ MmsValue_setOctetString(MmsValue* self, const uint8_t* buf, int size) void MmsValue_setOctetStringOctet(MmsValue* self, int octetPos, uint8_t value) { - if ((octetPos >= 0) && (octetPos < self->value.octetString.maxSize)) { + if ((octetPos >= 0) && (octetPos < abs(self->value.octetString.maxSize))) { self->value.octetString.buf[octetPos] = value; if (octetPos >= self->value.octetString.size) { @@ -1450,7 +1494,7 @@ MmsValue_getOctetStringSize(const MmsValue* self) uint16_t MmsValue_getOctetStringMaxSize(MmsValue* self) { - return self->value.octetString.maxSize; + return abs(self->value.octetString.maxSize); } uint8_t* diff --git a/src/mms/iso_mms/server/mms_access_result.c b/src/mms/iso_mms/server/mms_access_result.c index 06b50d28..b17461f0 100644 --- a/src/mms/iso_mms/server/mms_access_result.c +++ b/src/mms/iso_mms/server/mms_access_result.c @@ -394,7 +394,7 @@ MmsValue_getMaxEncodedSize(MmsValue* self) size = 2 + self->value.binaryTime.size; break; case MMS_OCTET_STRING: - elementSize = self->value.octetString.maxSize; + elementSize = abs(self->value.octetString.maxSize); size = 1 + BerEncoder_determineLengthSize(elementSize) + elementSize; break; case MMS_FLOAT: