update_engine: Check metadata and signature sizes
Check that the size of the metadata size and signature sizes are
smaller that the payload size. Without this check, the delta
performer writes X number of bytes to the buffer before validating
these values, and an attacker could provide a huge value which will
make update_engine crash.
BUG=chromium:1027166
TEST=fuzzer, unittest, install/unistall DLC on DUT
TEST=test_that -b $BOARD $IP autoupdate_EOL
Change-Id: Iad3a314efacbb1005fac37dd383a3f8852008f4b
Reviewed-on: https://chromium-review.googlesource.com/c/aosp/platform/system/update_engine/+/1976079
Commit-Queue: Andrew Lassalle <andrewlassalle@chromium.org>
Tested-by: Andrew Lassalle <andrewlassalle@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
Auto-Submit: Andrew Lassalle <andrewlassalle@chromium.org>
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index ee5f38c..3263ff7 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -458,6 +458,21 @@
return MetadataParseResult::kError;
}
}
+
+ // Check that the |metadata signature size_| and |metadata_size_| are not
+ // very big numbers. This is necessary since |update_engine| needs to write
+ // these values into the buffer before being able to use them, and if an
+ // attacker sets these values to a very big number, the buffer will overflow
+ // and |update_engine| will crash. A simple way of solving this is to check
+ // that the size of both values is smaller than the payload itself.
+ if (metadata_size_ + metadata_signature_size_ > payload_->size) {
+ LOG(ERROR) << "The size of the metadata_size(" << metadata_size_ << ")"
+ << " or metadata signature(" << metadata_signature_size_ << ")"
+ << " is greater than the size of the payload"
+ << "(" << payload_->size << ")";
+ *error = ErrorCode::kDownloadInvalidMetadataSize;
+ return MetadataParseResult::kError;
+ }
}
// Now that we have validated the metadata size, we should wait for the full