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

Commit 7b126f34 authored by Joseph Pirozzo's avatar Joseph Pirozzo
Browse files

Fix potential OOB vulnerability when SBC framedata is prefetched

Macros were filling a value buffer when reading bit stream data in
advance of any fetch being called, updated to only fetch data into
buffer when needed.

Bug: 110107252
Bug: 146032016
Bug: 146398979
Test: sbcdecoder_fuzzer
Change-Id: Ibb7793c9a015eaddcc8faa6ccfd8ec998d03ed86
parent d509d76d
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -78,17 +78,18 @@ PRIVATE void OI_BITSTREAM_Write2xUINT4Aligned(OI_BITSTREAM* bs, uint8_t datum1,
#define OI_BITSTREAM_READUINT(result, bits, ptr, value, bitPtr) \
  do {                                                          \
    OI_ASSERT((bits) <= 16);                                    \
    OI_ASSERT((bitPtr) < 16);                                   \
    OI_ASSERT((bitPtr) >= 8);                                   \
    OI_ASSERT((bitPtr) < 32);                                   \
    OI_ASSERT((bitPtr) >= 0);                                   \
                                                                \
    while ((bitPtr + bits) > 32) {                              \
      (value) = ((value) << 8) | *(ptr)++;                      \
      (bitPtr) -= 8;                                            \
    }                                                           \
                                                                \
    (result) = (value) << (bitPtr);                             \
    (result) >>= 32 - (bits);                                   \
                                                                \
    (bitPtr) += (bits);                                         \
    while ((bitPtr) >= 16) {                                    \
      (value) = ((value) << 8) | *(ptr)++;                      \
      (bitPtr) -= 8;                                            \
    }                                                           \
    OI_ASSERT(((bits) == 0) || ((result) < (1u << (bits))));    \
  } while (0)

+3 −4
Original line number Diff line number Diff line
@@ -39,10 +39,9 @@ Functions for manipulating input bitstreams.
#include "oi_stddefs.h"

PRIVATE void OI_BITSTREAM_ReadInit(OI_BITSTREAM* bs, const OI_BYTE* buffer) {
  bs->value =
      ((int32_t)buffer[0] << 16) | ((int32_t)buffer[1] << 8) | (buffer[2]);
  bs->ptr.r = buffer + 3;
  bs->bitPtr = 8;
  bs->value = 0;
  bs->ptr.r = buffer;
  bs->bitPtr = 32;
}

PRIVATE uint32_t OI_BITSTREAM_ReadUINT(OI_BITSTREAM* bs, OI_UINT bits) {
+14 −32
Original line number Diff line number Diff line
@@ -180,34 +180,17 @@ PRIVATE void OI_SBC_ReadSamples(OI_CODEC_SBC_DECODER_CONTEXT* context,
  OI_CODEC_SBC_COMMON_CONTEXT* common = &context->common;
  OI_UINT nrof_blocks = common->frameInfo.nrof_blocks;
  int32_t* RESTRICT s = common->subdata;
  uint8_t* ptr = global_bs->ptr.w;
  const uint8_t* ptr = global_bs->ptr.r;
  uint32_t value = global_bs->value;
  OI_UINT bitPtr = global_bs->bitPtr;

  const OI_UINT iter_count =
      common->frameInfo.nrof_channels * common->frameInfo.nrof_subbands / 4;
      common->frameInfo.nrof_channels * common->frameInfo.nrof_subbands;
  do {
    OI_UINT i;
    for (i = 0; i < iter_count; ++i) {
      uint32_t sf_by4 = ((uint32_t*)common->scale_factor)[i];
      uint32_t bits_by4 = common->bits.uint32[i];
    OI_UINT n;
      for (n = 0; n < 4; ++n) {
    for (n = 0; n < iter_count; ++n) {
      int32_t dequant;
        OI_UINT bits;
        OI_INT sf;

        if (OI_CPU_BYTE_ORDER == OI_LITTLE_ENDIAN_BYTE_ORDER) {
          bits = bits_by4 & 0xFF;
          bits_by4 >>= 8;
          sf = sf_by4 & 0xFF;
          sf_by4 >>= 8;
        } else {
          bits = (bits_by4 >> 24) & 0xFF;
          bits_by4 <<= 8;
          sf = (sf_by4 >> 24) & 0xFF;
          sf_by4 <<= 8;
        }
      OI_UINT bits = common->bits.uint8[n];
      OI_INT sf = common->scale_factor[n];
      if (bits) {
        uint32_t raw;
        OI_BITSTREAM_READUINT(raw, bits, ptr, value, bitPtr);
@@ -217,7 +200,6 @@ PRIVATE void OI_SBC_ReadSamples(OI_CODEC_SBC_DECODER_CONTEXT* context,
      }
      *s++ = dequant;
    }
    }
  } while (--nrof_blocks);
}