rde_handler: Check multiPartReceiveResp 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: Ic217a7a9be39c0873d10f89fe68b559e5d3cfadb
diff --git a/src/rde/rde_handler.cpp b/src/rde/rde_handler.cpp
index 49641c8..6f6acfb 100644
--- a/src/rde/rde_handler.cpp
+++ b/src/rde/rde_handler.cpp
@@ -20,7 +20,7 @@
RdeCommandHandler::RdeCommandHandler(
std::unique_ptr<ExternalStorerInterface> exStorer) :
flagState(RdeDictTransferFlagState::RdeStateIdle),
- exStorer(std::move(exStorer))
+ exStorer(std::move(exStorer)), prevDictResourceId(0), crc(0xFFFFFFFF)
{
// Initialize CRC table.
calcCrcTable();
@@ -122,9 +122,25 @@
RdeDecodeStatus RdeCommandHandler::multiPartReceiveResp(
std::span<const uint8_t> rdeCommand)
{
+ if (rdeCommand.size() < sizeof(MultipartReceiveResHeader))
+ {
+ stdplus::print(
+ stderr, "RDE command is smaller than the expected header size.\n");
+ return RdeDecodeStatus::RdeInvalidCommand;
+ }
+
const MultipartReceiveResHeader* header =
reinterpret_cast<const MultipartReceiveResHeader*>(rdeCommand.data());
+ if (rdeCommand.size() <
+ sizeof(MultipartReceiveResHeader) + header->dataLengthBytes)
+ {
+ stdplus::print(
+ stderr,
+ "RDE command size is smaller than header + declared payload size.\n");
+ return RdeDecodeStatus::RdeInvalidCommand;
+ }
+
// This is a hack to get the resource ID for the dictionary data. Even
// though nextDataTransferHandle field is supposed to be used for something
// else, BIOS is using it to specify the resource ID corresponding to the