diff options
author | Mikkel Krautz <mikkel@krautz.dk> | 2014-01-29 01:58:06 +0400 |
---|---|---|
committer | Mikkel Krautz <mikkel@krautz.dk> | 2014-01-29 02:17:03 +0400 |
commit | fd190328a9b24d37382b269a5674b0c0c7a7e36d (patch) | |
tree | 8174debb6aeb9627c3a89f6b2533424b431abbdd | |
parent | 39b28a082ddc02d0c336fff31590960106085a4c (diff) |
MKAudioOutputSpeech: fix handling of malformed Opus packets.
This commit fixes two issues with the handling of malformed
Opus packets.
1. A malformed Opus packet could trigger a NULL pointer
dereference.
2. A malformed Opus packet could trigger a heap-based
buffer overflow.
-rw-r--r-- | src/MKAudioOutputSpeech.m | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/src/MKAudioOutputSpeech.m b/src/MKAudioOutputSpeech.m index 8a54663..3b867df 100644 --- a/src/MKAudioOutputSpeech.m +++ b/src/MKAudioOutputSpeech.m @@ -201,6 +201,11 @@ NSUInteger size = (header & ((1 << 13) - 1)); if (size > 0) { NSData *opusFrames = [pds copyDataBlock:size]; + if ([opusFrames length] != size || ![pds valid]) { + [pds release]; + [_jitterLock unlock]; + return; + } int nframes = opus_packet_get_nb_frames([opusFrames bytes], size); samples = nframes * opus_packet_get_samples_per_frame([opusFrames bytes], SAMPLE_RATE); [opusFrames release]; @@ -308,8 +313,10 @@ _hasTerminator = header & (1 << 13); if (size > 0) { NSData *block = [pds copyDataBlock:size]; - [_frames addObject:block]; - [block release]; + if (block != nil) { + [_frames addObject:block]; + [block release]; + } } } else { unsigned int header = 0; @@ -317,8 +324,10 @@ header = (unsigned int)[pds next]; if (header) { NSData *block = [pds copyDataBlock:(header & 0x7f)]; - [_frames addObject:block]; - [block release]; + if (block != nil) { + [_frames addObject:block]; + [block release]; + } } else { _hasTerminator = YES; } @@ -360,6 +369,10 @@ if (_msgType == UDPVoiceOpusMessage) { decodedSamples = opus_decode_float(_opusDecoder, [frameData bytes], [frameData length], output, _audioBufferSize, 0); + if (decodedSamples < 0) { + decodedSamples = _frameSize; + memset(output, 0, _frameSize * sizeof(float)); + } } else if (_msgType == UDPVoiceSpeexMessage) { if ([frameData length] == 0) { speex_decode(_speexDecoder, NULL, output); |