diff options
author | wolfbeast <mcwerewolf@gmail.com> | 2018-11-01 07:31:23 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@gmail.com> | 2018-11-01 07:31:23 +0100 |
commit | a2a8c71d7774858db67f51b9c475c5b1d4e43e8f (patch) | |
tree | c8be0702232dc240e94c077c97473e7afb36f615 | |
parent | fdbac095968bc952fec6a03765a7156940ae4733 (diff) | |
download | UXP-a2a8c71d7774858db67f51b9c475c5b1d4e43e8f.tar UXP-a2a8c71d7774858db67f51b9c475c5b1d4e43e8f.tar.gz UXP-a2a8c71d7774858db67f51b9c475c5b1d4e43e8f.tar.lz UXP-a2a8c71d7774858db67f51b9c475c5b1d4e43e8f.tar.xz UXP-a2a8c71d7774858db67f51b9c475c5b1d4e43e8f.zip |
Make HTTP/2 compressor more resilient to bad data.
-rw-r--r-- | netwerk/protocol/http/Http2Compression.cpp | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/netwerk/protocol/http/Http2Compression.cpp b/netwerk/protocol/http/Http2Compression.cpp index 64fd05a17..9206f8b4c 100644 --- a/netwerk/protocol/http/Http2Compression.cpp +++ b/netwerk/protocol/http/Http2Compression.cpp @@ -402,7 +402,7 @@ Http2Decompressor::DecodeHeaderBlock(const uint8_t *data, uint32_t datalen, 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(); @@ -684,6 +684,11 @@ nsresult Http2Decompressor::DecodeFinalHuffmanCharacter(const HuffmanIncomingTable *table, uint8_t &c, uint8_t &bitsLeft) { + MOZ_ASSERT(mOffset <= mDataLen); + if (mOffset > mDataLen) { + NS_WARNING("DecodeFinalHuffmanCharacter trying to 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); @@ -721,6 +726,7 @@ Http2Decompressor::DecodeFinalHuffmanCharacter(const HuffmanIncomingTable *table uint8_t Http2Decompressor::ExtractByte(uint8_t bitsLeft, uint32_t &bytesConsumed) { + MOZ_DIAGNOSTIC_ASSERT(mOffset < mDataLen); uint8_t rv; if (bitsLeft) { @@ -750,8 +756,8 @@ Http2Decompressor::DecodeHuffmanCharacter(const HuffmanIncomingTable *table, 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")); @@ -892,6 +898,13 @@ Http2Decompressor::DoLiteralInternal(nsACString &name, nsACString &value, 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) { @@ -919,6 +932,13 @@ Http2Decompressor::DoLiteralInternal(nsACString &name, nsACString &value, 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); |