diff options
author | James Dong <jdong@google.com> | 2011-03-13 12:41:43 -0700 |
---|---|---|
committer | James Dong <jdong@google.com> | 2011-03-14 10:13:03 -0700 |
commit | a2e29968abe003f1b92ea9cbff5e70c77f28be34 (patch) | |
tree | 068a89178a121d05c5605f14896d4f4bfd757d07 /media/libstagefright/codecs/aacdec/sbr_dec.cpp | |
parent | 718e64b17f72874996425b7ba9a187d473bc58f7 (diff) | |
download | frameworks_base-a2e29968abe003f1b92ea9cbff5e70c77f28be34.zip frameworks_base-a2e29968abe003f1b92ea9cbff5e70c77f28be34.tar.gz frameworks_base-a2e29968abe003f1b92ea9cbff5e70c77f28be34.tar.bz2 |
Fix PV AAC decoder crash due to out-of-boundary array access.
Two cases were fixed:
o xover had a larger number of bands than the high frequency band, which led to some negative array index under some circumstances
o integrated a PV fix from OpenCore.git where the array index for scratch_mem may be over the array boundary
bug - 3473128
Change-Id: I844cd8797b4e5b0120fafa0c46a8c1facea78a8b
Diffstat (limited to 'media/libstagefright/codecs/aacdec/sbr_dec.cpp')
-rw-r--r-- | media/libstagefright/codecs/aacdec/sbr_dec.cpp | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/media/libstagefright/codecs/aacdec/sbr_dec.cpp b/media/libstagefright/codecs/aacdec/sbr_dec.cpp index 8fcc3ce..8519b17 100644 --- a/media/libstagefright/codecs/aacdec/sbr_dec.cpp +++ b/media/libstagefright/codecs/aacdec/sbr_dec.cpp @@ -1,5 +1,5 @@ /* ------------------------------------------------------------------ - * Copyright (C) 1998-2009 PacketVideo + * Copyright (C) 1998-2010 PacketVideo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -447,7 +447,12 @@ void sbr_dec(Int16 *inPcmData, if (xoverBand > sbrDec->highSubband) { - xoverBand = 32; /* error condition, default to upsampling mode */ + /* + * error condition, default to upsampling mode + * and make sure that the number of bands for xover does + * not exceed the number of high freq bands. + */ + xoverBand = (sbrDec->highSubband > 32)? 32: sbrDec->highSubband; } m = sbrDec->bufReadOffs + i; /* 2 + i */ @@ -558,18 +563,22 @@ void sbr_dec(Int16 *inPcmData, /* * Set Circular buffer for PS hybrid analysis */ + + int32_t *pt_temp = &scratch_mem[2][32]; + for (i = 0, j = 0; i < 3; i++) { - pv_memmove(&scratch_mem[2][32 + j ], + pv_memmove(&pt_temp[ j], hParametricStereoDec->hHybrid->mQmfBufferReal[i], HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferReal)); - pv_memmove(&scratch_mem[2][32 + j + 44], + pv_memmove(&pt_temp[ j + 44], hParametricStereoDec->hHybrid->mQmfBufferImag[i], HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferImag)); j += 88; } + pv_memset((void *)&qmf_PS_generated_Real[hParametricStereoDec->usb], 0, (64 - hParametricStereoDec->usb)*sizeof(*qmf_PS_generated_Real)); @@ -626,19 +635,23 @@ void sbr_dec(Int16 *inPcmData, * Save Circular buffer history used on PS hybrid analysis */ + + pt_temp = &scratch_mem[2][64]; + for (i = 0, j = 0; i < 3; i++) { pv_memmove(hParametricStereoDec->hHybrid->mQmfBufferReal[i], - &scratch_mem[2][ 64 + j ], + &pt_temp[ j], HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferReal)); pv_memmove(hParametricStereoDec->hHybrid->mQmfBufferImag[i], - &scratch_mem[2][ 64 + j + 44], + &pt_temp[ j + 44], HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferImag)); j += 88; } + pv_memmove(hFrameData->V, &circular_buffer_s[0], 1152*sizeof(*circular_buffer_s)); /* @@ -746,7 +759,12 @@ void sbr_dec(Int16 *inPcmData, if (xoverBand > sbrDec->highSubband) { - xoverBand = 32; /* error condition, default to upsampling mode */ + /* + * error condition, default to upsampling mode + * and make sure that the number of bands for xover does + * not exceed the number of high freq bands. + */ + xoverBand = (sbrDec->highSubband > 32)? 32: sbrDec->highSubband; } } else |