From d02f02250da9d2f0c4e81e1b19042f8f23dd8018 Mon Sep 17 00:00:00 2001 From: ankprasa Date: Wed, 1 Apr 2026 09:40:29 +0000 Subject: [PATCH] Validate APCB Token before applying PATCH There is a corner case where, if invalid APCB Token is passed through Redfish, the operation should throw invalid error. Signed-off-by: ankprasa --- redfish-core/lib/rde.hpp | 96 +++++++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 15 deletions(-) diff --git a/redfish-core/lib/rde.hpp b/redfish-core/lib/rde.hpp index 293064b1ce..4091b1472f 100644 --- a/redfish-core/lib/rde.hpp +++ b/redfish-core/lib/rde.hpp @@ -37,6 +37,10 @@ using RDEVariantType = std::variant, std::string, using RDEPropertiesMap = std::vector>; using ObjectPath = sdbusplus::message::object_path; using DbusVariantType = std::variant; +using APCBDataTableValueType = std::variant; +using APCBDataTableEntryType = + std::map; +using APCBDataTableType = std::map; constexpr const char* procSchemaName = "Processors"; constexpr const char* networkSchemaName = "NetworkAdapter"; @@ -47,6 +51,12 @@ constexpr const char* rdeSignalInterface = constexpr const char* rdeManagerPath = "/xyz/openbmc_project/RDE/Manager"; constexpr const char* rdeManagerInterface = "xyz.openbmc_project.RDE.Manager"; constexpr const char* rdeOperationMethod = "StartRedfishOperation"; +constexpr const char* rdeCacheManagerPath = "/xyz/openbmc_project/RDE/CacheManager"; +constexpr const char* rdeCacheManagerInterface = + "xyz.openbmc_project.RDE.CacheManager"; +constexpr const char* rdeApcbDataTableProperty = "APCBDataTable"; +constexpr const char* socConfigurationTokenSubUri = + "Oem/AMD/SocConfiguration/Token"; constexpr const char* rdeOperationTypeRead = "xyz.openbmc_project.RDE.Common.OperationType.READ"; constexpr const char* rdeOperationTypePatch = @@ -306,6 +316,30 @@ inline void rdeCreateTask(task::Payload&& payload, task->payload.emplace(std::move(payload)); } +inline bool validateSocConfigurationPatchTokenKeys( + crow::Response& response, const nlohmann::json& jsonPayload, + const APCBDataTableType& apcbDataTable) +{ + const nlohmann::json::object_t* requestObject = + jsonPayload.get_ptr(); + if (requestObject == nullptr || requestObject->empty()) + { + messages::propertyValueIncorrect(response, "RequestBody", jsonPayload); + return false; + } + + for (const auto& [key, value] : *requestObject) + { + if (key.empty() || apcbDataTable.find(key) == apcbDataTable.end()) + { + messages::propertyValueIncorrect(response, key, value); + return false; + } + } + + return true; +} + /** * @class RDEServiceHandler * @brief Handles Redfish Device Enablement (RDE) service requests. @@ -1069,29 +1103,61 @@ class RDEServiceHandler : public std::enable_shared_from_this return; } - std::string rdePayload = jsonPayload.dump(); - // Begin async method call - crow::connections::systemBus->async_method_call( - [self](const boost::system::error_code ec, - const sdbusplus::message_t&, const ObjectPath& objPath) { + auto startPatchOperation = [self](std::string&& rdePayload) { + crow::connections::systemBus->async_method_call( + [self](const boost::system::error_code ec, + const sdbusplus::message_t&, const ObjectPath& objPath) { + if (ec) + { + BMCWEB_LOG_ERROR("RDE: operationGet failed: {}", + ec.message()); + messages::internalError(self->asyncResp->res); + return; + } + + BMCWEB_LOG_INFO("RDE: task created at {}", + static_cast(objPath)); + + task::Payload payload(self->request); + rdeCreateTask(std::move(payload), objPath, + self->resourceData); + }, + pldmService, rdeManagerPath, rdeManagerInterface, + rdeOperationMethod, self->nextOperationId(), + rdeOperationTypePatch, self->subUri, self->deviceUUID, + self->deviceEID, std::move(rdePayload), rdePayloadFormatInline, + rdeEncodingFormatJSON, self->schema); + }; + + if (self->subUri != socConfigurationTokenSubUri) + { + startPatchOperation(jsonPayload.dump()); + return; + } + + dbus::utility::getProperty( + pldmService, rdeCacheManagerPath, rdeCacheManagerInterface, + rdeApcbDataTableProperty, + [self, jsonPayload = std::move(jsonPayload), + startPatchOperation = std::move(startPatchOperation)]( + const boost::system::error_code& ec, + const APCBDataTableType& apcbDataTable) mutable { if (ec) { - BMCWEB_LOG_ERROR("RDE: operationGet failed: {}", + BMCWEB_LOG_ERROR("RDE: APCBDataTable query failed: {}", ec.message()); messages::internalError(self->asyncResp->res); return; } - BMCWEB_LOG_INFO("RDE: task created at {}", - static_cast(objPath)); + if (!validateSocConfigurationPatchTokenKeys( + self->asyncResp->res, jsonPayload, apcbDataTable)) + { + return; + } - task::Payload payload(self->request); - rdeCreateTask(std::move(payload), objPath, self->resourceData); - }, - pldmService, rdeManagerPath, rdeManagerInterface, - rdeOperationMethod, self->nextOperationId(), rdeOperationTypePatch, - self->subUri, self->deviceUUID, self->deviceEID, rdePayload, - rdePayloadFormatInline, rdeEncodingFormatJSON, self->schema); + startPatchOperation(jsonPayload.dump()); + }); } /**