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:

committed by
WebRTC LUCI CQ

parent
77d987a724
commit
47a9e6e94e
@ -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 {
|
||||||
|
Reference in New Issue
Block a user