Bug 1492524. r=dragana
authorNicholas Hurley <hurley@mozilla.com>
Mon, 08 Oct 2018 06:44:42 -0400
changeset 488314 430f18b70e6f2def589d9b304abad3bc8d10d58d
parent 488313 2b61cf8794a0f641d980d9d7ec6aa3643184a1f0
child 488315 594b22ac459fc11ee7948cd7be54b88a86bd54c1
push id246
push userfmarier@mozilla.com
push dateSat, 13 Oct 2018 00:15:40 +0000
reviewersdragana
bugs1492524
milestone64.0a1
Bug 1492524. r=dragana Differential Revision: https://phabricator.services.mozilla.com/D6946
netwerk/protocol/http/Http2Compression.cpp
--- a/netwerk/protocol/http/Http2Compression.cpp
+++ b/netwerk/protocol/http/Http2Compression.cpp
@@ -416,17 +416,17 @@ Http2Decompressor::DecodeHeaderBlock(con
   mHeaderScheme.Truncate();
   mHeaderPath.Truncate();
   mHeaderMethod.Truncate();
   mSeenNonColonHeader = false;
   mIsPush = isPush;
 
   nsresult rv = NS_OK;
   nsresult softfail_rv = NS_OK;
-  while (NS_SUCCEEDED(rv) && (mOffset < datalen)) {
+  while (NS_SUCCEEDED(rv) && (mOffset < mDataLen)) {
     bool modifiesTable = true;
     if (mData[mOffset] & 0x80) {
       rv = DoIndexed();
       LOG(("Decompressor state after indexed"));
     } else if (mData[mOffset] & 0x40) {
       rv = DoLiteralWithIncremental();
       LOG(("Decompressor state after literal with incremental"));
     } else if (mData[mOffset] & 0x20) {
@@ -698,16 +698,21 @@ Http2Decompressor::CopyStringFromInput(u
   mOffset += bytes;
   return NS_OK;
 }
 
 nsresult
 Http2Decompressor::DecodeFinalHuffmanCharacter(const HuffmanIncomingTable *table,
                                                uint8_t &c, uint8_t &bitsLeft)
 {
+  MOZ_ASSERT(mOffset <= mDataLen);
+  if (mOffset > mDataLen) {
+    NS_WARNING("DecodeFinalHuffmanCharacter would read beyond end of buffer");
+    return NS_ERROR_FAILURE;
+  }
   uint8_t mask = (1 << bitsLeft) - 1;
   uint8_t idx = mData[mOffset - 1] & mask;
   idx <<= (8 - bitsLeft);
   // Don't update bitsLeft yet, because we need to check that value against the
   // number of bits used by our encoding later on. We'll update when we are sure
   // how many bits we've actually used.
 
   if (table->IndexHasANextTable(idx)) {
@@ -735,16 +740,17 @@ Http2Decompressor::DecodeFinalHuffmanCha
   bitsLeft -= entry->mPrefixLen;
 
   return NS_OK;
 }
 
 uint8_t
 Http2Decompressor::ExtractByte(uint8_t bitsLeft, uint32_t &bytesConsumed)
 {
+  MOZ_DIAGNOSTIC_ASSERT(mOffset < mDataLen);
   uint8_t rv;
 
   if (bitsLeft) {
     // Need to extract bitsLeft bits from the previous byte, and 8 - bitsLeft
     // bits from the current byte
     uint8_t mask = (1 << bitsLeft) - 1;
     rv = (mData[mOffset - 1] & mask) << (8 - bitsLeft);
     rv |= (mData[mOffset] & ~mask) >> bitsLeft;
@@ -764,18 +770,18 @@ Http2Decompressor::ExtractByte(uint8_t b
 nsresult
 Http2Decompressor::DecodeHuffmanCharacter(const HuffmanIncomingTable *table,
                                           uint8_t &c, uint32_t &bytesConsumed,
                                           uint8_t &bitsLeft)
 {
   uint8_t idx = ExtractByte(bitsLeft, bytesConsumed);
 
   if (table->IndexHasANextTable(idx)) {
-    if (bytesConsumed >= mDataLen) {
-      if (!bitsLeft || (bytesConsumed > mDataLen)) {
+    if (mOffset >= mDataLen) {
+      if (!bitsLeft || (mOffset > mDataLen)) {
         // TODO - does this get me into trouble in the new world?
         // No info left in input to try to consume, we're done
         LOG(("DecodeHuffmanCharacter all out of bits to consume, can't chain"));
         return NS_ERROR_FAILURE;
       }
 
       // We might get lucky here!
       return DecodeFinalHuffmanCharacter(table->NextTable(idx), c, bitsLeft);
@@ -906,16 +912,23 @@ Http2Decompressor::DoLiteralInternal(nsA
 
   // first let's get the name
   uint32_t index;
   nsresult rv = DecodeInteger(namePrefixLen, index);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
+  // sanity check
+  if (mOffset >= mDataLen) {
+    NS_WARNING("Http2 Decompressor ran out of data");
+    // This is session-fatal
+    return NS_ERROR_FAILURE;
+  }
+
   bool isHuffmanEncoded;
 
   if (!index) {
     // name is embedded as a literal
     uint32_t nameLen;
     isHuffmanEncoded = mData[mOffset] & (1 << 7);
     rv = DecodeInteger(7, nameLen);
     if (NS_SUCCEEDED(rv)) {
@@ -933,16 +946,23 @@ Http2Decompressor::DoLiteralInternal(nsA
     rv = CopyHeaderString(index - 1, name);
     LOG(("Http2Decompressor::DoLiteralInternal indexed name %d %s",
          index, name.BeginReading()));
   }
   if (NS_FAILED(rv)) {
     return rv;
   }
 
+  // sanity check
+  if (mOffset >= mDataLen) {
+    NS_WARNING("Http2 Decompressor ran out of data");
+    // This is session-fatal
+    return NS_ERROR_FAILURE;
+  }
+
   // now the value
   uint32_t valueLen;
   isHuffmanEncoded = mData[mOffset] & (1 << 7);
   rv = DecodeInteger(7, valueLen);
   if (NS_SUCCEEDED(rv)) {
     if (isHuffmanEncoded) {
       rv = CopyHuffmanStringFromInput(valueLen, value);
     } else {