diff --git a/src/app/util/attribute-storage.cpp b/src/app/util/attribute-storage.cpp index 415086483914cc..1359c59fc5f8de 100644 --- a/src/app/util/attribute-storage.cpp +++ b/src/app/util/attribute-storage.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -292,6 +293,30 @@ CHIP_ERROR emberAfSetDynamicEndpoint(uint16_t index, EndpointId id, const EmberA } } + const size_t bufferSize = Compatibility::Internal::gEmberAttributeIOBufferSpan.size(); + for (uint8_t i = 0; i < ep->clusterCount; i++) + { + const EmberAfCluster * cluster = &(ep->cluster[i]); + if (!cluster->attributes) + { + continue; + } + + for (uint16_t j = 0; j < cluster->attributeCount; j++) + { + const EmberAfAttributeMetadata * attr = &(cluster->attributes[j]); + uint16_t attrSize = emberAfAttributeSize(attr); + if (attrSize > bufferSize) + { + ChipLogError(DataManagement, + "Attribute size %u exceeds max size %lu, (attrId=" ChipLogFormatMEI ", clusterId=" ChipLogFormatMEI + ")", + attrSize, static_cast(bufferSize), ChipLogValueMEI(attr->attributeId), + ChipLogValueMEI(cluster->clusterId)); + return CHIP_ERROR_NO_MEMORY; + } + } + } emAfEndpoints[index].endpoint = id; emAfEndpoints[index].deviceTypeList = deviceTypeList; emAfEndpoints[index].endpointType = ep; @@ -642,10 +667,20 @@ Status emAfReadOrWriteAttribute(const EmberAfAttributeSearchRecord * attRecord, // Is the attribute externally stored? if (am->mask & MATTER_ATTRIBUTE_FLAG_EXTERNAL_STORAGE) { - return (write ? emberAfExternalAttributeWriteCallback(attRecord->endpoint, attRecord->clusterId, - am, buffer) - : emberAfExternalAttributeReadCallback(attRecord->endpoint, attRecord->clusterId, - am, buffer, emberAfAttributeSize(am))); + if (write) + { + return emberAfExternalAttributeWriteCallback(attRecord->endpoint, attRecord->clusterId, am, + buffer); + } + + if (readLength < emberAfAttributeSize(am)) + { + // Prevent a potential buffer overflow + return Status::ResourceExhausted; + } + + return emberAfExternalAttributeReadCallback(attRecord->endpoint, attRecord->clusterId, am, + buffer, emberAfAttributeSize(am)); } // Internal storage is only supported for fixed endpoints diff --git a/src/controller/tests/TestServerCommandDispatch.cpp b/src/controller/tests/TestServerCommandDispatch.cpp index 17acaa5887c14b..446b8b44daf16c 100644 --- a/src/controller/tests/TestServerCommandDispatch.cpp +++ b/src/controller/tests/TestServerCommandDispatch.cpp @@ -215,7 +215,8 @@ TEST_F(TestServerCommandDispatch, TestNoHandler) EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } -static const int kDescriptorAttributeArraySize = 254; +// Use 8 so that we don't exceed the size of ATTRIBUTE_LARGEST defined by ZAP +static const int kDescriptorAttributeArraySize = 8; // Declare Descriptor cluster attributes DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(descriptorAttrs)