Closed W4terf1re closed 1 month ago
I'll make sure to dive into this matter as soon as my schedule permits. Thank you for bringing it to my attention!
A simple way to fix the bug is adding a size check like this
if((size_t)(width * height * 4) >= 0x80000000){
// error message
exit(0);
}
By the way, the allocation in function stbi_write_png_to_mem
seems to have the same problem:
filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0;
line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; }
They can be fixed by the same way.
code:
#include <plutosvg.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
plutovg_surface_t* surface = plutosvg_load_from_file(argv[1], NULL, 0, 0, 96.0);
if(surface == NULL)
{
printf("Load failed\n");
return -1;
}
plutovg_surface_write_to_png(surface, "test.png");
plutovg_surface_destroy(surface);
return 0;
}
ASAN report
=================================================================
==32443==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000191 at pc 0x555555582f20 bp 0x7fffffffd740 sp 0x7fffffffd730
READ of size 1 at 0x602000000191 thread T0
#0 0x555555582f1f in stbiw__encode_png_line (/home/waterfire/fuzz/example/plutosvg/build/example/example_asan+0x2ef1f)
#1 0x555555583ff8 in stbi_write_png_to_mem (/home/waterfire/fuzz/example/plutosvg/build/example/example_asan+0x2fff8)
#2 0x5555555852cd in stbi_write_png (/home/waterfire/fuzz/example/plutosvg/build/example/example_asan+0x312cd)
#3 0x55555558950a in plutovg_surface_write_to_png (/home/waterfire/fuzz/example/plutosvg/build/example/example_asan+0x3550a)
#4 0x55555556408b in main (/home/waterfire/fuzz/example/plutosvg/build/example/example_asan+0x1008b)
#5 0x7ffff66aac86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86)
#6 0x555555563f19 in _start (/home/waterfire/fuzz/example/plutosvg/build/example/example_asan+0xff19)
0x602000000191 is located 0 bytes to the right of 1-byte region [0x602000000190,0x602000000191)
allocated by thread T0 here:
#0 0x7ffff6ef6b40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40)
#1 0x555555589232 in plutovg_surface_write_to_png (/home/waterfire/fuzz/example/plutosvg/build/example/example_asan+0x35232)
#2 0x55555556408b in main (/home/waterfire/fuzz/example/plutosvg/build/example/example_asan+0x1008b)
#3 0x7ffff66aac86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/waterfire/fuzz/example/plutosvg/build/example/example_asan+0x2ef1f) in stbiw__encode_png_line
Shadow bytes around the buggy address:
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff8000: fa fa fd fd fa fa fd fd fa fa 01 fa fa fa fd fd
0x0c047fff8010: fa fa fd fd fa fa fd fa fa fa fd fa fa fa fd fa
0x0c047fff8020: fa fa fd fd fa fa fd fa fa fa fd fa fa fa fd fa
=>0x0c047fff8030: fa fa[01]fa fa fa 00 01 fa fa 01 fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8080: 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
==32443==ABORTING
The poc does not cause segment fault, but can trigger heap overflow.
The allocation size of line_buffer
is overflowed to 0
, and the heap overflow is triggered in stbiw__encode_png_line
when writing to line_buffer
.
poc_heap_overflow.zip
@W4terf1re Resolved in the latest commit. Thank you for bringing this issue to our attention.
Summary
An integer overflow in the allocated size of
calloc
causes a segment fault. It might lead to heap overflow and arbitrary code execution.Steps to reproduce
code:
run
ASAN report
Analysis
plutosvg_load_from_memory
does not check the size ofwidth
andheight
and callsplutovg_surface_create(width, height);
. In plutovg_surface_create:An integer overflow might happen when calculating
width * height * 4
. It might be better to check the sizes ofwidth
andheight
before the allocation.PoC
poc.zip