Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fec73058 authored by Cheney Ni's avatar Cheney Ni
Browse files

A2DP: Fix integer sanitizer in SBC encoder

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)
parent b0aa88f0
Loading
Loading
Loading
Loading
+12 −13
Original line number Diff line number Diff line
@@ -41,13 +41,9 @@
  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;                      \
    __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);