Skip to content
This repository has been archived by the owner on Jan 13, 2022. It is now read-only.

Fix for multiple security vulnerabilities in BitStream. #139

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions Source/BitStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ void BitStream::Write( BitStream *bitStream)
}
void BitStream::Write( BitStream *bitStream, BitSize_t numberOfBits )
{
if (numberOfBits > bitStream->GetNumberOfUnreadBits())
return;

AddBitsAndReallocate( numberOfBits );
BitSize_t numberOfBitsMod8;

Expand All @@ -205,7 +208,7 @@ void BitStream::Write( BitStream *bitStream, BitSize_t numberOfBits )
numberOfBitsUsed+=BYTES_TO_BITS(numBytes);
}

while (numberOfBits-->0 && bitStream->readOffset + 1 <= bitStream->numberOfBitsUsed)
while (numberOfBits-->0)
{
numberOfBitsMod8 = numberOfBitsUsed & 7;
if ( numberOfBitsMod8 == 0 )
Expand Down Expand Up @@ -274,7 +277,7 @@ bool BitStream::Read( char* outByteArray, const unsigned int numberOfBytes )
// Optimization:
if ((readOffset & 7) == 0)
{
if ( readOffset + ( numberOfBytes << 3 ) > numberOfBitsUsed )
if (GetNumberOfUnreadBits() < (numberOfBytes << 3))
return false;

// Write the data
Expand Down Expand Up @@ -331,6 +334,10 @@ void BitStream::Write1( void )
// Returns true if the next data read is a 1, false if it is a 0
bool BitStream::ReadBit( void )
{
if (GetNumberOfUnreadBits() == 0) {
return false;
}

bool result = ( data[ readOffset >> 3 ] & ( 0x80 >> ( readOffset & 7 ) ) ) !=0;
readOffset++;
return result;
Expand Down Expand Up @@ -378,7 +385,7 @@ bool BitStream::ReadAlignedBytes( unsigned char* inOutByteArray, const unsigned
// Byte align
AlignReadToByteBoundary();

if ( readOffset + ( numberOfBytesToRead << 3 ) > numberOfBitsUsed )
if (GetNumberOfUnreadBits() < (numberOfBytesToRead << 3))
return false;

// Write the data
Expand Down Expand Up @@ -556,7 +563,7 @@ bool BitStream::ReadBits( unsigned char *inOutByteArray, BitSize_t numberOfBitsT
if (numberOfBitsToRead<=0)
return false;

if ( readOffset + numberOfBitsToRead > numberOfBitsUsed )
if (GetNumberOfUnreadBits() < numberOfBitsToRead)
return false;


Expand Down Expand Up @@ -1038,7 +1045,7 @@ void BitStream::WriteAlignedVar8(const char *inByteArray)
bool BitStream::ReadAlignedVar8(char *inOutByteArray)
{
RakAssert((readOffset&7)==0);
if ( readOffset + 1*8 > numberOfBitsUsed )
if (GetNumberOfUnreadBits() < 1 * 8)
return false;

inOutByteArray[0] = data[( readOffset >> 3 ) + 0];
Expand Down Expand Up @@ -1067,7 +1074,7 @@ void BitStream::WriteAlignedVar16(const char *inByteArray)
bool BitStream::ReadAlignedVar16(char *inOutByteArray)
{
RakAssert((readOffset&7)==0);
if ( readOffset + 2*8 > numberOfBitsUsed )
if (GetNumberOfUnreadBits() < 2 * 8)
return false;
#ifndef __BITSTREAM_NATIVE_END
if (DoEndianSwap())
Expand Down Expand Up @@ -1111,7 +1118,7 @@ void BitStream::WriteAlignedVar32(const char *inByteArray)
bool BitStream::ReadAlignedVar32(char *inOutByteArray)
{
RakAssert((readOffset&7)==0);
if ( readOffset + 4*8 > numberOfBitsUsed )
if (GetNumberOfUnreadBits() < 4 * 8)
return false;
#ifndef __BITSTREAM_NATIVE_END
if (DoEndianSwap())
Expand Down
6 changes: 3 additions & 3 deletions Source/BitStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ namespace RakNet
void SetReadOffset( const BitSize_t newReadOffset ) {readOffset=newReadOffset;}

/// \brief Returns the number of bits left in the stream that haven't been read
inline BitSize_t GetNumberOfUnreadBits( void ) const {return numberOfBitsUsed - readOffset;}
inline BitSize_t GetNumberOfUnreadBits( void ) const { return readOffset > numberOfBitsUsed ? 0 : numberOfBitsUsed - readOffset; }

/// \brief Makes a copy of the internal data for you \a _data will point to
/// the stream. Partial bytes are left aligned.
Expand Down Expand Up @@ -1474,7 +1474,7 @@ namespace RakNet
template <>
inline bool BitStream::Read(bool &outTemplateVar)
{
if ( readOffset + 1 > numberOfBitsUsed )
if (GetNumberOfUnreadBits() == 0)
return false;

if ( data[ readOffset >> 3 ] & ( 0x80 >> ( readOffset & 7 ) ) ) // Is it faster to just write it out here?
Expand Down Expand Up @@ -1524,7 +1524,7 @@ namespace RakNet
inline bool BitStream::Read(uint24_t &outTemplateVar)
{
AlignReadToByteBoundary();
if ( readOffset + 3*8 > numberOfBitsUsed )
if (GetNumberOfUnreadBits() < 3 * 8)
return false;

if (IsBigEndian()==false)
Expand Down