From 7f973d8726ed1bde875f66d773453ffb0c09bcb7 Mon Sep 17 00:00:00 2001 From: Cheney Ni Date: Sun, 12 Apr 2020 05:19:31 +0800 Subject: [PATCH] A2DP: Fix integer sanitizer in SBC encoder MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit There were three potential integer overflow within SBC software encoder: * embdrv/sbc/encoder/srce/sbc_packing.c:144:38: runtime error: unsigned integer overflow: 4294967231 + 8192 cannot be represented in type 'unsigned int' * embdrv/sbc/encoder/srce/sbc_packing.c:147:9: runtime error: signed integer overflow: 37932 * 65535 cannot be represented in type 'int' * embdrv/sbc/encoder/srce/sbc_packing.c:147:9: runtime error: signed integer overflow: 178177545 + 2146959360 cannot be represented in type 'int' They were caught by the integer sanitizer, and 1. (*ps32SbPtr >> 2) is either greater than 0xFF00,0000 or less than 0x007F,FFFF, so just cast to a signed integer explicitly. 2. Positive integer between 0x8000,0000 ~ 0xFFFF,FFFF can't be represented in type 'int', but is still feasible in 32-bits. 3. s32OutLow is the lower byte of a 64 bits integer, but can't have the carry values which is only for the higher byte. This change gives the compiler a signed 64-bits variable, and trusts it to do better optimization at multiplication. Bug: 153402404 Test: make sure there are no integer sanitization errors. Change-Id: I5046a42f9927c1aa7c25da2828c4f921ba7a5021 Merged-In: I5046a42f9927c1aa7c25da2828c4f921ba7a5021 (cherry picked from commit a42db783434da238e4daade95ce2adb1bca0f138) --- embdrv/sbc/encoder/srce/sbc_packing.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/embdrv/sbc/encoder/srce/sbc_packing.c b/embdrv/sbc/encoder/srce/sbc_packing.c index b478a8084..205b3737a 100644 --- a/embdrv/sbc/encoder/srce/sbc_packing.c +++ b/embdrv/sbc/encoder/srce/sbc_packing.c @@ -28,26 +28,22 @@ #if (SBC_ARM_ASM_OPT == TRUE) #define Mult32(s32In1, s32In2, s32OutLow) \ { \ - __asm { \ + __asm { \ MUL s32OutLow,s32In1,s32In2; } \ } #define Mult64(s32In1, s32In2, s32OutLow, s32OutHi) \ { \ - __asm { \ + __asm { \ SMULL s32OutLow,s32OutHi,s32In1,s32In2 } \ } #else #define Mult32(s32In1, s32In2, s32OutLow) \ s32OutLow = (int32_t)(s32In1) * (int32_t)(s32In2); -#define Mult64(s32In1, s32In2, s32OutLow, s32OutHi) \ - { \ - (s32OutLow) = ((int32_t)(uint16_t)(s32In1) * (uint16_t)(s32In2)); \ - s32TempVal2 = (int32_t)(((s32In1) >> 16) * (uint16_t)(s32In2)); \ - s32Carry = ((((uint32_t)(s32OutLow) >> 16) & 0xFFFF) + \ - +(s32TempVal2 & 0xFFFF)) >> \ - 16; \ - (s32OutLow) += (s32TempVal2 << 16); \ - (s32OutHi) = (s32TempVal2 >> 16) + s32Carry; \ +#define Mult64(s32In1, s32In2, s32OutLow, s32OutHi) \ + { \ + __builtin_mul_overflow(s32In1, (uint16_t)s32In2, &s64OutTemp); \ + s32OutLow = s64OutTemp & 0xFFFFFFFF; \ + s32OutHi = (s64OutTemp >> 32) & 0xFFFFFFFF; \ } #endif @@ -77,7 +73,10 @@ uint32_t EncPacking(SBC_ENC_PARAMS* pstrEncParams, uint8_t* output) { int32_t s32Temp1; /*used in 64-bit multiplication*/ int32_t s32Low; /*used in 64-bit multiplication*/ #if (SBC_IS_64_MULT_IN_QUANTIZER == TRUE) - int32_t s32Hi1, s32Low1, s32Carry, s32TempVal2, s32Hi, s32Temp2; + int32_t s32Hi1, s32Low1, s32Hi, s32Temp2; +#if (SBC_ARM_ASM_OPT != TRUE) + int64_t s64OutTemp; +#endif #endif pu8PacketPtr = output; /*Initialize the ptr*/ @@ -141,7 +140,7 @@ uint32_t EncPacking(SBC_ENC_PARAMS* pstrEncParams, uint8_t* output) { u16Levels = (uint16_t)(((uint32_t)1 << s32LoopCount) - 1); /* quantizer */ - s32Temp1 = (*ps32SbPtr >> 2) + (u32SfRaisedToPow2 << 12); + s32Temp1 = (*ps32SbPtr >> 2) + (int32_t)(u32SfRaisedToPow2 << 12); s32Temp2 = u16Levels; Mult64(s32Temp1, s32Temp2, s32Low, s32Hi); -- 2.11.0