metrics: Add a check for abnormally small messages to prevent crashes

In some situations the |message_size| read from |fd| comes up as 0. In this
case we try to read a negative size for the message body and this leads for
crashes. Add a check to make sure that message_size is at least 4 bytes long
to account for the required 32-bit integer message size field.

BUG=chrome-os-partner:40711
TEST=`FEATURES=test emerge-link metrics`

Change-Id: Ie9adbc8e0e6a9f2c80450bf7ebcb3e05ad1f1f8e
Reviewed-on: https://chromium-review.googlesource.com/276362
Trybot-Ready: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Reviewed-by: Bertrand Simonnet <bsimonnet@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/metrics/serialization/serialization_utils.cc b/metrics/serialization/serialization_utils.cc
index abb73ab..80d586e 100644
--- a/metrics/serialization/serialization_utils.cc
+++ b/metrics/serialization/serialization_utils.cc
@@ -36,7 +36,8 @@
   CHECK(message);
 
   int result;
-  int32 message_size;
+  int32_t message_size;
+  const int32_t message_hdr_size = sizeof(message_size);
   // The file containing the metrics do not leave the device so the writer and
   // the reader will always have the same endianness.
   result = HANDLE_EINTR(read(fd, &message_size, sizeof(message_size)));
@@ -48,7 +49,7 @@
     // This indicates a normal EOF.
     return false;
   }
-  if (result < static_cast<int>(sizeof(message_size))) {
+  if (result < message_hdr_size) {
     DLOG(ERROR) << "bad read size " << result << ", expecting "
                 << sizeof(message_size);
     return false;
@@ -68,7 +69,12 @@
     return true;
   }
 
-  message_size -= sizeof(message_size);  // The message size includes itself.
+  if (message_size < message_hdr_size) {
+    DLOG(ERROR) << "message too short : " << message_size;
+    return false;
+  }
+
+  message_size -= message_hdr_size;  // The message size includes itself.
   char buffer[SerializationUtils::kMessageMaxLength];
   if (!base::ReadFromFD(fd, buffer, message_size)) {
     DPLOG(ERROR) << "reading metrics message body";