From cc469934b34025cd2e0f1f3b76d54dabfdd36c62 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Wed, 30 Nov 2022 00:40:56 +0100 Subject: [PATCH 1/2] Fix potential OOB access during huffman decompression If 'readsize' is equal to the size of the input buffer, there's potentially OOB access because the while loop increases the bit offset and only checks the nodes from the huffman tree and not whether the number of bits exceeds 'readsize'. This won't lead to problems if the size of input buffer is greater than 'readsize' but still a design flaw. --- src/huffman.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/huffman.c b/src/huffman.c index 466b62dc..fa9e9f8c 100644 --- a/src/huffman.c +++ b/src/huffman.c @@ -50,9 +50,9 @@ static int get_bit( byte *fin ) { /* Get a symbol */ -static void Huff_offsetReceive( node_t *node, int *ch, byte *fin, int *offset ) { +static void Huff_offsetReceive( node_t *node, int *ch, byte *fin, int readsize, int *offset ) { bloc = *offset; - while ( node && node->symbol == INTERNAL_NODE ) { + while ( node && node->symbol == INTERNAL_NODE && bloc < readsize ) { if ( get_bit( fin ) ) { node = node->right; @@ -128,7 +128,7 @@ int MSG_ReadBitsCompress(const byte* input, int readsize, byte* outputBuf, int o } for(offset = 0, i = 0; offset < readsize && i < outputBufSize; i++){ - Huff_offsetReceive( msgHuff.tree, &get, (byte*)input, &offset); + Huff_offsetReceive( msgHuff.tree, &get, (byte*)input, readsize, &offset); *outptr = (byte)get; outptr++; } From f17147487d4d364c6f669b7e1ee1d15c8748a982 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Wed, 30 Nov 2022 16:50:22 +0100 Subject: [PATCH 2/2] Rectification of the previous patch for OOB access during huffman decompression If the OOB check is only included in the while evaluation, it's possible the 0x07 / EOF byte is never returned from this function. --- src/huffman.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/huffman.c b/src/huffman.c index fa9e9f8c..6c8590bf 100644 --- a/src/huffman.c +++ b/src/huffman.c @@ -61,6 +61,13 @@ static void Huff_offsetReceive( node_t *node, int *ch, byte *fin, int readsize, node = node->left; } + + if ( bloc >= readsize ) { + //Com_PrintError("OOB buffer access\n"); + *ch = 7; // EOF + *offset = bloc; + return; + } } if ( !node ) { *ch = 0;