Fix an msan issue in G722 decoder

If feeding an odd length payload to the G722 stereo decoder, the codec
would end up reading from uninitialized memory.

Bug: chromium:1302494
Change-Id: I2222377530fee31555e17a0c60ecf33261364b71
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/261303
Auto-Submit: Henrik Lundin <henrik.lundin@webrtc.org>
Reviewed-by: Minyue Li <minyue@google.com>
Commit-Queue: Henrik Lundin <henrik.lundin@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36810}
This commit is contained in:
Henrik Lundin
2022-05-05 17:02:44 +00:00
committed by WebRTC LUCI CQ
parent 77d987a724
commit 47a9e6e94e

View File

@ -89,16 +89,22 @@ int AudioDecoderG722StereoImpl::DecodeInternal(const uint8_t* encoded,
int16_t* decoded, int16_t* decoded,
SpeechType* speech_type) { SpeechType* speech_type) {
RTC_DCHECK_EQ(SampleRateHz(), sample_rate_hz); RTC_DCHECK_EQ(SampleRateHz(), sample_rate_hz);
// Adjust the encoded length down to ensure the same number of samples in each
// channel.
const size_t encoded_len_adjusted = PacketDuration(encoded, encoded_len) *
Channels() /
2; // 1/2 byte per sample per channel
int16_t temp_type = 1; // Default is speech. int16_t temp_type = 1; // Default is speech.
// De-interleave the bit-stream into two separate payloads. // De-interleave the bit-stream into two separate payloads.
uint8_t* encoded_deinterleaved = new uint8_t[encoded_len]; uint8_t* encoded_deinterleaved = new uint8_t[encoded_len_adjusted];
SplitStereoPacket(encoded, encoded_len, encoded_deinterleaved); SplitStereoPacket(encoded, encoded_len_adjusted, encoded_deinterleaved);
// Decode left and right. // Decode left and right.
size_t decoded_len = WebRtcG722_Decode(dec_state_left_, encoded_deinterleaved, size_t decoded_len =
encoded_len / 2, decoded, &temp_type); WebRtcG722_Decode(dec_state_left_, encoded_deinterleaved,
encoded_len_adjusted / 2, decoded, &temp_type);
size_t ret = WebRtcG722_Decode( size_t ret = WebRtcG722_Decode(
dec_state_right_, &encoded_deinterleaved[encoded_len / 2], dec_state_right_, &encoded_deinterleaved[encoded_len_adjusted / 2],
encoded_len / 2, &decoded[decoded_len], &temp_type); encoded_len_adjusted / 2, &decoded[decoded_len], &temp_type);
if (ret == decoded_len) { if (ret == decoded_len) {
ret += decoded_len; // Return total number of samples. ret += decoded_len; // Return total number of samples.
// Interleave output. // Interleave output.
@ -116,8 +122,10 @@ int AudioDecoderG722StereoImpl::DecodeInternal(const uint8_t* encoded,
int AudioDecoderG722StereoImpl::PacketDuration(const uint8_t* encoded, int AudioDecoderG722StereoImpl::PacketDuration(const uint8_t* encoded,
size_t encoded_len) const { size_t encoded_len) const {
// 1/2 encoded byte per sample per channel. // 1/2 encoded byte per sample per channel. Make sure the length represents
return static_cast<int>(2 * encoded_len / Channels()); // an equal number of bytes per channel. Otherwise, we cannot de-interleave
// the encoded data later.
return static_cast<int>(2 * (encoded_len / Channels()));
} }
int AudioDecoderG722StereoImpl::SampleRateHz() const { int AudioDecoderG722StereoImpl::SampleRateHz() const {