From 610388548667d7bcf963ef470491cd7e16829717 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 30 Jul 2026 13:40:22 +0300 Subject: [PATCH 01/13] memory: check allocation before constructing objects MakeUnique/MakeShared placement-constructed objects via the Allocator-based operator new, which only guarded a failed allocation with assert(). In release builds (NDEBUG) that assert is compiled out, so an exhausted allocator returned nullptr and the constructor still ran at a null address (UB). Both factories now call Allocator::Allocate() explicitly, check the result, and return an empty pointer instead of constructing when the allocation fails. Signed-off-by: Oleksandr Grytsov --- src/core/common/tools/memory.hpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/core/common/tools/memory.hpp b/src/core/common/tools/memory.hpp index a92d02f56..6323231a7 100644 --- a/src/core/common/tools/memory.hpp +++ b/src/core/common/tools/memory.hpp @@ -8,6 +8,8 @@ #ifndef AOS_CORE_COMMON_TOOLS_MEMORY_HPP_ #define AOS_CORE_COMMON_TOOLS_MEMORY_HPP_ +#include + #include "allocator.hpp" namespace aos { @@ -526,7 +528,12 @@ inline UniquePtr MakeUnique(Allocator* allocator, Args&&... args) { assert(allocator); - return UniquePtr(new (allocator) T(args...), DefaultDeleter(allocator)); + auto data = allocator->Allocate(sizeof(T)); + if (!data) { + return UniquePtr(); + } + + return UniquePtr(new (data) T(args...), DefaultDeleter(allocator)); } /** @@ -558,7 +565,12 @@ inline SharedPtr MakeShared(Allocator* allocator, Args&&... args) { assert(allocator); - return SharedPtr(allocator, new (allocator) T(args...), SmartPtrDeleter); + auto data = allocator->Allocate(sizeof(T)); + if (!data) { + return SharedPtr(); + } + + return SharedPtr(allocator, new (data) T(args...), SmartPtrDeleter); } } // namespace aos From c11047253f44b0df096de116b29d54029d0c2384 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 30 Jul 2026 16:10:33 +0300 Subject: [PATCH 02/13] tools: check MakeUnique/MakeShared allocation failures everywhere MakeUnique/MakeShared already returned an empty (falsy) pointer on allocator exhaustion, but most call sites across the codebase never checked the result before dereferencing it, so an out-of-memory condition would still crash on a null-pointer dereference instead of being reported as an error. Add a check after every such call site, propagating eNoMemory using whichever convention the enclosing function already uses (Error, RetWithError, bool, or void with a log message). Signed-off-by: Oleksandr Grytsov --- src/core/cm/alerts/alerts.cpp | 13 +++ src/core/cm/imagemanager/imagemanager.cpp | 6 +- .../cm/imagemanager/tests/imagemanager.cpp | 22 ++++ src/core/cm/launcher/balancer.cpp | 23 +++- src/core/cm/launcher/imageinfoprovider.cpp | 39 ++++++- src/core/cm/launcher/instance.cpp | 17 ++- src/core/cm/launcher/instancemanager.cpp | 19 +++ src/core/cm/launcher/launcher.cpp | 18 +++ src/core/cm/launcher/node.cpp | 21 +++- src/core/cm/launcher/nodemanager.cpp | 19 ++- src/core/cm/launcher/runrequestsloader.cpp | 12 +- src/core/cm/launcher/storagestate.cpp | 4 + .../cm/nodeinfoprovider/nodeinfoprovider.cpp | 11 ++ src/core/cm/storagestate/storagestate.cpp | 21 ++++ src/core/cm/unitconfig/unitconfig.cpp | 26 ++++- .../cm/updatemanager/desiredstatushandler.cpp | 28 ++++- .../cm/updatemanager/unitstatushandler.cpp | 6 + src/core/common/crypto/certloader.cpp | 15 ++- src/core/common/crypto/cryptohelper.cpp | 55 ++++++++- .../common/crypto/mbedtls/cryptoprovider.cpp | 13 +++ .../common/crypto/openssl/cryptoprovider.cpp | 12 ++ src/core/common/monitoring/average.cpp | 3 + src/core/common/monitoring/monitoring.cpp | 14 ++- src/core/common/pkcs11/pkcs11.cpp | 54 ++++++++- src/core/common/pkcs11/privatekey.cpp | 3 + .../common/spaceallocator/spaceallocator.hpp | 10 +- .../common/tests/stubs/spaceallocatorstub.hpp | 7 +- src/core/common/tools/fs.cpp | 8 +- src/core/common/tools/memory.hpp | 4 +- src/core/iam/certhandler/certhandler.cpp | 6 + src/core/iam/certhandler/certmodule.cpp | 35 +++++- .../certhandler/certmodules/pkcs11/pkcs11.cpp | 39 ++++++- .../iam/certhandler/tests/certhandler.cpp | 4 + src/core/iam/nodemanager/nodemanager.cpp | 20 +++- src/core/sm/launcher/launcher.cpp | 66 ++++++++++- src/core/sm/networkmanager/networkmanager.cpp | 108 +++++++++++++++++- src/core/sm/nodeconfig/nodeconfig.cpp | 6 + 37 files changed, 741 insertions(+), 46 deletions(-) diff --git a/src/core/cm/alerts/alerts.cpp b/src/core/cm/alerts/alerts.cpp index 994461f0e..a732e5d71 100644 --- a/src/core/cm/alerts/alerts.cpp +++ b/src/core/cm/alerts/alerts.cpp @@ -242,6 +242,9 @@ Error Alerts::SendAlerts() while (!mAlerts.IsEmpty()) { auto package = CreatePackage(); + if (!package) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } LOG_INF() << "Send alerts" << Log::Field("alertsCount", package->mItems.Size()); @@ -258,6 +261,11 @@ Error Alerts::SendAlerts() bool Alerts::IsDuplicated(const AlertVariant& alert) { auto alertCopy = MakeUnique(&mAllocator, alert); + if (!alertCopy) { + LOG_ERR() << "Can't allocate alert copy" << Log::Field(ErrorEnum::eNoMemory); + + return false; + } return mAlerts.FindIf([&alertCopy](const AlertVariant& item) { alertCopy->ApplyVisitor(SetTimestamp(item.ApplyVisitor(GetTimestamp()))); @@ -269,6 +277,11 @@ bool Alerts::IsDuplicated(const AlertVariant& alert) UniquePtr Alerts::CreatePackage() { auto package = MakeUnique(&mAllocator); + if (!package) { + LOG_ERR() << "Can't allocate alerts package" << Log::Field(ErrorEnum::eNoMemory); + + return package; + } const auto count = Min(cAlertItemsCount, mAlerts.Size()); diff --git a/src/core/cm/imagemanager/imagemanager.cpp b/src/core/cm/imagemanager/imagemanager.cpp index 9f2c46bb7..66dfcf1f2 100644 --- a/src/core/cm/imagemanager/imagemanager.cpp +++ b/src/core/cm/imagemanager/imagemanager.cpp @@ -1080,7 +1080,11 @@ Error ImageManager::EnsureBlob(const String& digest, const String& downloadPath, { LOG_DBG() << "Ensure blob" << Log::Field("digest", digest); - auto blobInfo = MakeUnique(&mAllocator); + auto blobInfo = MakeUnique(&mAllocator); + if (!blobInfo) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + UniquePtr downloadingSpace; do { diff --git a/src/core/cm/imagemanager/tests/imagemanager.cpp b/src/core/cm/imagemanager/tests/imagemanager.cpp index 283890ada..1aff9c5d1 100644 --- a/src/core/cm/imagemanager/tests/imagemanager.cpp +++ b/src/core/cm/imagemanager/tests/imagemanager.cpp @@ -213,6 +213,8 @@ TEST_F(ImageManagerTest, DownloadUpdateItems_Success_NewItem) EXPECT_CALL(mDownloadingSpaceAllocatorMock, AllocateSpace(_)) .WillRepeatedly(Invoke([this](size_t) -> RetWithError> { auto space = MakeUnique(&mAllocator); + EXPECT_TRUE(space); + EXPECT_CALL(*space, Accept()).Times(AtLeast(0)); EXPECT_CALL(*space, Release()).Times(AtLeast(0)); @@ -222,6 +224,8 @@ TEST_F(ImageManagerTest, DownloadUpdateItems_Success_NewItem) EXPECT_CALL(mInstallSpaceAllocatorMock, AllocateSpace(_)) .WillRepeatedly(Invoke([this](size_t) -> RetWithError> { auto space = MakeUnique(&mAllocator); + EXPECT_TRUE(space); + EXPECT_CALL(*space, Accept()).Times(AtLeast(0)); EXPECT_CALL(*space, Release()).Times(AtLeast(0)); @@ -339,6 +343,8 @@ TEST_F(ImageManagerTest, DownloadUpdateItems_AlreadyInstalled) EXPECT_CALL(mDownloadingSpaceAllocatorMock, AllocateSpace(_)) .WillRepeatedly(Invoke([this](size_t) -> RetWithError> { auto space = MakeUnique(&mAllocator); + EXPECT_TRUE(space); + EXPECT_CALL(*space, Accept()).Times(AtLeast(0)); EXPECT_CALL(*space, Release()).Times(AtLeast(0)); @@ -348,6 +354,8 @@ TEST_F(ImageManagerTest, DownloadUpdateItems_AlreadyInstalled) EXPECT_CALL(mInstallSpaceAllocatorMock, AllocateSpace(_)) .WillRepeatedly(Invoke([this](size_t) -> RetWithError> { auto space = MakeUnique(&mAllocator); + EXPECT_TRUE(space); + EXPECT_CALL(*space, Accept()).Times(AtLeast(0)); EXPECT_CALL(*space, Release()).Times(AtLeast(0)); @@ -522,6 +530,8 @@ TEST_F(ImageManagerTest, DownloadUpdateItems_MultipleItems_Success) EXPECT_CALL(mDownloadingSpaceAllocatorMock, AllocateSpace(_)) .WillRepeatedly(Invoke([this](size_t) -> RetWithError> { auto space = MakeUnique(&mAllocator); + EXPECT_TRUE(space); + EXPECT_CALL(*space, Accept()).Times(AtLeast(0)); EXPECT_CALL(*space, Release()).Times(AtLeast(0)); @@ -531,6 +541,8 @@ TEST_F(ImageManagerTest, DownloadUpdateItems_MultipleItems_Success) EXPECT_CALL(mInstallSpaceAllocatorMock, AllocateSpace(_)) .WillRepeatedly(Invoke([this](size_t) -> RetWithError> { auto space = MakeUnique(&mAllocator); + EXPECT_TRUE(space); + EXPECT_CALL(*space, Accept()).Times(AtLeast(0)); EXPECT_CALL(*space, Release()).Times(AtLeast(0)); @@ -670,6 +682,8 @@ TEST_F(ImageManagerTest, DownloadUpdateItems_Cancel_DownloadFailed) EXPECT_CALL(mDownloadingSpaceAllocatorMock, AllocateSpace(_)) .WillRepeatedly(Invoke([this](size_t) -> RetWithError> { auto space = MakeUnique(&mAllocator); + EXPECT_TRUE(space); + EXPECT_CALL(*space, Accept()).Times(AtLeast(0)); EXPECT_CALL(*space, Release()).Times(AtLeast(0)); testing::Mock::AllowLeak(space.Get()); @@ -759,6 +773,8 @@ TEST_F(ImageManagerTest, DownloadUpdateItems_RemovesOldPendingVersion) EXPECT_CALL(mDownloadingSpaceAllocatorMock, AllocateSpace(_)) .WillRepeatedly(Invoke([this](size_t) -> RetWithError> { auto space = MakeUnique(&mAllocator); + EXPECT_TRUE(space); + EXPECT_CALL(*space, Accept()).Times(AtLeast(0)); EXPECT_CALL(*space, Release()).Times(AtLeast(0)); @@ -768,6 +784,8 @@ TEST_F(ImageManagerTest, DownloadUpdateItems_RemovesOldPendingVersion) EXPECT_CALL(mInstallSpaceAllocatorMock, AllocateSpace(_)) .WillRepeatedly(Invoke([this](size_t) -> RetWithError> { auto space = MakeUnique(&mAllocator); + EXPECT_TRUE(space); + EXPECT_CALL(*space, Accept()).Times(AtLeast(0)); EXPECT_CALL(*space, Release()).Times(AtLeast(0)); @@ -876,6 +894,8 @@ TEST_F(ImageManagerTest, DownloadUpdateItems_RemovesOldFailedVersion) EXPECT_CALL(mDownloadingSpaceAllocatorMock, AllocateSpace(_)) .WillRepeatedly(Invoke([this](size_t) -> RetWithError> { auto space = MakeUnique(&mAllocator); + EXPECT_TRUE(space); + EXPECT_CALL(*space, Accept()).Times(AtLeast(0)); EXPECT_CALL(*space, Release()).Times(AtLeast(0)); @@ -885,6 +905,8 @@ TEST_F(ImageManagerTest, DownloadUpdateItems_RemovesOldFailedVersion) EXPECT_CALL(mInstallSpaceAllocatorMock, AllocateSpace(_)) .WillRepeatedly(Invoke([this](size_t) -> RetWithError> { auto space = MakeUnique(&mAllocator); + EXPECT_TRUE(space); + EXPECT_CALL(*space, Accept()).Times(AtLeast(0)); EXPECT_CALL(*space, Release()).Times(AtLeast(0)); diff --git a/src/core/cm/launcher/balancer.cpp b/src/core/cm/launcher/balancer.cpp index 6c1d15138..e16f08237 100644 --- a/src/core/cm/launcher/balancer.cpp +++ b/src/core/cm/launcher/balancer.cpp @@ -92,11 +92,19 @@ Error Balancer::PerformNodeBalancing(Array>& instances) } auto imageIndex = MakeUnique(&mAllocator); + if (!imageIndex) { + LOG_ERR() << "Can't allocate image index" << Log::Field("instance", id) << Log::Field(ErrorEnum::eNoMemory); + + mInstanceManager->ScheduleInstance(instance, AOS_ERROR_WRAP(ErrorEnum::eNoMemory)); + + continue; + } if (auto err = mImageInfoProvider->GetImageIndex(id.mItemID, info.mVersion, *imageIndex); !err.IsNone()) { LOG_ERR() << "Can't get images" << Log::Field("instance", id) << Log::Field(err); mInstanceManager->ScheduleInstance(instance, AOS_ERROR_WRAP(err)); + continue; } @@ -106,8 +114,7 @@ Error Balancer::PerformNodeBalancing(Array>& instances) LOG_DBG() << "Try to schedule instance" << Log::Field("instance", id) << Log::Field("manifest", manifest.mDigest); - scheduleErr = ScheduleInstance(instance, manifest); - if (scheduleErr.IsNone()) { + if (scheduleErr = ScheduleInstance(instance, manifest); scheduleErr.IsNone()) { LOG_DBG() << "Instance scheduled successfully" << Log::Field("nodeID", info.mNodeID); break; @@ -127,6 +134,9 @@ Error Balancer::PerformNodeBalancing(Array>& instances) Error Balancer::ScheduleInstance(SharedPtr& instance, const oci::IndexContentDescriptor& imageDescriptor) { auto nodes = MakeUnique>(&mAllocator); + if (!nodes) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } auto releaseConfigs = DeferRelease(reinterpret_cast(1), [&](int*) { instance->ResetConfigs(); }); @@ -197,6 +207,9 @@ void Balancer::FilterNodesByResources(Instance& instance, Array& nodes) RetWithError> Balancer::SelectRuntime(Instance& instance, const Array& nodes) { auto nodeRuntimes = MakeUnique(&mAllocator); + if (!nodeRuntimes) { + return {nullptr, AOS_ERROR_WRAP(ErrorEnum::eNoMemory)}; + } if (auto err = CreateRuntimes(nodes, *nodeRuntimes); !err.IsNone()) { return {nullptr, AOS_ERROR_WRAP(err)}; @@ -385,6 +398,9 @@ void Balancer::FilterTopPriorityNodes(NodeRuntimes& nodes) Error Balancer::PerformPolicyBalancing(Array>& instances) { auto imageIndex = MakeUnique(&mAllocator); + if (!imageIndex) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } for (auto& instance : instances) { const auto& info = instance->GetInfo(); @@ -466,6 +482,9 @@ Error Balancer::UpdateMonitoringData(bool isInitialUpdate) const auto& nodeID = node.GetInfo().mNodeID; auto nodeMonitoring = MakeUnique(&mAllocator); + if (!nodeMonitoring) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } // Monitoring data immediately after startup is not availble. // Assign zero consumption on start. diff --git a/src/core/cm/launcher/imageinfoprovider.cpp b/src/core/cm/launcher/imageinfoprovider.cpp index 7198363e0..8233e34b3 100644 --- a/src/core/cm/launcher/imageinfoprovider.cpp +++ b/src/core/cm/launcher/imageinfoprovider.cpp @@ -20,8 +20,19 @@ void ImageInfoProvider::Init(imagemanager::ItemInfoProviderItf& itemInfoProvider Error ImageInfoProvider::GetImageConfig(const oci::IndexContentDescriptor& imageDescriptor, oci::ImageConfig& config) { auto manifestPath = MakeUnique>(&mAllocator); - auto manifest = MakeUnique(&mAllocator); - auto configPath = MakeUnique>(&mAllocator); + if (!manifestPath) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + + auto manifest = MakeUnique(&mAllocator); + if (!manifest) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + + auto configPath = MakeUnique>(&mAllocator); + if (!configPath) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mItemInfoProvider->GetBlobPath(imageDescriptor.mDigest, *manifestPath); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -45,8 +56,19 @@ Error ImageInfoProvider::GetImageConfig(const oci::IndexContentDescriptor& image Error ImageInfoProvider::GetItemConfig(const oci::IndexContentDescriptor& imageDescriptor, oci::ItemConfig& itemConfig) { auto manifestPath = MakeUnique>(&mAllocator); - auto manifest = MakeUnique(&mAllocator); - auto servicePath = MakeUnique>(&mAllocator); + if (!manifestPath) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + + auto manifest = MakeUnique(&mAllocator); + if (!manifest) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + + auto servicePath = MakeUnique>(&mAllocator); + if (!servicePath) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mItemInfoProvider->GetBlobPath(imageDescriptor.mDigest, *manifestPath); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -74,7 +96,14 @@ Error ImageInfoProvider::GetItemConfig(const oci::IndexContentDescriptor& imageD Error ImageInfoProvider::GetImageIndex(const String& itemID, const String& version, oci::ImageIndex& imageIndex) { auto indexDigest = MakeUnique>(&mAllocator); - auto indexPath = MakeUnique>(&mAllocator); + if (!indexDigest) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + + auto indexPath = MakeUnique>(&mAllocator); + if (!indexPath) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mItemInfoProvider->GetIndexDigest(itemID, version, *indexDigest); !err.IsNone()) { return AOS_ERROR_WRAP(err); diff --git a/src/core/cm/launcher/instance.cpp b/src/core/cm/launcher/instance.cpp index 48fbf62a7..f9a7b12d7 100644 --- a/src/core/cm/launcher/instance.cpp +++ b/src/core/cm/launcher/instance.cpp @@ -37,8 +37,15 @@ Instance::Instance( Error Instance::LoadConfigs(const oci::IndexContentDescriptor& imageDescriptor) { - mItemConfig = MakeUnique(&mAllocator); + mItemConfig = MakeUnique(&mAllocator); + if (!mItemConfig) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + mImageConfig = MakeUnique(&mAllocator); + if (!mImageConfig) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } auto releaseConfigs = DeferRelease(reinterpret_cast(1), [&](int*) { ResetConfigs(); }); if (auto err = mImageInfoProvider.GetItemConfig(imageDescriptor, *mItemConfig); !err.IsNone()) { @@ -74,6 +81,11 @@ bool Instance::IsImageValid() } auto imageIndex = MakeUnique(&mAllocator); + if (!imageIndex) { + LOG_ERR() << "Can't allocate image index" << Log::Field(ErrorEnum::eNoMemory); + + return false; + } auto err = mImageInfoProvider.GetImageIndex(mInfo.mInstanceIdent.mItemID, mInfo.mVersion, *imageIndex); if (!err.IsNone()) { @@ -196,6 +208,9 @@ bool Instance::AreNodeLabelsOk(const LabelsArray& nodeLabels) RetWithError Instance::OverrideEnvVars(const OverrideEnvVarsRequest& envVars) { auto newEnvVars = MakeUnique(&mAllocator); + if (!newEnvVars) { + return {false, AOS_ERROR_WRAP(ErrorEnum::eNoMemory)}; + } for (const auto& item : envVars.mItems) { if (!item.Match(mInfo.mInstanceIdent)) { diff --git a/src/core/cm/launcher/instancemanager.cpp b/src/core/cm/launcher/instancemanager.cpp index c4f024be2..cd9129897 100644 --- a/src/core/cm/launcher/instancemanager.cpp +++ b/src/core/cm/launcher/instancemanager.cpp @@ -218,6 +218,9 @@ RetWithError> InstanceManager::CreateInstance(const RunInsta } auto instanceInfo = CreateInfo(id, "", "", request); + if (!instanceInfo) { + return {nullptr, AOS_ERROR_WRAP(ErrorEnum::eNoMemory)}; + } if (auto err = mStorage->AddInstance(*instanceInfo); !err.IsNone()) { return {nullptr, AOS_ERROR_WRAP(err)}; @@ -241,6 +244,9 @@ RetWithError> InstanceManager::CreateInstance(const RunInsta auto id = InstanceIdent {request.mItemID, request.mSubjectInfo.mSubjectID, index, request.mUpdateItemType}; auto instanceInfo = CreateInfo(id, nodeID, runtimeID, request); + if (!instanceInfo) { + return {nullptr, AOS_ERROR_WRAP(ErrorEnum::eNoMemory)}; + } if (auto err = mStorage->AddInstance(*instanceInfo); !err.IsNone()) { return {nullptr, AOS_ERROR_WRAP(err)}; @@ -416,6 +422,10 @@ Error InstanceManager::LoadInstancesFromStorage() mCachedInstances.Clear(); auto instances = MakeUnique>(&mAllocator); + if (!instances) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + if (auto err = mStorage->LoadActiveInstances(*instances); !err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -561,6 +571,10 @@ RetWithError> InstanceManager::CreateInstance(const Instance return {{}, AOS_ERROR_WRAP(ErrorEnum::eNotSupported)}; } + if (!newInstance) { + return {nullptr, AOS_ERROR_WRAP(ErrorEnum::eNoMemory)}; + } + if (auto err = newInstance->Init(); !err.IsNone()) { // Do not leave invalid instance in storage. if (auto rmErr = newInstance->Remove(); !rmErr.IsNone()) { @@ -723,6 +737,11 @@ UniquePtr InstanceManager::CreateInfo( const InstanceIdent& id, const String& nodeID, const String& runtimeID, const RunInstanceRequest& request) { auto info = MakeUnique(&mAllocator); + if (!info) { + LOG_ERR() << "Can't allocate instance info" << Log::Field(ErrorEnum::eNoMemory); + + return info; + } info->mInstanceIdent = id; info->mManifestDigest = ""; diff --git a/src/core/cm/launcher/launcher.cpp b/src/core/cm/launcher/launcher.cpp index b2cf1dde6..379c2fd76 100644 --- a/src/core/cm/launcher/launcher.cpp +++ b/src/core/cm/launcher/launcher.cpp @@ -110,6 +110,9 @@ Error Launcher::Start() // Set initial subjects list. auto subjects = MakeUnique(&mAllocator); + if (!subjects) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mIdentProvider->GetSubjects(*subjects); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -301,6 +304,12 @@ void Launcher::UpdateInstanceStatuses() // Copy old statuses. auto oldInstanceStatuses = MakeUnique>(&mAllocator); + if (!oldInstanceStatuses) { + LOG_ERR() << "Failed to allocate old instance statuses" << Log::Field(AOS_ERROR_WRAP(ErrorEnum::eNoMemory)); + + return; + } + if (auto err = oldInstanceStatuses->Assign(mInstanceStatuses); !err.IsNone()) { LOG_ERR() << "Failed to copy old instance statuses" << Log::Field(AOS_ERROR_WRAP(err)); @@ -341,6 +350,11 @@ void Launcher::UpdateInstanceStatuses() // Find new statuses. auto changedStatuses = MakeUnique>(&mAllocator); + if (!changedStatuses) { + LOG_ERR() << "Failed to allocate changed statuses" << Log::Field(AOS_ERROR_WRAP(ErrorEnum::eNoMemory)); + + return; + } for (size_t i = 0; i < mInstanceStatuses.Size(); ++i) { auto newStatus = !oldInstanceStatuses->Contains(mInstanceStatuses[i]); @@ -389,6 +403,10 @@ Error Launcher::BalanceInstances(UniqueLock& lock, bool rebalance) // Create instances from run requests. auto instances = MakeUnique, cMaxNumInstances>>(&mAllocator); + if (!instances) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + mRunRequestsLoader.CreateInstances(mNodeManager.GetNodes(), *instances); auto runErr = mBalancer.RunInstances(lock, *instances, rebalance); diff --git a/src/core/cm/launcher/node.cpp b/src/core/cm/launcher/node.cpp index 4eb880a0d..84001942d 100644 --- a/src/core/cm/launcher/node.cpp +++ b/src/core/cm/launcher/node.cpp @@ -268,8 +268,15 @@ Error Node::ReserveResources(const InstanceIdent& instanceIdent, const String& r Error Node::SendScheduledInstances( const Array>& scheduledInstances, const Array& runningInstances) { - auto stopInstances = MakeUnique>(mAllocator); + auto stopInstances = MakeUnique>(mAllocator); + if (!stopInstances) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + auto startInstances = MakeUnique>(mAllocator); + if (!startInstances) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } for (const auto& status : FilterActiveNodeInstances(runningInstances, mInfo.mNodeID)) { // Check if the instance is scheduled on this node (ident, runtime, node, and service version must match). @@ -318,8 +325,16 @@ Error Node::SendScheduledInstances( RetWithError Node::ResendInstances( const Array>& activeInstances, const Array& runningInstances, bool forceRestart) { - auto stopInstances = MakeUnique>(mAllocator); - auto startInstances = MakeUnique>(mAllocator); + auto stopInstances = MakeUnique>(mAllocator); + if (!stopInstances) { + return {false, AOS_ERROR_WRAP(ErrorEnum::eNoMemory)}; + } + + auto startInstances = MakeUnique>(mAllocator); + if (!startInstances) { + return {false, AOS_ERROR_WRAP(ErrorEnum::eNoMemory)}; + } + size_t runningNodeInstances = 0; for (const auto& status : FilterActiveNodeInstances(runningInstances, mInfo.mNodeID)) { diff --git a/src/core/cm/launcher/nodemanager.cpp b/src/core/cm/launcher/nodemanager.cpp index e35b345fa..6aecc3ed1 100644 --- a/src/core/cm/launcher/nodemanager.cpp +++ b/src/core/cm/launcher/nodemanager.cpp @@ -36,6 +36,9 @@ void NodeManager::Init(nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider, Error NodeManager::Start() { auto nodes = MakeUnique, cMaxNumNodes>>(&mAllocator); + if (!nodes) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mNodeInfoProvider->GetAllNodeIDs(*nodes); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -44,6 +47,9 @@ Error NodeManager::Start() LOG_DBG() << "Start node manager" << Log::Field("nodes", nodes->Size()); auto nodeInfo = MakeUnique(&mAllocator); + if (!nodeInfo) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } for (const auto& nodeID : *nodes) { if (auto err = mNodeInfoProvider->GetNodeInfo(nodeID, *nodeInfo); !err.IsNone()) { @@ -105,11 +111,19 @@ Error NodeManager::LoadSMDataForActiveInstances( if (node == nullptr) { LOG_ERR() << "Can't find node" << Log::Field("instanceID", instanceID) << Log::Field("nodeID", nodeID) << Log::Field(AOS_ERROR_WRAP(ErrorEnum::eNotFound)); + continue; } auto imageDescriptor = MakeUnique(&mAllocator); - auto findDescErr = FindImageDescriptor( + if (!imageDescriptor) { + LOG_ERR() << "Can't allocate image descriptor" << Log::Field("instanceID", instanceID) + << Log::Field(AOS_ERROR_WRAP(ErrorEnum::eNoMemory)); + + continue; + } + + auto findDescErr = FindImageDescriptor( instanceID.mItemID, instance->GetInfo().mVersion, manifestDigest, imageInfoProvider, *imageDescriptor); if (!findDescErr.IsNone()) { LOG_ERR() << "Can't find image descriptor" << Log::Field("instanceID", instanceID) @@ -352,6 +366,9 @@ Error NodeManager::FindImageDescriptor(const String& itemID, const String& versi ImageInfoProvider& imageInfoProvider, oci::IndexContentDescriptor& imageDescriptor) { auto imageIndex = MakeUnique(&mAllocator); + if (!imageIndex) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = imageInfoProvider.GetImageIndex(itemID, version, *imageIndex); !err.IsNone()) { return AOS_ERROR_WRAP(err); diff --git a/src/core/cm/launcher/runrequestsloader.cpp b/src/core/cm/launcher/runrequestsloader.cpp index cf865001c..11b3e6ed3 100644 --- a/src/core/cm/launcher/runrequestsloader.cpp +++ b/src/core/cm/launcher/runrequestsloader.cpp @@ -89,13 +89,23 @@ Error RunRequestsLoader::GenerateInstances( const RunInstanceRequest& request, const Array& nodes, Array>& instances) { auto imageIndex = MakeUnique(&mAllocator); + if (!imageIndex) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mImageInfoProvider->GetImageIndex(request.mItemID, request.mVersion, *imageIndex); !err.IsNone()) { return AOS_ERROR_WRAP(err); } auto combinedRuntimes = MakeUnique(&mAllocator); - auto itemConfig = MakeUnique(&mAllocator); + if (!combinedRuntimes) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + + auto itemConfig = MakeUnique(&mAllocator); + if (!itemConfig) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = CombinedRuntimes(*imageIndex, *combinedRuntimes, *itemConfig); !err.IsNone()) { return AOS_ERROR_WRAP(err); diff --git a/src/core/cm/launcher/storagestate.cpp b/src/core/cm/launcher/storagestate.cpp index a3f1f259f..4f4f1e72f 100644 --- a/src/core/cm/launcher/storagestate.cpp +++ b/src/core/cm/launcher/storagestate.cpp @@ -44,6 +44,10 @@ Error StorageState::PrepareForBalancing() mAvailableStorage = MakeShared(&mAllocator, 0); } + if (!mAvailableState || !mAvailableStorage) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + const auto& [stateSize, stateErr] = mStorageStateManager->GetTotalStateSize(); if (!stateErr.IsNone()) { return AOS_ERROR_WRAP(stateErr); diff --git a/src/core/cm/nodeinfoprovider/nodeinfoprovider.cpp b/src/core/cm/nodeinfoprovider/nodeinfoprovider.cpp index e29e2cd6d..f48136fa3 100644 --- a/src/core/cm/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/core/cm/nodeinfoprovider/nodeinfoprovider.cpp @@ -36,6 +36,9 @@ Error NodeInfoProvider::Start() } auto ids = MakeUnique, cMaxNumNodes>>(&mAllocator); + if (!ids) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mNodeInfoProvider->GetAllNodeIDs(*ids); !err.IsNone()) { return err; @@ -43,6 +46,9 @@ Error NodeInfoProvider::Start() for (const auto& id : *ids) { auto nodeInfo = MakeUnique(&mAllocator); + if (!nodeInfo) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mNodeInfoProvider->GetNodeInfo(id, *nodeInfo); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -250,6 +256,11 @@ NodeInfoCache* NodeInfoProvider::AddOrGetCacheItem(const String& nodeID) void NodeInfoProvider::NotifyListeners(const NodeInfoCache& info) { auto unitNodeInfo = MakeUnique(&mAllocator); + if (!unitNodeInfo) { + LOG_ERR() << "Can't allocate unit node info" << Log::Field(ErrorEnum::eNoMemory); + + return; + } info.GetUnitNodeInfo(*unitNodeInfo); diff --git a/src/core/cm/storagestate/storagestate.cpp b/src/core/cm/storagestate/storagestate.cpp index 4f1bf36e8..f6f513dbf 100644 --- a/src/core/cm/storagestate/storagestate.cpp +++ b/src/core/cm/storagestate/storagestate.cpp @@ -137,6 +137,9 @@ Error StorageState::UpdateState(const aos::UpdateState& state) } auto storageStateInfo = MakeUnique(&mAllocator); + if (!storageStateInfo) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mStorage->GetStorageStateInfo(state, *storageStateInfo); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -189,6 +192,9 @@ Error StorageState::AcceptState(const StateAcceptance& state) } auto storageStateInfo = MakeUnique(&mAllocator); + if (!storageStateInfo) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mStorage->GetStorageStateInfo(state, *storageStateInfo); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -213,10 +219,16 @@ Error StorageState::Setup( LOG_DBG() << "Setup storage and state" << setupParams; auto storageData = MakeUnique(&mAllocator); + if (!storageData) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } auto err = mStorage->GetStorageStateInfo(instanceIdent, *storageData); if (err.Is(ErrorEnum::eNotFound)) { storageData = MakeUnique(&mAllocator); + if (!storageData) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } storageData->mInstanceIdent = instanceIdent; @@ -353,6 +365,9 @@ Error StorageState::InitStateWatching() LOG_DBG() << "Init state watching"; auto infos = MakeUnique(&mAllocator); + if (!infos) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mStorage->GetAllStorageStateInfo(*infos); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -474,6 +489,9 @@ Error StorageState::CheckChecksumAndSendUpdateRequest(const State& state) LOG_DBG() << "Check checksum and send update request" << state; auto stateContent = MakeUnique>(&mAllocator); + if (!stateContent) { + return ErrorEnum::eNoMemory; + } if (auto err = fs::ReadFileToString(state.mFilePath, *stateContent); !err.IsNone()) { return err; @@ -575,6 +593,9 @@ Error StorageState::SetQuotas(const SetupParams& setupParams) Error StorageState::SendNewStateIfFileChanged(State& state) { auto newState = MakeUnique(&mAllocator); + if (!newState) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } static_cast(*newState) = state.mInstanceIdent; diff --git a/src/core/cm/unitconfig/unitconfig.cpp b/src/core/cm/unitconfig/unitconfig.cpp index 98aee4419..12aa9b298 100644 --- a/src/core/cm/unitconfig/unitconfig.cpp +++ b/src/core/cm/unitconfig/unitconfig.cpp @@ -84,6 +84,9 @@ Error UnitConfig::CheckUnitConfig(const aos::UnitConfig& config) for (const auto& id : nodeIds) { auto nodeInfo = MakeUnique(&mAllocator); + if (!nodeInfo) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mNodeInfoProvider->GetNodeInfo(id, *nodeInfo); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -103,6 +106,9 @@ Error UnitConfig::CheckUnitConfig(const aos::UnitConfig& config) if (nodeConfigStatus.mVersion != config.mVersion || !nodeConfigStatus.mError.IsNone()) { auto nodeConfig = MakeUnique(&mAllocator); + if (!nodeConfig) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = FindNodeConfig(nodeInfo->mNodeID, nodeInfo->mNodeType, config, *nodeConfig); !err.IsNone()) { return err; @@ -144,6 +150,9 @@ Error UnitConfig::UpdateUnitConfig(const aos::UnitConfig& unitConfig) mUnitConfig = unitConfig; auto unitConfigJSON = MakeUnique>(&mAllocator); + if (!unitConfigJSON) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mJSONProvider->UnitConfigToJSON(unitConfig, *unitConfigJSON); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -164,7 +173,14 @@ Error UnitConfig::UpdateUnitConfig(const aos::UnitConfig& unitConfig) for (const auto& id : nodeIds) { auto nodeConfig = MakeUnique(&mAllocator); - auto nodeInfo = MakeUnique(&mAllocator); + if (!nodeConfig) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + + auto nodeInfo = MakeUnique(&mAllocator); + if (!nodeInfo) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mNodeInfoProvider->GetNodeInfo(id, *nodeInfo); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -228,6 +244,11 @@ void UnitConfig::OnNodeInfoChanged(const UnitNodeInfo& info) } auto nodeConfig = MakeUnique(&mAllocator); + if (!nodeConfig) { + LOG_ERR() << "Can't allocate node config" << Log::Field(ErrorEnum::eNoMemory); + + return; + } if (auto err = FindNodeConfig(info.mNodeID, info.mNodeType, mUnitConfig, *nodeConfig); !err.IsNone()) { LOG_ERR() << "Error finding node config" << Log::Field(err); @@ -251,6 +272,9 @@ Error UnitConfig::LoadConfig() LOG_DBG() << "Load config"; auto unitConfig = MakeUnique>(&mAllocator); + if (!unitConfig) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } auto err = fs::ReadFileToString(mUnitConfigFile, *unitConfig); if (!err.IsNone()) { diff --git a/src/core/cm/updatemanager/desiredstatushandler.cpp b/src/core/cm/updatemanager/desiredstatushandler.cpp index 7c8ce5f33..f05a832b1 100644 --- a/src/core/cm/updatemanager/desiredstatushandler.cpp +++ b/src/core/cm/updatemanager/desiredstatushandler.cpp @@ -332,6 +332,9 @@ void DesiredStatusHandler::SetState(UpdateState state) Error DesiredStatusHandler::DownloadUpdateItems() { auto itemsStatuses = MakeUnique>(&mAllocator); + if (!itemsStatuses) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } LOG_DBG() << "Download update items" << Log::Field("count", mCurrentDesiredStatus.mUpdateItems.Size()); @@ -402,8 +405,15 @@ Error DesiredStatusHandler::InstallDesiredStatus() Error DesiredStatusHandler::LaunchInstances() { - auto runRequest = MakeUnique>(&mAllocator); + auto runRequest = MakeUnique>(&mAllocator); + if (!runRequest) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + auto instancesStatuses = MakeUnique>(&mAllocator); + if (!instancesStatuses) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } LOG_DBG() << "Launch instances" << Log::Field("count", mCurrentDesiredStatus.mInstances.Size()); @@ -459,6 +469,9 @@ Error DesiredStatusHandler::LaunchInstances() Error DesiredStatusHandler::WaitInstancesActive() { auto instancesStatuses = MakeUnique>(&mAllocator); + if (!instancesStatuses) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } while (mIsRunning) { if (auto err = mLauncher->GetInstancesStatuses(*instancesStatuses); !err.IsNone()) { @@ -492,6 +505,9 @@ Error DesiredStatusHandler::WaitInstancesActive() Error DesiredStatusHandler::FinalizeUpdate() { auto itemsStatuses = MakeUnique>(&mAllocator); + if (!itemsStatuses) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } LOG_DBG() << "Install update items" << Log::Field("count", mCurrentDesiredStatus.mUpdateItems.Size()); @@ -535,6 +551,11 @@ bool DesiredStatusHandler::IsUpdateRequired(const DesiredStatus& desiredStatus) bool DesiredStatusHandler::IsUpdateItemsRequired(const DesiredStatus& desiredStatus) const { auto itemsStatuses = MakeUnique>(&mAllocator); + if (!itemsStatuses) { + LOG_ERR() << "Failed to allocate update items statuses" << Log::Field(ErrorEnum::eNoMemory); + + return true; + } if (auto err = mImageManager->GetUpdateItemsStatuses(*itemsStatuses); !err.IsNone()) { LOG_ERR() << "Failed to get update items statuses" << Log::Field(err); @@ -595,6 +616,11 @@ bool DesiredStatusHandler::IsSameUpdate(const DesiredStatus& desiredStatus) cons bool DesiredStatusHandler::IsUpdateInstancesRequired(const DesiredStatus& desiredStatus) const { auto instancesStatuses = MakeUnique>(&mAllocator); + if (!instancesStatuses) { + LOG_ERR() << "Failed to allocate instances statuses" << Log::Field(ErrorEnum::eNoMemory); + + return true; + } if (auto err = mLauncher->GetInstancesStatuses(*instancesStatuses); !err.IsNone()) { LOG_ERR() << "Failed to get instances statuses" << Log::Field(err); diff --git a/src/core/cm/updatemanager/unitstatushandler.cpp b/src/core/cm/updatemanager/unitstatushandler.cpp index 14c0a61d0..c4939b98b 100644 --- a/src/core/cm/updatemanager/unitstatushandler.cpp +++ b/src/core/cm/updatemanager/unitstatushandler.cpp @@ -444,6 +444,9 @@ Error UnitStatusHandler::SetNodesInfo() Error UnitStatusHandler::SetUpdateItemsStatus() { auto itemsStatuses = MakeUnique(&mAllocator); + if (!itemsStatuses) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } mItemStatusProvider->GetUpdateItemsStatuses(*itemsStatuses); @@ -468,6 +471,9 @@ Error UnitStatusHandler::SetInstancesStatus() mUnitInstancesStatuses.Clear(); auto instancesStatuses = MakeUnique>(&mAllocator); + if (!instancesStatuses) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mInstanceStatusProvider->GetInstancesStatuses(*instancesStatuses); !err.IsNone()) { return AOS_ERROR_WRAP(err); diff --git a/src/core/common/crypto/certloader.cpp b/src/core/common/crypto/certloader.cpp index c64e32d37..146b2bd36 100644 --- a/src/core/common/crypto/certloader.cpp +++ b/src/core/common/crypto/certloader.cpp @@ -165,7 +165,11 @@ RetWithError> CertLoader::OpenSession( RetWithError CertLoader::FindToken(const pkcs11::LibraryContext& library, const String& token) { StaticArray slotList; - auto tokenInfo = MakeUnique(&mAllocator); + + auto tokenInfo = MakeUnique(&mAllocator); + if (!tokenInfo) { + return {0, ErrorEnum::eNoMemory}; + } auto err = library.GetSlotList(true, slotList); if (!err.IsNone()) { @@ -191,6 +195,9 @@ RetWithError> CertLoader::LoadCertsFromFile(co LOG_DBG() << "Load certs chain from file: fileName=" << fileName; auto buff = MakeUnique(&mAllocator); + if (!buff) { + return {nullptr, ErrorEnum::eNoMemory}; + } auto err = fs::ReadFileToString(fileName, *buff); if (!err.IsNone()) { @@ -198,6 +205,9 @@ RetWithError> CertLoader::LoadCertsFromFile(co } auto certificates = MakeShared(&mAllocator); + if (!certificates) { + return {nullptr, ErrorEnum::eNoMemory}; + } err = mCryptoProvider->PEMToX509Certs(*buff, *certificates); @@ -209,6 +219,9 @@ RetWithError> CertLoader::LoadPrivKeyFromFile(const Str LOG_DBG() << "Load private key from file: fileName=" << fileName; auto buff = MakeUnique>(&mAllocator); + if (!buff) { + return {nullptr, ErrorEnum::eNoMemory}; + } auto err = fs::ReadFileToString(fileName, *buff); if (!err.IsNone()) { diff --git a/src/core/common/crypto/cryptohelper.cpp b/src/core/common/crypto/cryptohelper.cpp index 0c1ccccd2..e3115173d 100644 --- a/src/core/common/crypto/cryptohelper.cpp +++ b/src/core/common/crypto/cryptohelper.cpp @@ -30,6 +30,9 @@ Error CryptoHelper::Init(iamclient::CertProviderItf& certProvider, CryptoProvide mServiceDiscoveryURL = serviceDiscoveryURL; auto caCertsPEM = MakeUnique>(&mAllocator); + if (!caCertsPEM) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = fs::ReadFileToString(caCert, *caCertsPEM); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -111,6 +114,9 @@ Error CryptoHelper::ValidateSigns(const String& decryptedPath, const SignInfo& s LockGuard lock {mSemaphore}; auto signCtx = MakeUnique(&mAllocator); + if (!signCtx) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = AddCertificates(certs, *signCtx); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -132,7 +138,14 @@ Error CryptoHelper::DecryptMetadata(const Array& input, Array& LockGuard lock {mSemaphore}; auto contentInfo = MakeUnique(&mAllocator); - auto symKey = MakeUnique>(&mAllocator); + if (!contentInfo) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + + auto symKey = MakeUnique>(&mAllocator); + if (!symKey) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } auto err = UnmarshalCMS(input, *contentInfo); if (!err.IsNone()) { @@ -165,6 +178,10 @@ Error CryptoHelper::DecryptMetadata(const Array& input, Array& RetWithError> CryptoHelper::GetOnlineCert() { auto certInfo = MakeUnique(&mAllocator); + if (!certInfo) { + return {{}, AOS_ERROR_WRAP(ErrorEnum::eNoMemory)}; + } + if (auto err = mCertProvider->GetCert(cOnlineCert, {}, {}, *certInfo); !err.IsNone()) { return {{}, AOS_ERROR_WRAP(err)}; } @@ -206,6 +223,9 @@ Error CryptoHelper::GetServiceDiscoveryFromOrganization( const x509::Certificate& cert, Array>& urls) { auto subject = MakeUnique>(&mAllocator); + if (!subject) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mCryptoProvider->ASN1DecodeDN(cert.mSubject, *subject); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -222,7 +242,14 @@ Error CryptoHelper::GetServiceDiscoveryFromOrganization( auto [valueEnd, _] = subject->FindSubstr(valueStart, ","); auto orgName = MakeUnique>(&mAllocator); - auto url = MakeUnique>(&mAllocator); + if (!orgName) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + + auto url = MakeUnique>(&mAllocator); + if (!url) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } auto assignErr = orgName->Insert(orgName->begin(), subject->begin() + valueStart, subject->begin() + valueEnd); if (!assignErr.IsNone()) { @@ -331,8 +358,15 @@ Error CryptoHelper::CheckSessionKey( Error CryptoHelper::DecodeFile(const String& encryptedFile, const String& decryptedFile, AESCipherItf& decoder) { - auto inBlock = MakeUnique>(&mAllocator); + auto inBlock = MakeUnique>(&mAllocator); + if (!inBlock) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + auto outBlock = MakeUnique>(&mAllocator); + if (!outBlock) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } fs::File inputFile, outputFile; @@ -411,6 +445,9 @@ Error CryptoHelper::AddCertificates(const Array& certs, SignCon } auto cert = MakeUnique(&mAllocator); + if (!cert) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mCryptoProvider->DERToX509Cert(certInfo.mCertificate, *cert); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -476,6 +513,9 @@ Error CryptoHelper::VerifySigns(const String& file, const SignInfo& signs, SignC // Verify sign auto hashSum = MakeUnique>(&mAllocator); + if (!hashSum) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = CalculateFileHash(file, hash, *mCryptoProvider, *hashSum); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -501,6 +541,9 @@ Error CryptoHelper::VerifySigns(const String& file, const SignInfo& signs, SignC // Verify certs auto intermCertPool = MakeUnique>(&mAllocator); + if (!intermCertPool) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = CreateIntermCertPool(signCtx, *chain, *intermCertPool); !err.IsNone()) { return err; @@ -857,6 +900,9 @@ Error CryptoHelper::ParseEncryptedContentInfo(const Array& data, Encryp Error CryptoHelper::GetKeyForEnvelope(const TransRecipientInfo& info, Array& symmetricKey) { auto certInfo = MakeUnique(&mAllocator); + if (!certInfo) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } auto err = mCertProvider->GetCert(cOfflineCert, info.mRID.mIssuer, info.mRID.mSerial, *certInfo); if (!err.IsNone()) { @@ -921,6 +967,9 @@ Error CryptoHelper::DecryptMessage( Error CryptoHelper::DecodeMessage(AESCipherItf& decoder, const Array& input, Array& message) { auto outBlock = MakeUnique>(&mAllocator); + if (!outBlock) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (input.Size() % AESCipherItf::cBlockSize != 0) { return AOS_ERROR_WRAP(Error(ErrorEnum::eInvalidArgument, "message should be a multiple of CBC block size")); diff --git a/src/core/common/crypto/mbedtls/cryptoprovider.cpp b/src/core/common/crypto/mbedtls/cryptoprovider.cpp index ec3980795..addb2d326 100644 --- a/src/core/common/crypto/mbedtls/cryptoprovider.cpp +++ b/src/core/common/crypto/mbedtls/cryptoprovider.cpp @@ -828,6 +828,9 @@ RetWithError> MbedTLSCryptoProvider::PEMToX509PrivKey(c LOG_ERR() << "Create private key from PEM"; auto res = MakeShared(&mAllocator); + if (!res) { + return {{}, ErrorEnum::eNoMemory}; + } auto err = res->Init(pemBlob); if (!err.IsNone()) { @@ -942,6 +945,10 @@ RetWithError> MbedTLSCryptoProvider::CreateHash(Hash algorith } auto hasher = MakeUnique(&mAllocator, alg); + if (!hasher) { + return {nullptr, ErrorEnum::eNoMemory}; + } + if (auto err = hasher->Init(); !err.IsNone()) { return {nullptr, AOS_ERROR_WRAP(err)}; } @@ -1056,6 +1063,9 @@ RetWithError> MbedTLSCryptoProvider::CreateAESEncoder( } auto cipher = MakeUnique(&mAllocator); + if (!cipher) { + return {{}, ErrorEnum::eNoMemory}; + } auto err = cipher->Init(key, iv, true); if (!err.IsNone()) { @@ -1073,6 +1083,9 @@ RetWithError> MbedTLSCryptoProvider::CreateAESDecoder( } auto cipher = MakeUnique(&mAllocator); + if (!cipher) { + return {{}, ErrorEnum::eNoMemory}; + } auto err = cipher->Init(key, iv, false); if (!err.IsNone()) { diff --git a/src/core/common/crypto/openssl/cryptoprovider.cpp b/src/core/common/crypto/openssl/cryptoprovider.cpp index 5fa63dd78..11db12e9a 100644 --- a/src/core/common/crypto/openssl/cryptoprovider.cpp +++ b/src/core/common/crypto/openssl/cryptoprovider.cpp @@ -1494,6 +1494,9 @@ RetWithError> OpenSSLCryptoProvider::PEMToX509PrivKey(c auto type = EVP_PKEY_base_id(pkey.Get()); if (type == EVP_PKEY_RSA) { auto res = MakeShared(&mAllocator); + if (!res) { + return {{}, ErrorEnum::eNoMemory}; + } auto err = res->Init(pkey.Get()); if (!err.IsNone()) { @@ -1769,6 +1772,9 @@ RetWithError> OpenSSLCryptoProvider::CreateHash(Hash algorith } auto hasher = MakeUnique(&mAllocator); + if (!hasher) { + return {{}, ErrorEnum::eNoMemory}; + } auto err = hasher->Init(mLibCtx, algorithm.ToString().CStr()); if (!err.IsNone()) { @@ -1856,6 +1862,9 @@ RetWithError> OpenSSLCryptoProvider::CreateAESEncoder( } auto cipher = MakeUnique(&mAllocator); + if (!cipher) { + return {{}, ErrorEnum::eNoMemory}; + } auto err = cipher->Init(mLibCtx, key, iv, true); if (!err.IsNone()) { @@ -1873,6 +1882,9 @@ RetWithError> OpenSSLCryptoProvider::CreateAESDecoder( } auto cipher = MakeUnique(&mAllocator); + if (!cipher) { + return {{}, ErrorEnum::eNoMemory}; + } auto err = cipher->Init(mLibCtx, key, iv, false); if (!err.IsNone()) { diff --git a/src/core/common/monitoring/average.cpp b/src/core/common/monitoring/average.cpp index f5b6d6dc3..cacc41366 100644 --- a/src/core/common/monitoring/average.cpp +++ b/src/core/common/monitoring/average.cpp @@ -125,6 +125,9 @@ Error Average::StartInstanceMonitoring(const InstanceIdent& instanceIdent) } auto averageData = MakeUnique(&mAllocator); + if (!averageData) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mAverageInstancesData.Set(instanceIdent, *averageData); !err.IsNone()) { return AOS_ERROR_WRAP(err); diff --git a/src/core/common/monitoring/monitoring.cpp b/src/core/common/monitoring/monitoring.cpp index ad3826d0f..760c20d2c 100644 --- a/src/core/common/monitoring/monitoring.cpp +++ b/src/core/common/monitoring/monitoring.cpp @@ -144,6 +144,9 @@ Error Monitoring::Start() if (mInstanceInfoProvider) { auto statuses = MakeUnique(&mAllocator); + if (!statuses) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mInstanceInfoProvider->GetInstancesStatuses(*statuses); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -164,6 +167,9 @@ Error Monitoring::Start() { auto nodeConfig = MakeUnique(&mAllocator); + if (!nodeConfig) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mNodeConfigProvider->GetNodeConfig(*nodeConfig); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -401,7 +407,13 @@ void Monitoring::ProcessMonitoring() { UniqueLock lock {mMutex}; - auto nodeMonitoringData = MakeUnique(&mAllocator); + auto nodeMonitoringData = MakeUnique(&mAllocator); + if (!nodeMonitoringData) { + LOG_ERR() << "Can't allocate node monitoring data" << Log::Field(ErrorEnum::eNoMemory); + + return; + } + nodeMonitoringData->mMonitoringData.mTimestamp = Time::Now(); GetInstanceMonitoringData(nodeMonitoringData->mInstances); diff --git a/src/core/common/pkcs11/pkcs11.cpp b/src/core/common/pkcs11/pkcs11.cpp index 9b4c7ee51..c204f8b19 100644 --- a/src/core/common/pkcs11/pkcs11.cpp +++ b/src/core/common/pkcs11/pkcs11.cpp @@ -551,6 +551,9 @@ RetWithError> LibraryContext::PKCS11OpenSession(SlotID } auto session = MakeShared(&mAllocator, handle, mFunctionList); + if (!session) { + return {nullptr, ErrorEnum::eNoMemory}; + } return {session, ErrorEnum::eNone}; } @@ -1266,7 +1269,11 @@ RetWithError> Utils::FindCertificateCh } SharedPtr certificate; - auto chain = MakeShared(&mAllocator); + + auto chain = MakeShared(&mAllocator); + if (!chain) { + return {nullptr, ErrorEnum::eNoMemory}; + } Tie(certificate, err) = GetCertificate(certHandles[0]); if (!err.IsNone()) { @@ -1331,7 +1338,14 @@ RetWithError Utils::ExportPrivateKey( attrTypes.PushBack(CKA_PUBLIC_EXPONENT); auto n = MakeUnique>(&mAllocator); + if (!n) { + return {{}, ErrorEnum::eNoMemory}; + } + auto e = MakeUnique>(&mAllocator); + if (!e) { + return {{}, ErrorEnum::eNoMemory}; + } attrValues.PushBack(*n); attrValues.PushBack(*e); @@ -1341,8 +1355,15 @@ RetWithError Utils::ExportPrivateKey( return {{}, err}; } - auto pubKey = MakeUnique(&mAllocator, attrValues[0], attrValues[1]); + auto pubKey = MakeUnique(&mAllocator, attrValues[0], attrValues[1]); + if (!pubKey) { + return {{}, ErrorEnum::eNoMemory}; + } + auto cryptoKey = MakeShared(&mAllocator, mSession, privKeyHandle, *pubKey); + if (!cryptoKey) { + return {{}, ErrorEnum::eNoMemory}; + } PrivateKey pkcsKey = {privKeyHandle, pubKeyHandle, cryptoKey}; @@ -1357,7 +1378,14 @@ RetWithError Utils::ExportPrivateKey( attrTypes.PushBack(CKA_EC_POINT); auto derEncodedParams = MakeUnique>(&mAllocator); - auto derEncodedPoint = MakeUnique>(&mAllocator); + if (!derEncodedParams) { + return {{}, ErrorEnum::eNoMemory}; + } + + auto derEncodedPoint = MakeUnique>(&mAllocator); + if (!derEncodedPoint) { + return {{}, ErrorEnum::eNoMemory}; + } attrValues.PushBack(*derEncodedParams); attrValues.PushBack(*derEncodedPoint); @@ -1368,7 +1396,14 @@ RetWithError Utils::ExportPrivateKey( } auto params = MakeUnique>(&mAllocator); - auto point = MakeUnique>(&mAllocator); + if (!params) { + return {{}, ErrorEnum::eNoMemory}; + } + + auto point = MakeUnique>(&mAllocator); + if (!point) { + return {{}, ErrorEnum::eNoMemory}; + } err = mCryptoProvider.ASN1DecodeOID(attrValues[0], *params); if (!err.IsNone()) { @@ -1381,8 +1416,15 @@ RetWithError Utils::ExportPrivateKey( } auto pubKey = MakeUnique(&mAllocator, *params, *point); + if (!pubKey) { + return {{}, ErrorEnum::eNoMemory}; + } + auto cryptoKey = MakeShared(&mAllocator, mSession, mCryptoProvider, privKeyHandle, *pubKey); + if (!cryptoKey) { + return {{}, ErrorEnum::eNoMemory}; + } PrivateKey pkcsKey = {privKeyHandle, pubKeyHandle, cryptoKey}; @@ -1483,6 +1525,10 @@ RetWithError> Utils::FindCertificateByKeyID RetWithError> Utils::GetCertificate(ObjectHandle handle) { auto certificate = MakeShared(&mAllocator); + if (!certificate) { + return {nullptr, ErrorEnum::eNoMemory}; + } + StaticArray, cObjectAttributesCount> attrValues; StaticArray attrTypes; diff --git a/src/core/common/pkcs11/privatekey.cpp b/src/core/common/pkcs11/privatekey.cpp index 863ae10fb..4cbb61a0e 100644 --- a/src/core/common/pkcs11/privatekey.cpp +++ b/src/core/common/pkcs11/privatekey.cpp @@ -39,6 +39,9 @@ Error PKCS11RSAPrivateKey::Sign( const Array& digest, const crypto::SignOptions& options, Array& signature) const { auto t = MakeUnique>(&mAllocator); + if (!t) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } t->Append(GetPrefix(options.mHash)); t->Append(digest); diff --git a/src/core/common/spaceallocator/spaceallocator.hpp b/src/core/common/spaceallocator/spaceallocator.hpp index f64f00e6a..982cbfd9f 100644 --- a/src/core/common/spaceallocator/spaceallocator.hpp +++ b/src/core/common/spaceallocator/spaceallocator.hpp @@ -461,7 +461,15 @@ class SpaceAllocator : public SpaceAllocatorItf, public SpaceAllocatorStorage { return {nullptr, err}; } - return UniquePtr(MakeUnique(&mAllocator, size, this)); + auto space = MakeUnique(&mAllocator, size, this); + if (!space) { + mPartition->Free(size); + Free(size); + + return {nullptr, ErrorEnum::eNoMemory}; + } + + return UniquePtr(Move(space)); }; /** diff --git a/src/core/common/tests/stubs/spaceallocatorstub.hpp b/src/core/common/tests/stubs/spaceallocatorstub.hpp index b40a35a66..0ff70fd19 100644 --- a/src/core/common/tests/stubs/spaceallocatorstub.hpp +++ b/src/core/common/tests/stubs/spaceallocatorstub.hpp @@ -78,7 +78,12 @@ class SpaceAllocatorStub : public SpaceAllocatorItf { */ RetWithError> AllocateSpace(size_t size) override { - return {UniquePtr(MakeUnique(&mAllocator, size))}; + auto space = MakeUnique(&mAllocator, size); + if (!space) { + return {nullptr, ErrorEnum::eNoMemory}; + } + + return UniquePtr(Move(space)); } /** diff --git a/src/core/common/tools/fs.cpp b/src/core/common/tools/fs.cpp index d957625f1..7e0b00a29 100644 --- a/src/core/common/tools/fs.cpp +++ b/src/core/common/tools/fs.cpp @@ -525,8 +525,12 @@ RetWithError CalculateSize(const String& path) return {static_cast(st.st_size)}; } - size_t size = 0; - auto dirIterators = MakeUnique(&sCalculateSizeAllocator); + size_t size = 0; + + auto dirIterators = MakeUnique(&sCalculateSizeAllocator); + if (!dirIterators) { + return {0, AOS_ERROR_WRAP(ErrorEnum::eNoMemory)}; + } if (auto err = dirIterators->EmplaceBack(path); !err.IsNone()) { return {0, AOS_ERROR_WRAP(err)}; diff --git a/src/core/common/tools/memory.hpp b/src/core/common/tools/memory.hpp index 6323231a7..8289da43b 100644 --- a/src/core/common/tools/memory.hpp +++ b/src/core/common/tools/memory.hpp @@ -521,7 +521,7 @@ class SharedPtr : public SmartPtr { * @tparam Args holding object constructor parameters types. * @param allocator allocator. * @param args holding object constructor parameters. - * @return UniquePtr constructed unique ptr. + * @return UniquePtr constructed unique ptr, empty if allocation failed. */ template inline UniquePtr MakeUnique(Allocator* allocator, Args&&... args) @@ -558,7 +558,7 @@ inline UniquePtr DeferRelease(T* ptr, Deleter&& deleter) * @tparam Args holding object constructor parameters types. * @param allocator allocator. * @param args holding object constructor parameters. - * @return SharedPtr constructed shared ptr. + * @return SharedPtr constructed shared ptr, empty if allocation failed. */ template inline SharedPtr MakeShared(Allocator* allocator, Args&&... args) diff --git a/src/core/iam/certhandler/certhandler.cpp b/src/core/iam/certhandler/certhandler.cpp index 88f8c57ef..5a0c6044f 100644 --- a/src/core/iam/certhandler/certhandler.cpp +++ b/src/core/iam/certhandler/certhandler.cpp @@ -166,6 +166,9 @@ Error CertHandler::SubscribeListener(const String& certType, iamclient::CertList } auto certInfo = MakeUnique(&mAllocator); + if (!certInfo) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } auto err = module->GetCertificate(Array(), Array(), *certInfo); if (!err.IsNone()) { @@ -244,6 +247,9 @@ CertModule* CertHandler::FindModule(const String& certType) const Error CertHandler::UpdateCerts(CertModule& certModule) { auto certInfo = MakeUnique(&mAllocator); + if (!certInfo) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } auto err = certModule.GetCertificate(Array(), Array(), *certInfo); if (!err.IsNone()) { diff --git a/src/core/iam/certhandler/certmodule.cpp b/src/core/iam/certhandler/certmodule.cpp index dd6c8e049..c85cdf3fc 100644 --- a/src/core/iam/certhandler/certmodule.cpp +++ b/src/core/iam/certhandler/certmodule.cpp @@ -36,6 +36,9 @@ Error CertModule::Init(const String& certType, const ModuleConfig& config, crypt } auto validCerts = MakeUnique(&mAllocator); + if (!validCerts) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mHSM->ValidateCertificates(mInvalidCerts, mInvalidKeys, *validCerts); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -47,6 +50,9 @@ Error CertModule::Init(const String& certType, const ModuleConfig& config, crypt Error CertModule::GetCertificate(const Array& issuer, const Array& serial, CertInfo& resCert) { auto certsInStorage = MakeUnique(&mAllocator); + if (!certsInStorage) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (serial.IsEmpty()) { auto err = mStorage->GetCertsInfo(GetCertType(), *certsInStorage); @@ -58,7 +64,7 @@ Error CertModule::GetCertificate(const Array& issuer, const Array(&mAllocator); + resCert = CertInfo(); for (const auto& item : *certsInStorage) { if (resCert.mNotAfter.IsZero() || resCert.mNotAfter < item.mNotAfter) { @@ -121,7 +127,11 @@ RetWithError> CertModule::CreateKey(const Strin Error CertModule::CreateCSR(const String& subjectCommonName, const crypto::PrivateKeyItf& privKey, String& pemCSR) { - auto templ = MakeUnique(&mAllocator); + auto templ = MakeUnique(&mAllocator); + if (!templ) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + StaticString subject; templ->mDNSNames = mModuleConfig.mAlternativeNames; @@ -182,6 +192,9 @@ Error CertModule::CreateCSR(const String& subjectCommonName, const crypto::Priva Error CertModule::ApplyCert(const String& pemCert, CertInfo& info) { auto certificates = MakeUnique(&mAllocator); + if (!certificates) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } auto err = mX509Provider->PEMToX509Certs(pemCert, *certificates); if (!err.IsNone()) { @@ -221,7 +234,11 @@ Error CertModule::CreateSelfSignedCert(const String& password) } const uint64_t serial = Time::Now().UnixNano(); - auto templ = MakeUnique(&mAllocator); + + auto templ = MakeUnique(&mAllocator); + if (!templ) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } templ->mSerial = Array(reinterpret_cast(&serial), sizeof(serial)); templ->mNotBefore = Time::Now(); @@ -238,6 +255,9 @@ Error CertModule::CreateSelfSignedCert(const String& password) } auto pemCert = MakeUnique(&mAllocator); + if (!pemCert) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } err = mX509Provider->CreateCertificate(*templ, *templ, *key.mValue, *pemCert); if (!err.IsNone()) { @@ -245,6 +265,9 @@ Error CertModule::CreateSelfSignedCert(const String& password) } auto certInfo = MakeUnique(&mAllocator); + if (!certInfo) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } return ApplyCert(*pemCert, *certInfo); } @@ -313,6 +336,9 @@ Error CertModule::RemoveInvalidKeys(const String& password) Error CertModule::TrimCerts(const String& password) { auto certsInStorage = MakeUnique(&mAllocator); + if (!certsInStorage) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } auto err = mStorage->GetCertsInfo(GetCertType(), *certsInStorage); if (!err.IsNone() && err != ErrorEnum::eNotFound) { @@ -405,6 +431,9 @@ Error CertModule::CheckCertChain(const Array& chain) Error CertModule::SyncValidCerts(const Array& validCerts) { auto certsInStorage = MakeUnique(&mAllocator); + if (!certsInStorage) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } auto err = mStorage->GetCertsInfo(GetCertType(), *certsInStorage); if (!err.IsNone() && err != ErrorEnum::eNotFound) { diff --git a/src/core/iam/certhandler/certmodules/pkcs11/pkcs11.cpp b/src/core/iam/certhandler/certmodules/pkcs11/pkcs11.cpp index e5508e9ee..238b74140 100644 --- a/src/core/iam/certhandler/certmodules/pkcs11/pkcs11.cpp +++ b/src/core/iam/certhandler/certmodules/pkcs11/pkcs11.cpp @@ -166,7 +166,14 @@ Error PKCS11Module::Clear() // certs, privKeys, pubKeys auto objects = MakeUnique>(&mTmpObjAllocator); - auto filter = MakeUnique(&mTmpObjAllocator); + if (!objects) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + + auto filter = MakeUnique(&mTmpObjAllocator); + if (!filter) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } err = FindObject(*session, *filter, *objects); if (err.IsNone()) { @@ -485,6 +492,9 @@ RetWithError PKCS11Module::GetSlotID() if ((slotInfo.mFlags & CKF_TOKEN_PRESENT) != 0) { auto tokenInfo = MakeUnique(&mTmpObjAllocator); + if (!tokenInfo) { + return {0, AOS_ERROR_WRAP(ErrorEnum::eNoMemory)}; + } err = mPKCS11->GetTokenInfo(slotID, *tokenInfo); if (!err.IsNone()) { @@ -513,6 +523,9 @@ RetWithError PKCS11Module::GetSlotID() RetWithError PKCS11Module::IsOwned() const { auto tokenInfo = MakeUnique(&mTmpObjAllocator); + if (!tokenInfo) { + return {false, AOS_ERROR_WRAP(ErrorEnum::eNoMemory)}; + } auto err = mPKCS11->GetTokenInfo(mSlotID, *tokenInfo); if (!err.IsNone()) { @@ -633,6 +646,9 @@ RetWithError> PKCS11Module::CreateSession(bool LOG_DBG() << "Create session: session=" << mSession->GetHandle() << ", slotID=" << mSlotID; auto sessionInfo = MakeShared(&mTmpObjAllocator); + if (!sessionInfo) { + return {nullptr, AOS_ERROR_WRAP(ErrorEnum::eNoMemory)}; + } err = mSession->GetSessionInfo(*sessionInfo); if (!err.IsNone()) { @@ -819,7 +835,14 @@ Error PKCS11Module::CreateURL(const String& label, const Array& id, Str }; auto opaque = MakeUnique>(&mTmpObjAllocator); - auto query = MakeUnique>(&mTmpObjAllocator); + if (!opaque) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + + auto query = MakeUnique>(&mTmpObjAllocator); + if (!query) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } // create opaque part of url AddParam("token", mTokenLabel.CStr(), true, *opaque); @@ -894,8 +917,15 @@ Error PKCS11Module::GetValidInfo(const pkcs11::SessionContext& session, Array(&mAllocator); + ASSERT_TRUE(mCertHandler); RegisterPKCS11Module("iam"); // Check Storage is restored. @@ -547,6 +549,7 @@ TEST_F(CerthandlerTest, RemoveInvalidPKCS11Objects) // reinit certhandler to sync certificates/keys with PKCS11 storage mCertHandler = MakeShared(&mAllocator); + ASSERT_TRUE(mCertHandler); RegisterPKCS11Module("iam"); // create key, because certmodule updates PKCS11 storage after that only @@ -583,6 +586,7 @@ TEST_F(CerthandlerTest, RenewCertificate) // reinit certhandler to sync certificates/keys with PKCS11 storage mCertHandler = MakeShared(&mAllocator); + ASSERT_TRUE(mCertHandler); RegisterPKCS11Module("iam"); RegisterPKCS11Module("sm"); diff --git a/src/core/iam/nodemanager/nodemanager.cpp b/src/core/iam/nodemanager/nodemanager.cpp index b5a52a47f..62fccf5f4 100644 --- a/src/core/iam/nodemanager/nodemanager.cpp +++ b/src/core/iam/nodemanager/nodemanager.cpp @@ -24,6 +24,9 @@ Error NodeManager::Init(StorageItf& storage) mStorage = &storage; auto nodeIDs = MakeUnique, cMaxNumNodes>>(&mAllocator); + if (!nodeIDs) { + return ErrorEnum::eNoMemory; + } auto err = storage.GetAllNodeIDs(*nodeIDs); if (!err.IsNone()) { @@ -32,6 +35,9 @@ Error NodeManager::Init(StorageItf& storage) for (const auto& nodeID : *nodeIDs) { auto nodeInfo = MakeUnique(&mAllocator); + if (!nodeInfo) { + return ErrorEnum::eNoMemory; + } err = storage.GetNodeInfo(nodeID, *nodeInfo); if (!err.IsNone()) { @@ -77,6 +83,9 @@ Error NodeManager::SetNodeState(const String& nodeID, const NodeState& state) } auto nodeInfo = MakeUnique(&mAllocator); + if (!nodeInfo) { + return ErrorEnum::eNoMemory; + } *nodeInfo = *cachedInfo; nodeInfo->mState = state; @@ -104,6 +113,9 @@ Error NodeManager::SetNodeConnected(const String& nodeID, bool isConnected) } auto nodeInfo = MakeUnique(&mAllocator); + if (!nodeInfo) { + return ErrorEnum::eNoMemory; + } *nodeInfo = *cachedInfo; nodeInfo->mIsConnected = isConnected; @@ -216,8 +228,12 @@ Error NodeManager::UpdateCache(const NodeInfo& nodeInfo) Error NodeManager::UpdateStorage(const NodeInfo& info) { - auto storageInfo = MakeUnique(&mAllocator); - const auto* cachedInfo = GetNodeFromCache(info.mNodeID); + auto storageInfo = MakeUnique(&mAllocator); + if (!storageInfo) { + return ErrorEnum::eNoMemory; + } + + const auto* cachedInfo = GetNodeFromCache(info.mNodeID); *storageInfo = info; diff --git a/src/core/sm/launcher/launcher.cpp b/src/core/sm/launcher/launcher.cpp index d2c4fef42..af97278c6 100644 --- a/src/core/sm/launcher/launcher.cpp +++ b/src/core/sm/launcher/launcher.cpp @@ -74,6 +74,9 @@ Error Launcher::Start() } auto storedInstances = MakeUnique(&mAllocator); + if (!storedInstances) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mStorage->GetAllInstancesInfos(*storedInstances); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -159,8 +162,15 @@ Error Launcher::UpdateInstances(const Array& stopInstances, const // Wait in case previous request is not yet finished mThread.Join(); - auto stop = MakeShared>(&mAllocator, stopInstances); + auto stop = MakeShared>(&mAllocator, stopInstances); + if (!stop) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + auto start = MakeShared(&mAllocator, startInstances); + if (!start) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mThread.Run([this, stop, start](void*) { UpdateInstancesImpl(*stop, *start); @@ -540,6 +550,11 @@ void Launcher::SendNodeInstancesStatuses() LOG_INF() << "Send node instances statuses" << Log::Field("count", mInstances.Size()); auto statuses = MakeUnique(&mAllocator); + if (!statuses) { + LOG_ERR() << "Failed to allocate instance statuses" << Log::Field(ErrorEnum::eNoMemory); + + return; + } for (const auto& instance : mInstances) { LOG_INF() << "Node instance status" << Log::Field("instance", instance.mInfo) @@ -578,6 +593,9 @@ Error Launcher::HandleComponentStatus(const aos::InstanceStatus& status) } auto instanceInfo = MakeUnique(&mAllocator); + if (!instanceInfo) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } static_cast(*instanceInfo) = status; instanceInfo->mRuntimeID = status.mRuntimeID; @@ -594,8 +612,15 @@ Error Launcher::HandleComponentStatus(const aos::InstanceStatus& status) Error Launcher::LoadInstanceData(InstanceData& instanceData) { - auto itemConfig = MakeUnique(&mAllocator); + auto itemConfig = MakeUnique(&mAllocator); + if (!itemConfig) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + auto imageConfig = MakeUnique(&mAllocator); + if (!imageConfig) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = GetInstanceConfigs(instanceData.mInfo, *itemConfig, *imageConfig); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -674,6 +699,11 @@ void Launcher::UpdateInstancesImpl(Array& stopInstances, const Ar } auto removeItems = MakeUnique>(&mAllocator); + if (!removeItems) { + LOG_ERR() << "Failed to allocate remove update items" << Log::Field(ErrorEnum::eNoMemory); + + return; + } if (!mFirstStart) { GetRemoveUpdateItems(stopInstances, startInstances, *removeItems); @@ -838,8 +868,15 @@ Error Launcher::PrepareInstance(InstanceData& instanceData) return ErrorEnum::eNone; } - auto itemConfig = MakeUnique(&mAllocator); + auto itemConfig = MakeUnique(&mAllocator); + if (!itemConfig) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } + auto imageConfig = MakeUnique(&mAllocator); + if (!imageConfig) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = GetInstanceConfigs(instanceData.mInfo, *itemConfig, *imageConfig); !err.IsNone()) { return err; @@ -1282,7 +1319,18 @@ void Launcher::RemoveUpdateItems(const Array& removeItems) void Launcher::InstallUpdateItems(const Array& startInstances) { auto currentItems = MakeUnique>(&mAllocator); + if (!currentItems) { + LOG_ERR() << "Failed to allocate current items" << Log::Field(ErrorEnum::eNoMemory); + + return; + } + auto installItems = MakeUnique>(&mAllocator); + if (!installItems) { + LOG_ERR() << "Failed to allocate install items" << Log::Field(ErrorEnum::eNoMemory); + + return; + } if (auto err = mImageManager->GetAllInstalledItems(*currentItems); !err.IsNone()) { LOG_ERR() << "Get update items statuses failed" << Log::Field(AOS_ERROR_WRAP(err)); @@ -1427,12 +1475,18 @@ Error Launcher::GetInstanceConfigs( LOG_DBG() << "Get instance configs" << Log::Field("instance", instance); auto path = MakeUnique>(&mAllocator); + if (!path) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mItemInfoProvider->GetBlobPath(instance.mManifestDigest, *path); !err.IsNone()) { return AOS_ERROR_WRAP(err); } auto manifest = MakeUnique(&mAllocator); + if (!manifest) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mOCISpec->LoadImageManifest(*path, *manifest); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -1467,6 +1521,9 @@ Error Launcher::GetInstanceNetworkConfig(const InstanceInfo& instance, const oci networkConfig.mInstanceIdent = static_cast(instance); auto resourceInfo = MakeUnique(&mAllocator); + if (!resourceInfo) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } for (const auto& resource : itemConfig.mResources) { @@ -1516,6 +1573,9 @@ Error Launcher::CreateNetwork( const InstanceData& instanceData, const oci::ItemConfig& itemConfig, const oci::ImageConfig& imageConfig) { auto networkConfig = MakeUnique(&mAllocator); + if (!networkConfig) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = GetInstanceNetworkConfig(instanceData.mInfo, itemConfig, imageConfig, *networkConfig); !err.IsNone()) { diff --git a/src/core/sm/networkmanager/networkmanager.cpp b/src/core/sm/networkmanager/networkmanager.cpp index b4242480a..41f77c981 100644 --- a/src/core/sm/networkmanager/networkmanager.cpp +++ b/src/core/sm/networkmanager/networkmanager.cpp @@ -37,6 +37,9 @@ Error NetworkManager::Init(StorageItf& storage, BridgeNetworkItf& bridgeNet, Fir auto instanceNetworkInfos = MakeUnique>(&mInstanceNetworkInfosAllocator); + if (!instanceNetworkInfos) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mStorage->GetInstanceNetworksInfo(*instanceNetworkInfos); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -47,6 +50,9 @@ Error NetworkManager::Init(StorageItf& storage, BridgeNetworkItf& bridgeNet, Fir } auto networkInfos = MakeUnique>(&mNetworkInfosAllocator); + if (!networkInfos) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mStorage->GetNetworksInfo(*networkInfos); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -204,12 +210,22 @@ Error NetworkManager::CreateInstanceNetwork( } auto serviceData = MakeUnique(&mAllocator); + if (!serviceData) { + err = AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + + return err; + } if (err = PrepareUpdateItemNetworkParams(instanceNetworkParameters, networkID, *serviceData); !err.IsNone()) { return err; } auto allocatedParams = MakeUnique(&mAllocator); + if (!allocatedParams) { + err = AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + + return err; + } if (err = mNetworkProvider->AllocateInstanceNetwork( instanceNetworkParameters.mInstanceIdent, networkID, mNodeID, *serviceData, *allocatedParams); @@ -229,6 +245,11 @@ Error NetworkManager::CreateInstanceNetwork( auto info = MakeUnique( &mAllocator, instanceID, networkID, instanceNetworkParameters, *allocatedParams); + if (!info) { + err = AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + + return err; + } if (err = mStorage->AddInstanceNetworkInfo(*info); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -248,6 +269,9 @@ Error NetworkManager::StartInstanceNetwork(const String& instanceID, const Strin LOG_DBG() << "Start instance network" << Log::Field("instanceID", instanceID) << Log::Field("networkID", networkID); auto cachedInfo = MakeUnique(&mAllocator); + if (!cachedInfo) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } { LockGuard lock {mMutex}; @@ -303,7 +327,10 @@ Error NetworkManager::GetResolvServers(const String& instanceID, Array networkID; StaticString bridgeIP; - auto dns = MakeUnique, cMaxNumDNSServers>>(&mResolvHostsAllocator); + auto dns = MakeUnique, cMaxNumDNSServers>>(&mResolvHostsAllocator); + if (!dns) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } { LockGuard lock {mMutex}; @@ -350,7 +377,10 @@ Error NetworkManager::GetHosts(const String& instanceID, Array& hosts) con StaticString networkID; StaticString instanceIP; StaticString hostname; - auto customHosts = MakeUnique>(&mResolvHostsAllocator); + auto customHosts = MakeUnique>(&mResolvHostsAllocator); + if (!customHosts) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } { LockGuard lock {mMutex}; @@ -863,6 +893,11 @@ Error NetworkManager::AddInstanceToNetwork(const String& instanceID, const Strin }); auto hosts = MakeUnique, cMaxNumHosts>>(&mAllocator); + if (!hosts) { + err = AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + + return err; + } if (err = PrepareHosts(instanceID, networkID, networkConfig, *hosts); !err.IsNone()) { return err; @@ -876,6 +911,11 @@ Error NetworkManager::AddInstanceToNetwork(const String& instanceID, const Strin } auto bridgeParams = MakeUnique(&mAllocator); + if (!bridgeParams) { + err = AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + + return err; + } if (err = PrepareBridgeParams(networkID, networkParams, *bridgeParams); !err.IsNone()) { return err; @@ -898,6 +938,11 @@ Error NetworkManager::AddInstanceToNetwork(const String& instanceID, const Strin }); auto firewallParams = MakeUnique(&mAllocator); + if (!firewallParams) { + err = AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + + return err; + } if (err = PrepareInstanceFirewallParams(networkConfig, networkParams, *firewallParams); !err.IsNone()) { return err; @@ -917,6 +962,11 @@ Error NetworkManager::AddInstanceToNetwork(const String& instanceID, const Strin }); auto bandwidthParams = MakeUnique(&mAllocator); + if (!bandwidthParams) { + err = AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + + return err; + } if (err = PrepareBandwidthParams(networkConfig, *bandwidthParams); !err.IsNone()) { return err; @@ -953,6 +1003,11 @@ Error NetworkManager::AddInstanceToNetwork(const String& instanceID, const Strin } auto dnsParams = MakeUnique(&mAllocator); + if (!dnsParams) { + err = AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + + return err; + } if (err = PrepareDNSAliasesParams(networkParams, *hosts, *dnsParams); !err.IsNone()) { return err; @@ -994,6 +1049,11 @@ Error NetworkManager::AddInstanceToNetwork(const String& instanceID, const Strin } auto info = MakeUnique(&mAllocator); + if (!info) { + err = AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + + return err; + } { LockGuard lock {mMutex}; @@ -1112,7 +1172,16 @@ Error NetworkManager::DeleteInstanceNetworkConfig(const String& instanceID, cons } if (err.IsNone() && !hostIfName.IsEmpty()) { - auto info = MakeUnique(&mAllocator); + auto info = MakeUnique(&mAllocator); + if (!info) { + LOG_ERR() << "Failed to allocate instance network info" << Log::Field("instanceID", instanceID) + << Log::Field(ErrorEnum::eNoMemory); + + err = AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + + return err; + } + bool needPersist = false; { @@ -1295,6 +1364,9 @@ Error NetworkManager::ReconcileInstances() }; auto entries = MakeUnique>(&mAllocator); + if (!entries) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } { LockGuard lock {mMutex}; @@ -1388,6 +1460,9 @@ Error NetworkManager::RemoveFirewallOrphans() Error NetworkManager::RemoveDNSOrphans() { auto known = MakeUnique, cMaxNumOwners>>(&mAllocator); + if (!known) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } { LockGuard lock {mMutex}; @@ -1889,8 +1964,19 @@ void NetworkManager::OnPendingFirewallUpdate( StaticString networkID; bool isRunning = false; - auto networkConfig = MakeUnique(&mAllocator); + auto networkConfig = MakeUnique(&mAllocator); + if (!networkConfig) { + LOG_ERR() << "Failed to allocate network config" << Log::Field(ErrorEnum::eNoMemory); + + return; + } + auto allocatedParams = MakeUnique(&mAllocator); + if (!allocatedParams) { + LOG_ERR() << "Failed to allocate network allocation params" << Log::Field(ErrorEnum::eNoMemory); + + return; + } StaticString hostIfName; @@ -1925,6 +2011,12 @@ void NetworkManager::OnPendingFirewallUpdate( auto info = MakeUnique( &mInstanceNetworkInfosAllocator, instanceID, networkID, *networkConfig, *allocatedParams, hostIfName); + if (!info) { + LOG_ERR() << "Failed to allocate instance network info" << Log::Field("instanceID", instanceID) + << Log::Field(ErrorEnum::eNoMemory); + + return; + } if (auto err = mStorage->UpdateInstanceNetworkInfo(*info); !err.IsNone()) { LOG_ERR() << "Failed to update instance network info" << Log::Field("instanceID", instanceID) @@ -1951,6 +2043,11 @@ void NetworkManager::OnConnect() LOG_DBG() << "SM connected to CM, synchronizing network state"; auto instances = MakeUnique>(&mAllocator); + if (!instances) { + LOG_ERR() << "Failed to allocate instances sync state" << Log::Field(ErrorEnum::eNoMemory); + + return; + } { LockGuard lock {mMutex}; @@ -1984,6 +2081,9 @@ Error NetworkManager::UpdateInstanceFirewall(const String& instanceID, const Str << Log::Field("networkID", networkID); auto firewallParams = MakeUnique(&mAllocator); + if (!firewallParams) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = PrepareInstanceFirewallParams(networkConfig, networkParams, *firewallParams); !err.IsNone()) { return err; diff --git a/src/core/sm/nodeconfig/nodeconfig.cpp b/src/core/sm/nodeconfig/nodeconfig.cpp index 3ad412b29..7ce950bae 100644 --- a/src/core/sm/nodeconfig/nodeconfig.cpp +++ b/src/core/sm/nodeconfig/nodeconfig.cpp @@ -67,6 +67,9 @@ Error NodeConfig::UpdateNodeConfig(const aos::NodeConfig& config) mNodeConfig = config; auto nodeConfigJSON = MakeUnique>(&mAllocator); + if (!nodeConfigJSON) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } if (auto err = mJSONProvider->NodeConfigToJSON(config, *nodeConfigJSON); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -146,6 +149,9 @@ Error NodeConfig::LoadConfig() LOG_DBG() << "Load config"; auto nodeConfigJSON = MakeUnique>(&mAllocator); + if (!nodeConfigJSON) { + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); + } auto err = fs::ReadFileToString(mNodeConfigFile, *nodeConfigJSON); if (!err.IsNone()) { From afda74d135a15f1c42721a4f8a004306c686a93b Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 30 Jul 2026 20:26:30 +0300 Subject: [PATCH 03/13] tools: replace static allocator with AllocatorItf/HeapAllocator Rework the memory allocation abstraction in memory.hpp: - Rename Allocator to AllocatorItf, keeping only Allocate/Free and a virtual destructor. This decouples callers from any particular allocation strategy. - Remove StaticAllocator, BufferAllocator and the custom placement new/delete operator overloads (allocator.hpp is deleted). Sizing a static arena correctly, especially for multithreaded usage, was error prone and required extra bookkeeping. - Add HeapAllocator (malloc/free backed) for Linux and test usage. Safety-critical targets can provide their own AllocatorItf implementation. - Rework SharedPtr to use intrusive control blocks (SharedControlBlock/SharedObjectControlBlock/SharedAdoptControlBlock) instead of allocator-external ref-counting, so it works uniformly over any AllocatorItf implementation. - MakeUnique/MakeShared now check the allocation result before constructing the object, returning a null pointer on failure instead of relying on assert(), which is stripped in release builds. Signed-off-by: Oleksandr Grytsov --- src/core/common/tools/CMakeLists.txt | 2 +- src/core/common/tools/allocator.hpp | 356 --------------- src/core/common/tools/heapallocator.hpp | 43 ++ src/core/common/tools/memory.hpp | 502 ++++++++++++++-------- src/core/common/tools/tests/allocator.cpp | 94 ++-- src/core/common/tools/tests/memory.cpp | 105 ++--- 6 files changed, 436 insertions(+), 666 deletions(-) delete mode 100644 src/core/common/tools/allocator.hpp create mode 100644 src/core/common/tools/heapallocator.hpp diff --git a/src/core/common/tools/CMakeLists.txt b/src/core/common/tools/CMakeLists.txt index a62b5212f..c9f65fd3b 100644 --- a/src/core/common/tools/CMakeLists.txt +++ b/src/core/common/tools/CMakeLists.txt @@ -22,7 +22,6 @@ set(SOURCES fs.cpp semver.cpp time.cpp timer.cpp uuid.cpp) set(HEADERS algorithm.hpp - allocator.hpp array.hpp buffer.hpp config.hpp @@ -30,6 +29,7 @@ set(HEADERS error.hpp fs.hpp function.hpp + heapallocator.hpp identifierpool.hpp list.hpp log.hpp diff --git a/src/core/common/tools/allocator.hpp b/src/core/common/tools/allocator.hpp deleted file mode 100644 index 5e63d1660..000000000 --- a/src/core/common/tools/allocator.hpp +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef AOS_CORE_COMMON_TOOLS_ALLOCATOR_HPP_ -#define AOS_CORE_COMMON_TOOLS_ALLOCATOR_HPP_ - -#include -#include - -#include "buffer.hpp" -#include "list.hpp" -#include "noncopyable.hpp" -#include "thread.hpp" - -namespace aos { - -/** - * Allocator instance. - */ -class Allocator { -public: - /** - * Allocation instance. - */ - class Allocation { - public: - /** - * Creates allocation. - */ - Allocation() = default; - - /** - * Creates allocation. - * - * @param data pointer to allocated data. - * @param size allocated size. - */ - Allocation(uint8_t* data, size_t size) - : mData(data) - , mSize(size) - , mSharedCount(0) - { - } - - /** - * Returns pointer to allocated data. - * - * @return uint8_t* pointer to allocated data. - */ - uint8_t* Data() const { return mData; } - - /** - * Returns allocated size. - * - * @return size_t allocated size. - */ - size_t Size() const { return mSize; } - - /** - * Increases shared count. - * - * @param mutex mutex to lock context. - * @return size_t chared count value; - */ - size_t Take(Mutex& mutex) - { - LockGuard lock(mutex); - - return ++mSharedCount; - } - - /** - * Decreases shared count. - * - * @param mutex mutex to lock context. - * @return size_t chared count value; - */ - size_t Give(Mutex& mutex) - { - LockGuard lock(mutex); - - return --mSharedCount; - } - - private: - uint8_t* mData = nullptr; - size_t mSize = 0; - size_t mSharedCount = 0; - }; - - /** - * Clears allocator. - */ - void Clear() - { - LockGuard lock {mMutex}; - - mAllocations->Clear(); - } - - /** - * Allocates data with specified size. - * - * @param size allocate size. - * @return void* pointer to allocated data. - */ - void* Allocate(size_t size) - { - LockGuard lock {mMutex}; - - if (mAllocations->IsFull() || GetAllocatedSize() + size > mMaxSize) { - assert(!mAllocations->IsFull()); - assert(GetAllocatedSize() + size <= mMaxSize); - - return nullptr; - } - - auto* pos = mBuffer; - auto it = mAllocations->begin(); - - for (; it != mAllocations->end(); ++it) { - size_t availableSize = it->Data() - pos; - - if (availableSize >= size) { - return Allocate(it, pos, size); - } - - pos = it->Data() + it->Size(); - } - - if (pos + size <= mBuffer + mMaxSize) { - return Allocate(mAllocations->end(), pos, size); - } - - assert(false); - - return nullptr; - } - - /** - * Frees previously allocated data. - * - * @param data allocated data to free. - */ - void Free(void* data) - { - LockGuard lock {mMutex}; - - [[maybe_unused]] auto curSize = mAllocations->Size(); - mAllocations->RemoveIf([data](const Allocation& allocation) { return allocation.Data() == data; }); - [[maybe_unused]] auto newSize = mAllocations->Size(); - - assert(curSize != newSize); - } - - /** - * Finds allocation by data. - * - * @param data allocated data. - * @return List::Iterator. - */ - RetWithError::Iterator> FindAllocation(const void* data) - { - LockGuard lock {mMutex}; - - return mAllocations->FindIf([data](const Allocation& allocation) { return allocation.Data() == data; }); - } - - /** - * Increases allocation shared count. - * - * @param it allocation to increase shared count. - * @return size_t allocation shared count. - */ - size_t TakeAllocation(List::Iterator it) { return it->Take(mMutex); } - - /** - * Decreases allocation shared count. - * - * @param it allocation to increase shared count. - * @return size_t allocation shared count. - */ - size_t GiveAllocation(List::Iterator it) { return it->Give(mMutex); } - - /** - * Returns allocator free size. - * - * @return size_t free size. - */ - size_t FreeSize() const - { - LockGuard lock {mMutex}; - - return mMaxSize - GetAllocatedSize(); - } - - /** - * Return allocator max size. - * - * @return size_t max size. - */ - size_t MaxSize() const - { - LockGuard lock {mMutex}; - - return mMaxSize; - } - - /** - * Return max allocated size. - * - * @return size_t max allocated size. - */ - size_t MaxAllocatedSize() const - { - LockGuard lock {mMutex}; - - return mMaxAllocatedSize; - } - - /** - * Resets max allocated size. - */ - void ResetMaxAllocatedSize() - { - LockGuard lock {mMutex}; - - mMaxAllocatedSize = 0; - } - -protected: - void SetBuffer(const Buffer& buffer, List& allocations) - { - mBuffer = static_cast(buffer.Get()); - mMaxSize = buffer.Size(); - mAllocations = &allocations; - mAllocations->Clear(); - } - -private: - // cppcheck-suppress passedByValue - void* Allocate(List::ConstIterator it, uint8_t* data, size_t size) - { - [[maybe_unused]] auto err = mAllocations->Emplace(it, Allocation(data, size)); - assert(err.IsNone()); - - if (GetAllocatedSize() > mMaxAllocatedSize) { - mMaxAllocatedSize = GetAllocatedSize(); - } - - return data; - } - - size_t GetAllocatedSize() const - { - size_t allocatedSize = 0; - - for (const auto& allocation : *mAllocations) { - allocatedSize += allocation.Size(); - } - - return allocatedSize; - } - - uint8_t* mBuffer = {}; - List* mAllocations = {}; - size_t mMaxSize = {}; - size_t mMaxAllocatedSize = {}; - mutable Mutex mMutex; -}; - -/** - * Buffer allocator instance. - */ -template -class BufferAllocator : public Allocator { -public: - /** - * Creates buffer allocator instance. - */ - explicit BufferAllocator(const Buffer& buffer) { SetBuffer(buffer, mAllocations); } - -private: - StaticArray mAllocations; -}; - -/** - * Static allocator instance. - */ -template -class StaticAllocator : public Allocator { -public: - /** - * Creates static allocator instance. - */ - StaticAllocator() { SetBuffer(mBuffer, mAllocations); } - -private: - StaticBuffer mBuffer; - StaticList mAllocations; -}; - -} // namespace aos - -/** - * Overloads placement new operator to allocate object on Aos buffer. - * - * @param size allocate size. - * @param allocator allocator. - * @return void* allocated space. - */ -inline void* operator new(size_t size, aos::Allocator* allocator) -{ - assert(allocator); - - auto data = allocator->Allocate(size); - assert(data); - - return data; -} - -/** - * Overloads placement sized new operator to allocate object on Aos buffer. - * - * @param size allocate size. - * @param allocator allocator. - * @return void* allocated space. - */ -inline void* operator new[](size_t size, aos::Allocator* allocator) -{ - assert(allocator); - - auto data = allocator->Allocate(size); - assert(data); - - return data; -} - -/** - * Overloads placement delete operator to release object on Aos buffer. - * - * @param data pointer to allocated data. - * @param allocator allocator. - */ -inline void operator delete(void* data, aos::Allocator* allocator) -{ - assert(allocator); - - allocator->Free(data); -} - -#endif diff --git a/src/core/common/tools/heapallocator.hpp b/src/core/common/tools/heapallocator.hpp new file mode 100644 index 000000000..17e17ebb6 --- /dev/null +++ b/src/core/common/tools/heapallocator.hpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2023 Renesas Electronics Corporation. + * Copyright (C) 2023 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef AOS_CORE_COMMON_TOOLS_HEAPALLOCATOR_HPP_ +#define AOS_CORE_COMMON_TOOLS_HEAPALLOCATOR_HPP_ + +#include + +#include "memory.hpp" + +namespace aos { + +/** + * Heap allocator instance. Backs the AllocatorItf interface with the standard heap + * (malloc/free). Intended for hosted targets (e.g. Linux) where dynamic memory allocation + * is acceptable, and for unit tests; safety critical/embedded targets should provide their + * own custom AllocatorItf implementation. + */ +class HeapAllocator : public AllocatorItf { +public: + /** + * Allocates data with specified size. + * + * @param size allocate size. + * @return void* pointer to allocated data, nullptr if allocation failed. + */ + void* Allocate(size_t size) override { return std::malloc(size); } + + /** + * Frees previously allocated data. + * + * @param data allocated data to free. + */ + void Free(void* data) override { std::free(data); } +}; + +} // namespace aos + +#endif diff --git a/src/core/common/tools/memory.hpp b/src/core/common/tools/memory.hpp index 8289da43b..8b825cd65 100644 --- a/src/core/common/tools/memory.hpp +++ b/src/core/common/tools/memory.hpp @@ -8,12 +8,45 @@ #ifndef AOS_CORE_COMMON_TOOLS_MEMORY_HPP_ #define AOS_CORE_COMMON_TOOLS_MEMORY_HPP_ +#include #include +#include -#include "allocator.hpp" +#include "noncopyable.hpp" +#include "utils.hpp" namespace aos { +/** + * Allocator interface. + * + * Any implementation only has to provide Allocate/Free semantics, so it can be backed by a + * heap (see HeapAllocator) or by any custom allocation strategy required by a specific target + * (e.g. a static/embedded arena for safety critical domains). + */ +class AllocatorItf { +public: + /** + * Allocates data with specified size. + * + * @param size allocate size. + * @return void* pointer to allocated data, nullptr if allocation failed. + */ + virtual void* Allocate(size_t size) = 0; + + /** + * Frees previously allocated data. + * + * @param data allocated data to free. + */ + virtual void Free(void* data) = 0; + + /** + * Destroys allocator instance. + */ + virtual ~AllocatorItf() = default; +}; + /** * Default deleter invokes delete operator for the given pointer. */ @@ -25,7 +58,7 @@ class DefaultDeleter : public NonCopyable { * * @param allocator input allocator. */ - explicit DefaultDeleter(Allocator* allocator = nullptr) + explicit DefaultDeleter(AllocatorItf* allocator = nullptr) : mAllocator(allocator) { } @@ -53,9 +86,9 @@ class DefaultDeleter : public NonCopyable { /** * Returns allocator. * - * @return Allocator*. + * @return AllocatorItf*. */ - Allocator* GetAllocator() const { return mAllocator; } + AllocatorItf* GetAllocator() const { return mAllocator; } /** * Destroys object & deallocates memory. @@ -66,149 +99,29 @@ class DefaultDeleter : public NonCopyable { { if (mAllocator) { ptr->~T(); - operator delete(ptr, mAllocator); + mAllocator->Free(ptr); } } private: - Allocator* mAllocator; + AllocatorItf* mAllocator; }; /** - * Deleter function for shared pointer. + * Deleter function for objects adopted by a shared pointer. */ template -inline void SmartPtrDeleter(void* ptr, Allocator* allocator) +inline void SmartPtrDeleter(void* ptr, AllocatorItf* allocator) { if (ptr) { static_cast(ptr)->~T(); if (allocator) { - operator delete(ptr, allocator); + allocator->Free(ptr); } } } -/** - * Smart pointer instance. - * - * @tparam T holding object type. - */ -template -class SmartPtr { -public: - /** - * Deleter. - */ - using Deleter = void (*)(void*, Allocator*); - - // cppcheck-suppress noExplicitConstructor - /** - * Creates smart pointer. - * - * @param allocator allocator. - * @param object object to make smart pointer. - */ - SmartPtr(Allocator* allocator = nullptr, T* object = nullptr, Deleter deleter = SmartPtrDeleter) - : mAllocator(allocator) - , mObject(object) - , mDeleter(deleter) - { - assert(!(object && !allocator && !deleter)); - } - - /** - * Deletes holding object and release smart pointer. - * - * @param allocator new allocator. - * @param object new object. - */ - void Reset(Allocator* allocator = nullptr, T* object = nullptr, Deleter deleter = SmartPtrDeleter) - { - if (mAllocator && mObject && mDeleter) { - mDeleter(const_cast*>(mObject), mAllocator); - } - - assert(!(object && !allocator)); - - Release(allocator, object, deleter); - } - - /** - * Releases smart pointer. - * - * @param allocator new allocator. - * @param object new object. - * @return T* pointer to holding object. - */ - T* Release(Allocator* allocator = nullptr, T* object = nullptr, Deleter deleter = SmartPtrDeleter) - { - auto curObject = mObject; - - mObject = object; - mAllocator = allocator; - mDeleter = deleter; - - return curObject; - } - - /** - * Returns holding object. - * - * @return T* holding object. - */ - T* Get() const { return mObject; } - - /** - * Returns holding allocator. - * - * @return Allocator* holding allocator. - */ - Allocator* GetAllocator() const { return mAllocator; } - - /** - * Returns holding deleter. - * - * @return Deleter. - */ - Deleter GetDeleter() const { return mDeleter; } - - /** - * Checks if pointer holds object. - * - * @return bool. - */ - explicit operator bool() const { return mObject != nullptr; } - - /** - * Compares two smart pointers. - * - * @param ptr1 first smart pointer. - * @param ptr2 second smart pointer. - * @return bool. - */ - friend bool operator==(const SmartPtr& ptr1, const SmartPtr& ptr2) { return ptr1.mObject == ptr2.mObject; } - - /** - * Provides access to holding object fields. - * - * @return T* holding object pointer. - */ - T* operator->() const { return mObject; } - - /** - * Dereferences holding object. - * - * @return T& holding object value. - */ - T& operator*() const { return *(mObject); } - -private: - Allocator* mAllocator {}; - T* mObject {}; - Deleter mDeleter {}; -}; - /** * Unique pointer instance. * @@ -238,7 +151,7 @@ class UniquePtr : private NonCopyable { * @param allocator allocator that object was allocated with. * */ - UniquePtr(T* ptr = nullptr, Allocator* allocator = nullptr) + UniquePtr(T* ptr = nullptr, AllocatorItf* allocator = nullptr) : mObject(ptr) , mDeleter(DefaultDeleter(allocator)) { @@ -389,30 +302,189 @@ class UniquePtr : private NonCopyable { Deleter mDeleter; }; +/** + * Defers object destruction till the end of the current scope. + * + * @tparam T type of the object to be destroyed. + * @tparam Deleter type of the deleter. + * @param ptr pointer to the object to be destroyed. + * @param deleter functor object to be deferred. + * @return UniquePtr. + */ +template +inline UniquePtr DeferRelease(T* ptr, Deleter&& deleter) +{ + return UniquePtr(ptr, Move(deleter)); +} + +/** + * Base class for shared pointer control blocks. + * + * Owns the reference count and knows how to dispose of itself (and whatever it holds) through + * the same AllocatorItf it was created with. This keeps SharedPtr's ref-counting independent + * from any allocator-specific bookkeeping, so it works the same way for any AllocatorItf + * implementation (heap based or static/embedded). + */ +class SharedControlBlock : private NonCopyable { +public: + /** + * Creates control block instance. + * + * @param allocator allocator the control block itself was allocated from. + */ + explicit SharedControlBlock(AllocatorItf& allocator) + : mAllocator(allocator) + { + } + + /** + * Increases shared count. + * + * @return size_t shared count value. + */ + size_t Take() { return ++mRefCount; } + + /** + * Decreases shared count. Disposes the control block once the count reaches zero. + * + * @return size_t shared count value. + */ + size_t Give() + { + auto count = --mRefCount; + + if (count == 0) { + Dispose(); + } + + return count; + } + + /** + * Destroys control block instance. + */ + virtual ~SharedControlBlock() = default; + +protected: + /** + * Allocator the control block itself was allocated from. + */ + AllocatorItf& mAllocator; + +private: + virtual void Dispose() = 0; + + size_t mRefCount = 1; +}; + +/** + * Control block that owns an object of type T directly (single allocation). Used by MakeShared. + * + * @tparam T holding object type. + */ +template +class SharedObjectControlBlock : public SharedControlBlock { +public: + /** + * Creates control block instance constructing the held object in place. + * + * @param allocator allocator the control block is allocated from. + * @param args holding object constructor parameters. + */ + template + explicit SharedObjectControlBlock(AllocatorItf& allocator, Args&&... args) + : SharedControlBlock(allocator) + , mObject(args...) + { + } + + /** + * Returns pointer to the held object. + * + * @return T*. + */ + T* GetObject() { return &mObject; } + +private: + void Dispose() override + { + auto& allocator = mAllocator; + + this->~SharedObjectControlBlock(); + allocator.Free(this); + } + + T mObject; +}; + +/** + * Control block that adopts an already constructed, separately allocated object. + * + * @tparam T holding object type. + */ +template +class SharedAdoptControlBlock : public SharedControlBlock { +public: + /** + * Deleter. + */ + using Deleter = void (*)(void*, AllocatorItf*); + + /** + * Creates control block instance. + * + * @param allocator allocator the control block itself is allocated from. + * @param object object to adopt. + * @param deleter functor destroying the adopted object. + */ + SharedAdoptControlBlock(AllocatorItf& allocator, T* object, Deleter deleter) + : SharedControlBlock(allocator) + , mObject(object) + , mDeleter(deleter) + { + } + +private: + void Dispose() override + { + auto& allocator = mAllocator; + + if (mDeleter) { + mDeleter(mObject, &allocator); + } + + this->~SharedAdoptControlBlock(); + allocator.Free(this); + } + + T* mObject; + Deleter mDeleter; +}; + /** * Shared pointer instance. * * @tparam T holding object type. */ template -class SharedPtr : public SmartPtr { +class SharedPtr { public: /** * Deleter. */ - using typename SmartPtr::Deleter; + using Deleter = void (*)(void*, AllocatorItf*); // cppcheck-suppress noExplicitConstructor /** - * Creates shared pointer. + * Creates shared pointer adopting an already allocated object. + * + * @param allocator allocator object was allocated with. + * @param object object to adopt. + * @param deleter functor destroying the object. */ - SharedPtr(Allocator* allocator = nullptr, T* object = nullptr, Deleter deleter = SmartPtrDeleter) - : SmartPtr(allocator, object, deleter) + SharedPtr(AllocatorItf* allocator = nullptr, T* object = nullptr, Deleter deleter = SmartPtrDeleter) { - if (allocator && object) { - mAllocation = allocator->FindAllocation(object).mValue; - SmartPtr::GetAllocator()->TakeAllocation(mAllocation); - } + Adopt(allocator, object, deleter); } /** @@ -421,11 +493,11 @@ class SharedPtr : public SmartPtr { * @param ptr pointer to create from. */ SharedPtr(const SharedPtr& ptr) - : SmartPtr(ptr.GetAllocator(), ptr.Get(), ptr.GetDeleter()) - , mAllocation(ptr.mAllocation) + : mObject(ptr.mObject) + , mControlBlock(ptr.mControlBlock) { - if (SmartPtr::GetAllocator()) { - SmartPtr::GetAllocator()->TakeAllocation(mAllocation); + if (mControlBlock) { + mControlBlock->Take(); } } @@ -436,11 +508,17 @@ class SharedPtr : public SmartPtr { */ SharedPtr& operator=(const SharedPtr& ptr) { - SmartPtr::Release(ptr.GetAllocator(), ptr.Get(), ptr.GetDeleter()); - mAllocation = ptr.mAllocation; + if (this == &ptr) { + return *this; + } - if (SmartPtr::GetAllocator()) { - SmartPtr::GetAllocator()->TakeAllocation(mAllocation); + Reset(); + + mObject = ptr.mObject; + mControlBlock = ptr.mControlBlock; + + if (mControlBlock) { + mControlBlock->Take(); } return *this; @@ -454,11 +532,11 @@ class SharedPtr : public SmartPtr { template // cppcheck-suppress noExplicitConstructor SharedPtr(const SharedPtr

& ptr) - : SmartPtr(ptr.GetAllocator(), ptr.Get(), ptr.GetDeleter()) - , mAllocation(ptr.mAllocation) + : mObject(ptr.mObject) + , mControlBlock(ptr.mControlBlock) { - if (SmartPtr::GetAllocator()) { - SmartPtr::GetAllocator()->TakeAllocation(mAllocation); + if (mControlBlock) { + mControlBlock->Take(); } } @@ -470,40 +548,76 @@ class SharedPtr : public SmartPtr { template SharedPtr& operator=(const SharedPtr

& ptr) { - SmartPtr::Release(ptr.GetAllocator(), ptr.Get(), ptr.GetDeleter()); - mAllocation = ptr.mAllocation; + Reset(); + + mObject = ptr.mObject; + mControlBlock = ptr.mControlBlock; - if (SmartPtr::GetAllocator()) { - SmartPtr::GetAllocator()->TakeAllocation(mAllocation); + if (mControlBlock) { + mControlBlock->Take(); } return *this; } - // cppcheck-suppress duplInheritedMember /** * Resets shared pointer. * * @param allocator new allocator. * @param object new object. + * @param deleter functor destroying the object. */ - void Reset(Allocator* allocator = nullptr, T* object = nullptr, Deleter deleter = SmartPtrDeleter) + void Reset(AllocatorItf* allocator = nullptr, T* object = nullptr, Deleter deleter = SmartPtrDeleter) { - if (SmartPtr::GetAllocator() && SmartPtr::GetAllocator()->GiveAllocation(mAllocation) == 0) { - SmartPtr::Reset(allocator, object, deleter); + if (mControlBlock) { + mControlBlock->Give(); } - SmartPtr::Release(allocator, object, deleter); - mAllocation = {}; + mObject = nullptr; + mControlBlock = nullptr; - if (allocator && object) { - mAllocation = allocator->FindAllocation(object).mValue; - SmartPtr::GetAllocator()->TakeAllocation(mAllocation); - } + Adopt(allocator, object, deleter); } /** - * Destroys unique pointer. + * Returns holding object. + * + * @return T* holding object. + */ + T* Get() const { return mObject; } + + /** + * Checks if pointer holds object. + * + * @return bool. + */ + explicit operator bool() const { return mObject != nullptr; } + + /** + * Compares two shared pointers. + * + * @param ptr1 first shared pointer. + * @param ptr2 second shared pointer. + * @return bool. + */ + friend bool operator==(const SharedPtr& ptr1, const SharedPtr& ptr2) { return ptr1.mObject == ptr2.mObject; } + + /** + * Provides access to holding object fields. + * + * @return T* holding object pointer. + */ + T* operator->() const { return mObject; } + + /** + * Dereferences holding object. + * + * @return T& holding object value. + */ + T& operator*() const { return *(mObject); } + + /** + * Destroys shared pointer. */ ~SharedPtr() { Reset(); } @@ -511,7 +625,36 @@ class SharedPtr : public SmartPtr { template friend class SharedPtr; - List::Iterator mAllocation; + template + friend SharedPtr MakeShared(AllocatorItf* allocator, Args&&... args); + + SharedPtr(SharedControlBlock* controlBlock, T* object) + : mObject(object) + , mControlBlock(controlBlock) + { + } + + void Adopt(AllocatorItf* allocator, T* object, Deleter deleter) + { + if (!allocator || !object) { + return; + } + + auto data = allocator->Allocate(sizeof(SharedAdoptControlBlock)); + if (!data) { + if (deleter) { + deleter(object, allocator); + } + + return; + } + + mControlBlock = new (data) SharedAdoptControlBlock(*allocator, object, deleter); + mObject = object; + } + + T* mObject {}; + SharedControlBlock* mControlBlock {}; }; /** @@ -524,7 +667,7 @@ class SharedPtr : public SmartPtr { * @return UniquePtr constructed unique ptr, empty if allocation failed. */ template -inline UniquePtr MakeUnique(Allocator* allocator, Args&&... args) +inline UniquePtr MakeUnique(AllocatorItf* allocator, Args&&... args) { assert(allocator); @@ -536,21 +679,6 @@ inline UniquePtr MakeUnique(Allocator* allocator, Args&&... args) return UniquePtr(new (data) T(args...), DefaultDeleter(allocator)); } -/** - * Defers object destruction till the end of the current scope. - * - * @tparam T type of the object to be destroyed. - * @tparam Deleter type of the deleter. - * @param ptr pointer to the object to be destroyed. - * @param deleter functor object to be deferred. - * @return UniquePtr. - */ -template -inline UniquePtr DeferRelease(T* ptr, Deleter&& deleter) -{ - return UniquePtr(ptr, Move(deleter)); -} - /** * Constructs shared pointer. * @@ -561,16 +689,18 @@ inline UniquePtr DeferRelease(T* ptr, Deleter&& deleter) * @return SharedPtr constructed shared ptr, empty if allocation failed. */ template -inline SharedPtr MakeShared(Allocator* allocator, Args&&... args) +inline SharedPtr MakeShared(AllocatorItf* allocator, Args&&... args) { assert(allocator); - auto data = allocator->Allocate(sizeof(T)); + auto data = allocator->Allocate(sizeof(SharedObjectControlBlock)); if (!data) { return SharedPtr(); } - return SharedPtr(allocator, new (data) T(args...), SmartPtrDeleter); + auto* controlBlock = new (data) SharedObjectControlBlock(*allocator, args...); + + return SharedPtr(controlBlock, controlBlock->GetObject()); } } // namespace aos diff --git a/src/core/common/tools/tests/allocator.cpp b/src/core/common/tools/tests/allocator.cpp index 1fa84c9a0..602f4306a 100644 --- a/src/core/common/tools/tests/allocator.cpp +++ b/src/core/common/tools/tests/allocator.cpp @@ -7,80 +7,46 @@ #include -#include +#include +#include using namespace aos; -TEST(AllocatorTest, Allocator) +TEST(AllocatorTest, HeapAllocator) { - StaticAllocator<256> allocator; + HeapAllocator allocator; - EXPECT_EQ(allocator.MaxSize(), 256); - EXPECT_EQ(allocator.FreeSize(), 256); + auto* data = allocator.Allocate(128); + ASSERT_NE(data, nullptr); - struct TestItem { - void* mData; - size_t mSize; - }; - - TestItem testData[] = {{nullptr, 32}, {nullptr, 64}, {nullptr, 128}}; - - auto freeSize = allocator.MaxSize(); - - for (auto& item : testData) { - item.mData = allocator.Allocate(item.mSize); - freeSize -= item.mSize; - EXPECT_EQ(allocator.FreeSize(), freeSize); - } + allocator.Free(data); - for (size_t i = 0; i < ArraySize(testData); i++) { - freeSize += testData[i].mSize; - allocator.Free(testData[i].mData); - - EXPECT_EQ(allocator.FreeSize(), freeSize); - } - - allocator.Allocate(32); - - allocator.Clear(); - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize()); -} + struct TestStruct { + TestStruct(int a, int b) + : mA(a) + , mB(b) + { + } -TEST(AllocatorTest, New) -{ - StaticAllocator<256> allocator; - - auto freeSize = allocator.MaxSize(); - - auto val1 = new (&allocator) uint8_t(); - freeSize -= sizeof(uint8_t); - EXPECT_EQ(allocator.FreeSize(), freeSize); - - auto val2 = new (&allocator) uint16_t(); - freeSize -= sizeof(uint16_t); - EXPECT_EQ(allocator.FreeSize(), freeSize); - - auto val3 = new (&allocator) uint32_t(); - freeSize -= sizeof(uint32_t); - EXPECT_EQ(allocator.FreeSize(), freeSize); - - auto val4 = new (&allocator) uint64_t(); - freeSize -= sizeof(uint64_t); - EXPECT_EQ(allocator.FreeSize(), freeSize); + int mA; + int mB; + }; - operator delete(val4, &allocator); - freeSize += sizeof(uint64_t); - EXPECT_EQ(allocator.FreeSize(), freeSize); + auto uPtr = MakeUnique(&allocator, 1, 2); + ASSERT_TRUE(uPtr); + EXPECT_EQ(uPtr->mA, 1); + EXPECT_EQ(uPtr->mB, 2); - operator delete(val3, &allocator); - freeSize += sizeof(uint32_t); - EXPECT_EQ(allocator.FreeSize(), freeSize); + auto shPtr = MakeShared(&allocator, 3, 4); + ASSERT_TRUE(shPtr); + EXPECT_EQ(shPtr->mA, 3); + EXPECT_EQ(shPtr->mB, 4); - operator delete(val2, &allocator); - freeSize += sizeof(uint16_t); - EXPECT_EQ(allocator.FreeSize(), freeSize); + auto shPtr2 = shPtr; + EXPECT_EQ(shPtr2->mA, 3); - operator delete(val1, &allocator); - freeSize += sizeof(uint8_t); - EXPECT_EQ(allocator.FreeSize(), freeSize); + shPtr.Reset(); + EXPECT_FALSE(shPtr); + EXPECT_TRUE(shPtr2); + EXPECT_EQ(shPtr2->mB, 4); } diff --git a/src/core/common/tools/tests/memory.cpp b/src/core/common/tools/tests/memory.cpp index 70ea4a780..2b23628f7 100644 --- a/src/core/common/tools/tests/memory.cpp +++ b/src/core/common/tools/tests/memory.cpp @@ -7,6 +7,7 @@ #include +#include #include using namespace aos; @@ -38,35 +39,36 @@ class NewClass : public BaseClass { TEST(MemoryTest, UniquePtr) { - StaticAllocator<256> allocator; + HeapAllocator allocator; // Basic test { UniquePtr uPtr = MakeUnique(&allocator, 0); - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize() - sizeof(uint32_t)); + EXPECT_TRUE(uPtr); + EXPECT_EQ(*uPtr, 0U); } - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize()); - // Construct with allocator { - UniquePtr uPtr(new (&allocator) uint32_t(), &allocator); - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize() - sizeof(uint32_t)); - } + auto* raw = static_cast(allocator.Allocate(sizeof(uint32_t))); + ASSERT_NE(raw, nullptr); - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize()); + UniquePtr uPtr(new (raw) uint32_t(), &allocator); + EXPECT_TRUE(uPtr); + } // Construct with deleter { auto deleter = [&allocator](uint32_t* ptr) { allocator.Free(ptr); }; - UniquePtr uPtr(new (&allocator) uint32_t(), Move(deleter)); - } + auto* raw = static_cast(allocator.Allocate(sizeof(uint32_t))); + ASSERT_NE(raw, nullptr); - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize()); + UniquePtr uPtr(new (raw) uint32_t(), Move(deleter)); + } // Move ownership @@ -80,37 +82,36 @@ TEST(MemoryTest, UniquePtr) uPtr = MakeUnique(&allocator); } - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize() - sizeof(uint32_t)); + EXPECT_TRUE(uPtr); OwnUniquePtr(Move(uPtr)); - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize()); + EXPECT_FALSE(uPtr); // Make unique auto uPtr2 = MakeUnique(&allocator); - - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize() - sizeof(uint32_t)); + EXPECT_TRUE(uPtr2); // Check reset uPtr2.Reset(); - - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize()); + EXPECT_FALSE(uPtr2); } TEST(MemoryTest, SharedPtr) { - StaticAllocator<256> allocator; + HeapAllocator allocator; // Basic test { - SharedPtr shPtr(&allocator, new (&allocator) uint32_t()); - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize() - sizeof(uint32_t)); - } + auto* raw = static_cast(allocator.Allocate(sizeof(uint32_t))); + ASSERT_NE(raw, nullptr); - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize()); + SharedPtr shPtr(&allocator, new (raw) uint32_t()); + EXPECT_TRUE(shPtr); + } // Test share @@ -122,69 +123,58 @@ TEST(MemoryTest, SharedPtr) EXPECT_TRUE(nullptr == shPtr); { - shPtr = SharedPtr(&allocator, new (&allocator) uint32_t()); + auto* raw = static_cast(allocator.Allocate(sizeof(uint32_t))); + ASSERT_NE(raw, nullptr); + + shPtr = SharedPtr(&allocator, new (raw) uint32_t()); } - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize() - sizeof(uint32_t)); + EXPECT_TRUE(shPtr); TakeSharedPtr(shPtr); } - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize()); - // Make shared auto shPtr2 = MakeShared(&allocator); - - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize() - sizeof(uint32_t)); + EXPECT_TRUE(shPtr2); // Check reset shPtr2.Reset(); - - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize()); + EXPECT_FALSE(shPtr2); } TEST(MemoryTest, UniquePtrDerivedClass) { - StaticAllocator<256> allocator; - - { - UniquePtr basePtr; + HeapAllocator allocator; - { - auto newPtr = MakeUnique(&allocator); + UniquePtr basePtr; - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize() - sizeof(NewClass)); - - basePtr = Move(newPtr); - } + { + auto newPtr = MakeUnique(&allocator); + EXPECT_TRUE(newPtr); - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize() - sizeof(NewClass)); + basePtr = Move(newPtr); } - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize()); + EXPECT_TRUE(basePtr); } TEST(MemoryTest, SharedPtrDerivedClass) { - StaticAllocator<256> allocator; + HeapAllocator allocator; - { - SharedPtr basePtr; - - { - auto newPtr = MakeShared(&allocator); - - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize() - sizeof(NewClass)); + SharedPtr basePtr; - basePtr = newPtr; - } + { + auto newPtr = MakeShared(&allocator); + EXPECT_TRUE(newPtr); - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize() - sizeof(NewClass)); + basePtr = newPtr; } - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize()); + EXPECT_TRUE(basePtr); } TEST(MemoryTest, DeferRelease) @@ -268,16 +258,13 @@ TEST(MemoryTest, SharedPtrDerivedValueClass) MockFunction* mFunc; }; - StaticAllocator<256> allocator; - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize()); + HeapAllocator allocator; // Check NewClass destructor is called EXPECT_CALL(callback, Call()).Times(1); { SharedPtr basePtr = MakeShared(&allocator, &callback); - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize() - sizeof(NewClass)); + EXPECT_TRUE(basePtr); } - - EXPECT_EQ(allocator.FreeSize(), allocator.MaxSize()); } From c958f60707af34b5b5de4c8418686be9447b0008 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 30 Jul 2026 20:29:26 +0300 Subject: [PATCH 04/13] common: migrate to injected AllocatorItf Convert common/ classes that previously owned a private static allocator to receive an AllocatorItf reference/pointer instead, following the two-phase construct-then-Init() pattern used across the codebase (allocator as the first Init()/constructor parameter): - crypto: CertLoader, CryptoHelper, mbedtls/openssl CryptoProviderItf implementations, pkcs11::Utils, PKCS11RSAPrivateKey. - pkcs11: LibraryContext, PKCS11Manager. - monitoring: Average, Monitoring. - spaceallocator: SpaceAllocator; also renamed its own "space" allocator members (OutdatedItem::mSpaceAllocator, the nested Space class's mSpaceAllocator) to avoid confusion with the new memory AllocatorItf member. - fs: CalculateSize takes an AllocatorItf parameter (first), and FileInfoProvider forwards it internally; dropped the shared static allocator and its guarding mutex, since callers now own their allocator's thread-safety. Multiple per-class named allocators are consolidated into a single AllocatorItf pointer where heap allocation removes the need for separate statically-sized pools. Unit tests construct a HeapAllocator and pass it in, always declared before any member that may allocate from it, since C++ destroys members in reverse declaration order. Signed-off-by: Oleksandr Grytsov --- src/core/common/crypto/certloader.cpp | 15 ++--- src/core/common/crypto/certloader.hpp | 13 +---- src/core/common/crypto/cryptohelper.cpp | 36 ++++++------ src/core/common/crypto/cryptohelper.hpp | 15 ++--- src/core/common/crypto/cryptoutils.cpp | 1 + .../common/crypto/mbedtls/cryptoprovider.cpp | 12 ++-- .../common/crypto/mbedtls/cryptoprovider.hpp | 10 +--- .../common/crypto/openssl/cryptoprovider.cpp | 12 ++-- .../common/crypto/openssl/cryptoprovider.hpp | 11 +--- src/core/common/crypto/tests/certloader.cpp | 24 ++++---- src/core/common/crypto/tests/cryptohelper.cpp | 14 +++-- .../common/crypto/tests/cryptoprovider.cpp | 7 ++- src/core/common/crypto/tests/cryptoutils.cpp | 7 ++- src/core/common/monitoring/average.cpp | 6 +- src/core/common/monitoring/average.hpp | 7 +-- src/core/common/monitoring/monitoring.cpp | 12 ++-- src/core/common/monitoring/monitoring.hpp | 9 ++- .../common/monitoring/tests/monitoring.cpp | 25 ++++---- src/core/common/pkcs11/pkcs11.cpp | 22 +++++-- src/core/common/pkcs11/pkcs11.hpp | 29 +++++++--- src/core/common/pkcs11/privatekey.cpp | 7 ++- src/core/common/pkcs11/privatekey.hpp | 12 ++-- src/core/common/pkcs11/tests/pkcs11.cpp | 52 ++++++++--------- .../common/spaceallocator/spaceallocator.hpp | 58 ++++++++++--------- .../spaceallocator/tests/spaceallocator.cpp | 21 ++++--- .../crypto/providers/cryptofactoryitf.hpp | 3 +- .../tests/crypto/providers/mbedtlsfactory.cpp | 4 +- .../tests/crypto/providers/mbedtlsfactory.hpp | 3 +- .../tests/crypto/providers/opensslfactory.cpp | 4 +- .../tests/crypto/providers/opensslfactory.hpp | 3 +- src/core/common/tests/crypto/softhsmenv.cpp | 8 ++- src/core/common/tests/crypto/softhsmenv.hpp | 5 +- .../common/tests/stubs/spaceallocatorstub.hpp | 3 +- src/core/common/tools/fs.cpp | 22 ++----- src/core/common/tools/fs.hpp | 8 ++- src/core/common/tools/tests/fs.cpp | 14 +++-- 36 files changed, 277 insertions(+), 237 deletions(-) diff --git a/src/core/common/crypto/certloader.cpp b/src/core/common/crypto/certloader.cpp index 146b2bd36..bcfe966fe 100644 --- a/src/core/common/crypto/certloader.cpp +++ b/src/core/common/crypto/certloader.cpp @@ -24,10 +24,11 @@ constexpr auto cSchemeMaxLength = Max(sizeof(cSchemeFile), sizeof(cSchemePKCS11) * CertLoader **********************************************************************************************************************/ -Error CertLoader::Init(x509::ProviderItf& cryptoProvider, pkcs11::PKCS11Manager& pkcs11Manager) +Error CertLoader::Init(AllocatorItf& allocator, x509::ProviderItf& cryptoProvider, pkcs11::PKCS11Manager& pkcs11Manager) { LOG_DBG() << "Init cert loader"; + mAllocator = &allocator; mCryptoProvider = &cryptoProvider; mPKCS11 = &pkcs11Manager; @@ -73,7 +74,7 @@ RetWithError> CertLoader::LoadCertsChainByURL( return {nullptr, err}; } - return pkcs11::Utils(session, *mCryptoProvider, mAllocator).FindCertificateChain(id, label); + return pkcs11::Utils(*mAllocator, session, *mCryptoProvider).FindCertificateChain(id, label); } return {nullptr, ErrorEnum::eInvalidArgument}; @@ -118,7 +119,7 @@ RetWithError> CertLoader::LoadPrivKeyByURL(const String return {nullptr, err}; } - auto key = pkcs11::Utils(session, *mCryptoProvider, mAllocator).FindPrivateKey(id, label); + auto key = pkcs11::Utils(*mAllocator, session, *mCryptoProvider).FindPrivateKey(id, label); return {key.mValue.GetPrivKey(), key.mError}; } @@ -166,7 +167,7 @@ RetWithError CertLoader::FindToken(const pkcs11::LibraryContext& { StaticArray slotList; - auto tokenInfo = MakeUnique(&mAllocator); + auto tokenInfo = MakeUnique(mAllocator); if (!tokenInfo) { return {0, ErrorEnum::eNoMemory}; } @@ -194,7 +195,7 @@ RetWithError> CertLoader::LoadCertsFromFile(co { LOG_DBG() << "Load certs chain from file: fileName=" << fileName; - auto buff = MakeUnique(&mAllocator); + auto buff = MakeUnique(mAllocator); if (!buff) { return {nullptr, ErrorEnum::eNoMemory}; } @@ -204,7 +205,7 @@ RetWithError> CertLoader::LoadCertsFromFile(co return {nullptr, err}; } - auto certificates = MakeShared(&mAllocator); + auto certificates = MakeShared(mAllocator); if (!certificates) { return {nullptr, ErrorEnum::eNoMemory}; } @@ -218,7 +219,7 @@ RetWithError> CertLoader::LoadPrivKeyFromFile(const Str { LOG_DBG() << "Load private key from file: fileName=" << fileName; - auto buff = MakeUnique>(&mAllocator); + auto buff = MakeUnique>(mAllocator); if (!buff) { return {nullptr, ErrorEnum::eNoMemory}; } diff --git a/src/core/common/crypto/certloader.hpp b/src/core/common/crypto/certloader.hpp index fa63febe6..cd2a58d4a 100644 --- a/src/core/common/crypto/certloader.hpp +++ b/src/core/common/crypto/certloader.hpp @@ -24,11 +24,12 @@ class CertLoader : public CertLoaderItf { /** * Initializes object instance. * + * @param allocator allocator to use for certificates/keys. * @param cryptoProvider crypto provider interface. * @param pkcs11Manager PKCS11 library manager. * @return Error. */ - Error Init(x509::ProviderItf& cryptoProvider, pkcs11::PKCS11Manager& pkcs11Manager); + Error Init(AllocatorItf& allocator, x509::ProviderItf& cryptoProvider, pkcs11::PKCS11Manager& pkcs11Manager); /** * Loads certificate chain by URL. @@ -49,12 +50,6 @@ class CertLoader : public CertLoaderItf { private: using PEMCertChainBlob = StaticString; - static constexpr auto cCertAllocatorSize - = cCertChainsCount * cCertChainSize * sizeof(x509::Certificate) + sizeof(PEMCertChainBlob); - static constexpr auto cKeyAllocatorSize - = AOS_CONFIG_CRYPTO_PRIV_KEYS_COUNT * pkcs11::cPrivateKeyMaxSize + sizeof(cPrivKeyPEMLen); - static constexpr auto cNumAllocation = AOS_CONFIG_CRYPTO_NUM_ALLOCATIONS; - static constexpr auto cDefaultPKCS11Library = AOS_CONFIG_CRYPTO_DEFAULT_PKCS11_LIB; RetWithError> OpenSession( @@ -66,9 +61,7 @@ class CertLoader : public CertLoaderItf { x509::ProviderItf* mCryptoProvider = nullptr; pkcs11::PKCS11Manager* mPKCS11 = nullptr; - - StaticAllocator - mAllocator; + AllocatorItf* mAllocator {}; }; } // namespace aos::crypto diff --git a/src/core/common/crypto/cryptohelper.cpp b/src/core/common/crypto/cryptohelper.cpp index e3115173d..0be0cc313 100644 --- a/src/core/common/crypto/cryptohelper.cpp +++ b/src/core/common/crypto/cryptohelper.cpp @@ -21,15 +21,17 @@ CryptoHelper::CryptoHelper() { } -Error CryptoHelper::Init(iamclient::CertProviderItf& certProvider, CryptoProviderItf& cryptoProvider, - CertLoaderItf& certLoader, const String& serviceDiscoveryURL, const String& caCert) +Error CryptoHelper::Init(AllocatorItf& allocator, iamclient::CertProviderItf& certProvider, + CryptoProviderItf& cryptoProvider, CertLoaderItf& certLoader, const String& serviceDiscoveryURL, + const String& caCert) { + mAllocator = &allocator; mCertProvider = &certProvider; mCryptoProvider = &cryptoProvider; mCertLoader = &certLoader; mServiceDiscoveryURL = serviceDiscoveryURL; - auto caCertsPEM = MakeUnique>(&mAllocator); + auto caCertsPEM = MakeUnique>(mAllocator); if (!caCertsPEM) { return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } @@ -113,7 +115,7 @@ Error CryptoHelper::ValidateSigns(const String& decryptedPath, const SignInfo& s { LockGuard lock {mSemaphore}; - auto signCtx = MakeUnique(&mAllocator); + auto signCtx = MakeUnique(mAllocator); if (!signCtx) { return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } @@ -137,12 +139,12 @@ Error CryptoHelper::DecryptMetadata(const Array& input, Array& { LockGuard lock {mSemaphore}; - auto contentInfo = MakeUnique(&mAllocator); + auto contentInfo = MakeUnique(mAllocator); if (!contentInfo) { return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } - auto symKey = MakeUnique>(&mAllocator); + auto symKey = MakeUnique>(mAllocator); if (!symKey) { return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } @@ -177,7 +179,7 @@ Error CryptoHelper::DecryptMetadata(const Array& input, Array& RetWithError> CryptoHelper::GetOnlineCert() { - auto certInfo = MakeUnique(&mAllocator); + auto certInfo = MakeUnique(mAllocator); if (!certInfo) { return {{}, AOS_ERROR_WRAP(ErrorEnum::eNoMemory)}; } @@ -222,7 +224,7 @@ Error CryptoHelper::GetServiceDiscoveryFromExtensions(const x509::Certificate& c Error CryptoHelper::GetServiceDiscoveryFromOrganization( const x509::Certificate& cert, Array>& urls) { - auto subject = MakeUnique>(&mAllocator); + auto subject = MakeUnique>(mAllocator); if (!subject) { return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } @@ -241,12 +243,12 @@ Error CryptoHelper::GetServiceDiscoveryFromOrganization( auto valueStart = orgPos + orgKey.Size(); auto [valueEnd, _] = subject->FindSubstr(valueStart, ","); - auto orgName = MakeUnique>(&mAllocator); + auto orgName = MakeUnique>(mAllocator); if (!orgName) { return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } - auto url = MakeUnique>(&mAllocator); + auto url = MakeUnique>(mAllocator); if (!url) { return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } @@ -358,12 +360,12 @@ Error CryptoHelper::CheckSessionKey( Error CryptoHelper::DecodeFile(const String& encryptedFile, const String& decryptedFile, AESCipherItf& decoder) { - auto inBlock = MakeUnique>(&mAllocator); + auto inBlock = MakeUnique>(mAllocator); if (!inBlock) { return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } - auto outBlock = MakeUnique>(&mAllocator); + auto outBlock = MakeUnique>(mAllocator); if (!outBlock) { return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } @@ -444,7 +446,7 @@ Error CryptoHelper::AddCertificates(const Array& certs, SignCon continue; } - auto cert = MakeUnique(&mAllocator); + auto cert = MakeUnique(mAllocator); if (!cert) { return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } @@ -512,7 +514,7 @@ Error CryptoHelper::VerifySigns(const String& file, const SignInfo& signs, SignC } // Verify sign - auto hashSum = MakeUnique>(&mAllocator); + auto hashSum = MakeUnique>(mAllocator); if (!hashSum) { return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } @@ -540,7 +542,7 @@ Error CryptoHelper::VerifySigns(const String& file, const SignInfo& signs, SignC } // Verify certs - auto intermCertPool = MakeUnique>(&mAllocator); + auto intermCertPool = MakeUnique>(mAllocator); if (!intermCertPool) { return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } @@ -899,7 +901,7 @@ Error CryptoHelper::ParseEncryptedContentInfo(const Array& data, Encryp Error CryptoHelper::GetKeyForEnvelope(const TransRecipientInfo& info, Array& symmetricKey) { - auto certInfo = MakeUnique(&mAllocator); + auto certInfo = MakeUnique(mAllocator); if (!certInfo) { return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } @@ -966,7 +968,7 @@ Error CryptoHelper::DecryptMessage( Error CryptoHelper::DecodeMessage(AESCipherItf& decoder, const Array& input, Array& message) { - auto outBlock = MakeUnique>(&mAllocator); + auto outBlock = MakeUnique>(mAllocator); if (!outBlock) { return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } diff --git a/src/core/common/crypto/cryptohelper.hpp b/src/core/common/crypto/cryptohelper.hpp index a569e6f5b..df8e6b4ae 100644 --- a/src/core/common/crypto/cryptohelper.hpp +++ b/src/core/common/crypto/cryptohelper.hpp @@ -8,6 +8,7 @@ #define AOS_AOS_COMMON_CRYPTO_CRYPTOHELPER_HPP_ #include +#include #include "itf/certloader.hpp" #include "itf/crypto.hpp" @@ -97,6 +98,7 @@ class CryptoHelper : public CryptoHelperItf { /** * Initializes crypto helper. * + * @param allocator allocator to use for temporary objects. * @param certProvider certificate provider interface. * @param cryptoProvider cryptographic provider interface. * @param certLoader certificate loader interface. @@ -104,8 +106,8 @@ class CryptoHelper : public CryptoHelperItf { * @param caCert root certificate path. * @return Error. */ - Error Init(iamclient::CertProviderItf& certProvider, CryptoProviderItf& cryptoProvider, CertLoaderItf& certLoader, - const String& serviceDiscoveryURL, const String& caCert); + Error Init(AllocatorItf& allocator, iamclient::CertProviderItf& certProvider, CryptoProviderItf& cryptoProvider, + CertLoaderItf& certLoader, const String& serviceDiscoveryURL, const String& caCert); /** * Retrieves available service discovery URLs. @@ -157,11 +159,6 @@ class CryptoHelper : public CryptoHelperItf { static constexpr auto cRSAEncryptionOid = "1.2.840.113549.1.1.1"; static constexpr auto cAES256CBCOid = "2.16.840.1.101.3.4.1.42"; - static constexpr auto cThreadHeapUsage = 2 * sizeof(CertInfo) + sizeof(StaticString) - + sizeof(StaticArray) + sizeof(SignContext) + sizeof(x509::Certificate) - + sizeof(StaticArray) + sizeof(StaticArray) - + sizeof(StaticArray) * 2 + sizeof(StaticString) * 2; - RetWithError> GetOnlineCert(); Error SetDefaultServiceDiscoveryURL(Array>& urls); Error GetServiceDiscoveryFromExtensions(const x509::Certificate& cert, Array>& urls); @@ -201,8 +198,8 @@ class CryptoHelper : public CryptoHelperItf { StaticString mServiceDiscoveryURL; x509::CertificateChain mCACerts; - Semaphore mSemaphore; - StaticAllocator mAllocator; + Semaphore mSemaphore; + AllocatorItf* mAllocator {}; }; } // namespace aos::crypto diff --git a/src/core/common/crypto/cryptoutils.cpp b/src/core/common/crypto/cryptoutils.cpp index be1ee173b..243f89c31 100644 --- a/src/core/common/crypto/cryptoutils.cpp +++ b/src/core/common/crypto/cryptoutils.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "cryptoutils.hpp" diff --git a/src/core/common/crypto/mbedtls/cryptoprovider.cpp b/src/core/common/crypto/mbedtls/cryptoprovider.cpp index addb2d326..3bd3e92f3 100644 --- a/src/core/common/crypto/mbedtls/cryptoprovider.cpp +++ b/src/core/common/crypto/mbedtls/cryptoprovider.cpp @@ -574,10 +574,12 @@ Error VerifyECDSASignature(const ECDSAPublicKey& pubKey, const Array& d * Public **********************************************************************************************************************/ -Error MbedTLSCryptoProvider::Init() +Error MbedTLSCryptoProvider::Init(AllocatorItf& allocator) { LOG_DBG() << "Init mbedTLS crypto provider"; + mAllocator = &allocator; + auto ret = psa_crypto_init(); return ret != PSA_SUCCESS ? AOS_ERROR_WRAP(ret) : ErrorEnum::eNone; @@ -827,7 +829,7 @@ RetWithError> MbedTLSCryptoProvider::PEMToX509PrivKey(c { LOG_ERR() << "Create private key from PEM"; - auto res = MakeShared(&mAllocator); + auto res = MakeShared(mAllocator); if (!res) { return {{}, ErrorEnum::eNoMemory}; } @@ -944,7 +946,7 @@ RetWithError> MbedTLSCryptoProvider::CreateHash(Hash algorith return {nullptr, ErrorEnum::eNotSupported}; } - auto hasher = MakeUnique(&mAllocator, alg); + auto hasher = MakeUnique(mAllocator, alg); if (!hasher) { return {nullptr, ErrorEnum::eNoMemory}; } @@ -1062,7 +1064,7 @@ RetWithError> MbedTLSCryptoProvider::CreateAESEncoder( return {{}, AOS_ERROR_WRAP(ErrorEnum::eNotSupported)}; } - auto cipher = MakeUnique(&mAllocator); + auto cipher = MakeUnique(mAllocator); if (!cipher) { return {{}, ErrorEnum::eNoMemory}; } @@ -1082,7 +1084,7 @@ RetWithError> MbedTLSCryptoProvider::CreateAESDecoder( return {{}, AOS_ERROR_WRAP(ErrorEnum::eNotSupported)}; } - auto cipher = MakeUnique(&mAllocator); + auto cipher = MakeUnique(mAllocator); if (!cipher) { return {{}, ErrorEnum::eNoMemory}; } diff --git a/src/core/common/crypto/mbedtls/cryptoprovider.hpp b/src/core/common/crypto/mbedtls/cryptoprovider.hpp index 88ec9d269..7b1f43b61 100644 --- a/src/core/common/crypto/mbedtls/cryptoprovider.hpp +++ b/src/core/common/crypto/mbedtls/cryptoprovider.hpp @@ -27,9 +27,10 @@ class MbedTLSCryptoProvider : public CryptoProviderItf { /** * Initializes the object. * + * @param allocator allocator to use for temporary and key objects. * @result Error. */ - Error Init(); + Error Init(AllocatorItf& allocator); /** * Creates a new certificate based on a template. @@ -396,11 +397,6 @@ class MbedTLSCryptoProvider : public CryptoProviderItf { mutable mbedtls_pk_context mPrivKey; }; - static constexpr auto cAllocatorSize - = AOS_CONFIG_CRYPTO_PUB_KEYS_COUNT * Max(sizeof(RSAPublicKey), sizeof(ECDSAPublicKey)) - + AOS_CONFIG_CRYPTO_HASHER_COUNT * sizeof(MBedTLSHash) - + AOS_CONFIG_CRYPTO_PRIV_KEYS_COUNT * sizeof(MbedTLSRSAPrivKey); - static int VerifyTime(void* data, mbedtls_x509_crt* crt, int depth, uint32_t* flags); static RetWithError