rde_handler: Check operationInitRequest over-read
It seems the handler had vulnerabilities to buffer over-reads found by
the fuzzer. Fix them and add unit test coverage.
Tested: Unit test
Signed-off-by: Brandon Kim <brandonkim@google.com>
Change-Id: I655c28c799f0eda072636d55bfef83727afc5df7
diff --git a/src/rde/rde_handler.cpp b/src/rde/rde_handler.cpp
index 6f6acfb..74f6204 100644
--- a/src/rde/rde_handler.cpp
+++ b/src/rde/rde_handler.cpp
@@ -50,14 +50,39 @@
RdeDecodeStatus RdeCommandHandler::operationInitRequest(
std::span<const uint8_t> rdeCommand)
{
+ // Ensure rdeCommand is large enough for the header.
+ if (rdeCommand.size() < sizeof(RdeOperationInitReqHeader))
+ {
+ stdplus::print(
+ stderr,
+ "RDE OperationInitRequest command is smaller than the expected header size. Received: {}, Expected: {}\n",
+ rdeCommand.size(), sizeof(RdeOperationInitReqHeader));
+ return RdeDecodeStatus::RdeInvalidCommand;
+ }
+
const RdeOperationInitReqHeader* header =
reinterpret_cast<const RdeOperationInitReqHeader*>(rdeCommand.data());
+
// Check if there is a payload. If not, we are not doing anything.
if (!header->containsRequestPayload)
{
return RdeDecodeStatus::RdeOk;
}
+ // Ensure rdeCommand is large enough for header + locator + declared
+ // payload.
+ size_t expectedTotalSize =
+ sizeof(RdeOperationInitReqHeader) + header->operationLocatorLength +
+ header->requestPayloadLength;
+ if (rdeCommand.size() < expectedTotalSize)
+ {
+ stdplus::print(
+ stderr,
+ "RDE OperationInitRequest command size is smaller than header + locator + declared payload size. Received: {}, Expected: {}\n",
+ rdeCommand.size(), expectedTotalSize);
+ return RdeDecodeStatus::RdeInvalidCommand;
+ }
+
if (header->operationType !=
static_cast<uint8_t>(RdeOperationInitType::RdeOpInitOperationUpdate))
{