From eb3ae0c18cc5f00256bfcfffa83cf769ef4b6cc4 Mon Sep 17 00:00:00 2001 From: olivier Date: Sun, 22 May 2022 19:11:43 +0200 Subject: [PATCH] Severe Remote Code Execution vulnerability #22 add partial fixes from https://github.com/macosforge/alac/issues/22 --- codec/ALACBitUtilities.c | 8 ++++++++ codec/ALACDecoder.cpp | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/codec/ALACBitUtilities.c b/codec/ALACBitUtilities.c index 9414889..6b95fda 100644 --- a/codec/ALACBitUtilities.c +++ b/codec/ALACBitUtilities.c @@ -37,6 +37,8 @@ void BitBufferInit( BitBuffer * bits, uint8_t * buffer, uint32_t byteSize ) bits->byteSize = byteSize; } +#define AssertBufferReadBounds(b, n) RequireAction( b->end >= (b->cur + ((b->bitIndex + n) / 8 + ((b->bitIndex + n) % 8 > 0))), return 0; ); + // BitBufferRead // uint32_t BitBufferRead( BitBuffer * bits, uint8_t numBits ) @@ -45,6 +47,8 @@ uint32_t BitBufferRead( BitBuffer * bits, uint8_t numBits ) //Assert( numBits <= 16 ); + AssertBufferReadBounds(bits, numBits) + returnBits = ((uint32_t)bits->cur[0] << 16) | ((uint32_t)bits->cur[1] << 8) | ((uint32_t)bits->cur[2]); returnBits = returnBits << bits->bitIndex; returnBits &= 0x00FFFFFF; @@ -69,6 +73,8 @@ uint8_t BitBufferReadSmall( BitBuffer * bits, uint8_t numBits ) uint16_t returnBits; //Assert( numBits <= 8 ); + + AssertBufferReadBounds(bits, numBits) returnBits = (bits->cur[0] << 8) | bits->cur[1]; returnBits = returnBits << bits->bitIndex; @@ -92,6 +98,8 @@ uint8_t BitBufferReadOne( BitBuffer * bits ) { uint8_t returnBits; + AssertBufferReadBounds(bits, 8) + returnBits = (bits->cur[0] >> (7 - bits->bitIndex)) & 1; bits->bitIndex++; diff --git a/codec/ALACDecoder.cpp b/codec/ALACDecoder.cpp index ce3340d..e6b2dc0 100644 --- a/codec/ALACDecoder.cpp +++ b/codec/ALACDecoder.cpp @@ -129,7 +129,12 @@ int32_t ALACDecoder::Init( void * inMagicCookie, uint32_t inMagicCookieSize ) mConfig = theConfig; + // sanity checks RequireAction( mConfig.compatibleVersion <= kALACVersion, return kALAC_ParamError; ); + RequireAction(mConfig.bitDepth == 16 || mConfig.bitDepth == 20 || mConfig.bitDepth == 24 || mConfig.bitDepth == 32, return kALAC_ParamError; ); + RequireAction(mConfig.frameLength > 0 && mConfig.frameLength <= 16384, return kALAC_ParamError; ); + RequireAction(mConfig.sampleRate > 0 && mConfig.sampleRate <= 384000, return kALAC_ParamError; ); + RequireAction(mConfig.numChannels > 0 && mConfig.numChannels < kALACMaxChannels, return kALAC_ParamError; ); // allocate mix buffers mMixBufferU = (int32_t *) calloc( mConfig.frameLength * sizeof(int32_t), 1 ); @@ -251,6 +256,8 @@ int32_t ALACDecoder::Decode( BitBuffer * bits, uint8_t * sampleBuffer, uint32_t { numSamples = BitBufferRead( bits, 16 ) << 16; numSamples |= BitBufferRead( bits, 16 ); + + RequireAction(numSamples <= mConfig.frameLength, status = kALAC_ParamError; goto Exit; ); } if ( escapeFlag == 0 ) @@ -402,6 +409,8 @@ int32_t ALACDecoder::Decode( BitBuffer * bits, uint8_t * sampleBuffer, uint32_t { numSamples = BitBufferRead( bits, 16 ) << 16; numSamples |= BitBufferRead( bits, 16 ); + + RequireAction(numSamples <= mConfig.frameLength, status = kALAC_ParamError; goto Exit; ); } if ( escapeFlag == 0 )