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