diff options
author | /dev/humancontroller <devhc@example.com> | 2017-08-14 14:04:02 +0200 |
---|---|---|
committer | /dev/humancontroller <devhc@example.com> | 2017-08-14 14:04:02 +0200 |
commit | 57a3338110978b37baab6f7c45935a1dff5db603 (patch) | |
tree | a9b6be3eb4b16c1e8053e8ae64b79cd0b9377181 /src/qcommon/msg.c | |
parent | a150f425666146fbdca921ea44838b81889ec9e9 (diff) |
apply the security patch for incoming-packet VoIP-data parsing and Huffman decompression
TODO: improve this description
Diffstat (limited to 'src/qcommon/msg.c')
-rw-r--r-- | src/qcommon/msg.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/src/qcommon/msg.c b/src/qcommon/msg.c index 8258abdd..22347633 100644 --- a/src/qcommon/msg.c +++ b/src/qcommon/msg.c @@ -111,9 +111,7 @@ void MSG_WriteBits( msg_t *msg, int value, int bits ) { oldsize += bits; - // this isn't an exact overflow check, but close enough - if ( msg->maxsize - msg->cursize < 4 ) { - msg->overflowed = qtrue; + if ( msg->overflowed ) { return; } @@ -141,6 +139,11 @@ void MSG_WriteBits( msg_t *msg, int value, int bits ) { bits = -bits; } if (msg->oob) { + if ( msg->cursize + ( bits >> 3 ) > msg->maxsize ) { + msg->overflowed = qtrue; + return; + } + if(bits==8) { msg->data[msg->cursize] = value; @@ -169,6 +172,10 @@ void MSG_WriteBits( msg_t *msg, int value, int bits ) { if (bits&7) { int nbits; nbits = bits&7; + if ( msg->bit + nbits > msg->maxsize << 3 ) { + msg->overflowed = qtrue; + return; + } for(i=0;i<nbits;i++) { Huff_putBit((value&1), msg->data, &msg->bit); value = (value>>1); @@ -178,8 +185,12 @@ void MSG_WriteBits( msg_t *msg, int value, int bits ) { if (bits) { for(i=0;i<bits;i+=8) { // fwrite(bp, 1, 1, fp); - Huff_offsetTransmit (&msgHuff.compressor, (value&0xff), msg->data, &msg->bit); + Huff_offsetTransmit( &msgHuff.compressor, (value & 0xff), msg->data, &msg->bit, msg->maxsize << 3 ); value = (value>>8); + if ( msg->bit > msg->maxsize << 3 ) { + msg->overflowed = qtrue; + return; + } } } msg->cursize = (msg->bit>>3)+1; @@ -194,6 +205,11 @@ int MSG_ReadBits( msg_t *msg, int bits ) { int i, nbits; // FILE* fp; + if ( msg->readcount > msg->cursize ) { + // overflowed + return 0; + } + value = 0; if ( bits < 0 ) { @@ -204,6 +220,12 @@ int MSG_ReadBits( msg_t *msg, int bits ) { } if (msg->oob) { + if (msg->readcount + (bits>>3) > msg->cursize) { + // overflowed + msg->readcount = msg->cursize + 1; + return 0; + } + if(bits==8) { value = msg->data[msg->readcount]; @@ -231,6 +253,11 @@ int MSG_ReadBits( msg_t *msg, int bits ) { nbits = 0; if (bits&7) { nbits = bits&7; + if (msg->bit + nbits > msg->cursize << 3) { + // overflowed + msg->readcount = msg->cursize + 1; + return 0; + } for(i=0;i<nbits;i++) { value |= (Huff_getBit(msg->data, &msg->bit)<<i); } @@ -239,9 +266,15 @@ int MSG_ReadBits( msg_t *msg, int bits ) { if (bits) { // fp = fopen("c:\\netchan.bin", "a"); for(i=0;i<bits;i+=8) { - Huff_offsetReceive (msgHuff.decompressor.tree, &get, msg->data, &msg->bit); + Huff_offsetReceive (msgHuff.decompressor.tree, &get, msg->data, &msg->bit, msg->cursize<<3); // fwrite(&get, 1, 1, fp); value |= (get<<(i+nbits)); + + if (msg->bit > msg->cursize<<3) { + // overflowed + msg->readcount = msg->cursize + 1; + return 0; + } } // fclose(fp); } |