SEGV In GifDestroy At Ngiflib.c:57
Introduction
The ngiflib library is a widely used library for handling GIF images. However, a critical bug has been discovered in the GifDestroy function, which can lead to a segmentation fault (SEGV) when dealing with a specific ngiflib_gif structure. In this article, we will delve into the details of this bug, its cause, and how to trigger it.
Description of the Bug
When using the GifDestroy function to handle a specific ngiflib_gif structure, a segmentation fault (SEGV) is triggered at GifDestroy in ngiflib.c:57. The cause of this bug is that the passed ngiflib_gif structure is not properly checked. If g->palette incorrectly points to an inaccessible address, the statement g->palette at line 57 in the GifDestroy function will result in a segmentation fault.
GifDestroy Function in ngiflib.c
The GifDestroy function in ngiflib.c is responsible for freeing the resources allocated by the GifImgDestroy function. The function takes a pointer to an ngiflib_gif structure as an argument and frees the memory allocated for the palette, frame buffer, and the ngiflib_gif structure itself.
void GifDestroy(struct ngiflib_gif * g) {
if(g==NULL) return;
GifImgDestroy(g->first_img);
if(g->palette) ngiflib_free(g->palette);
if(g->frbuff.p8) ngiflib_free(g->frbuff.p8);
ngiflib_free(g);
}
Test Environment
The bug was discovered on an Ubuntu 24.04.1, 64-bit system using the ngiflib library with the commit hash fbf2d0c3b7b70122a89a82fad5dcdd47d89be770. The test program was compiled and run on the same system.
How to Trigger the Bug
To trigger the bug, you can download the poc file and program from the GitHub repository and run the following command:
$ ./GifImgDestroy ./poc2
GDB Report
The GDB report provides valuable information about the bug. The report shows that the program received a signal SIGSEGV, which indicates a segmentation fault. The backtrace shows that the segmentation fault occurred in the GifDestroy function at line 57.
(gdb) r
Starting program: /home/ambrose/vsproject/HIMFuzz/harness/output/ngiflib_deepseek24/crashes2/ngiflib.c/GifDestroy/GifImgDestroy/GifImgDestroy ./output/default/crashes/id:000001,sig:11,src:000002,time:3905,execs:4588,op:havoc,rep:52
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7ca53fe in __GI___libc_free (mem=0xe8e8e8e8e8e803e8) at ./malloc/malloc.c:3368
3368 ./malloc/malloc.c: No such file or directory.
(gdb) bt
#0 0x00007ffff7ca53fe in __GI___libc_free (mem=0xe8e8e8e8e8e803e8) at ./malloc/malloc.c:3368
#1 0x00005555555555c0 in GifDestroy (g=g@entry=0x7fffffffd950) at /home/ambrose/vsproject/TestLib/ngiflib/ngiflib.c:57
#2 0x0000555555556ae6 in main (argc=<optimised out>, argv=0x7fffffffdad8)
at /home/ambrose/vsproject/HIMFuzz/harness/output/ngiflib_deepseek/harness/code/ngiflib.c/GifDestroy/GifImgDestroy.c:31
(gdb) frame 1
#1 0x00005555555555c0 in GifDestroy (g=g@entry=0x7fffffffd950) at /home/ambrose/vsproject/TestLib/ngiflib/ngiflib.c:57
57 if(g->palette) ngiflib_free(g->palette);
(gdb) p *g
$2 = {first_img = 0x0, cur_img = 0x1b00100110100078, palette = 0xe8e8e8e8e8e803e8, input = {file = 0x10000010e2e8, buffer = {
bytes = 0x10000010e2e8 <error: Cannot access memory at address 0x10000010e2e8>, count = 16782919098093797376}},
frbuff = {p8 = 0x2000e8e8e8e803e9 <error: Cannot access memory at address 0x2000e8e8e8e803e9>, p32 = 0x2000e8e8e8e803e9},
log = 0x36e41b1b565d06, nimg = 1105152, netscape_loop_count = 5376, ncolors = 0, width = 0, height = 0,
backgroundindex = 0 '\000', pixaspectratio = 0 '\000', imgbits = 0 '\000', colorresolution = 0 '\000',
sort_flag = 0 '\000', mode = 0 '\000', signature = "\000\377\377\000\000\000"}
(gdb) p g->palette
$3 = (struct ngiflib_rgb *) 0xe8e8e8e8e8e803e8
Conclusion
Q: What is the SEGV in GifDestroy at ngiflib.c:57?
A: The SEGV in GifDestroy at ngiflib.c:57 is a segmentation fault that occurs when the GifDestroy function is called with a specific ngiflib_gif structure. This bug is caused by the fact that the passed ngiflib_gif structure is not properly checked, and if g->palette incorrectly points to an inaccessible address, the statement g->palette at line 57 in the GifDestroy function will result in a segmentation fault.
Q: What is the cause of the SEGV in GifDestroy at ngiflib.c:57?
A: The cause of the SEGV in GifDestroy at ngiflib.c:57 is that the passed ngiflib_gif structure is not properly checked. If g->palette incorrectly points to an inaccessible address, the statement g->palette at line 57 in the GifDestroy function will result in a segmentation fault.
Q: How can I trigger the SEGV in GifDestroy at ngiflib.c:57?
A: To trigger the SEGV in GifDestroy at ngiflib.c:57, you can download the poc file and program from the GitHub repository and run the following command:
$ ./GifImgDestroy ./poc2
Q: What is the GDB report for the SEGV in GifDestroy at ngiflib.c:57?
A: The GDB report for the SEGV in GifDestroy at ngiflib.c:57 shows that the program received a signal SIGSEGV, which indicates a segmentation fault. The backtrace shows that the segmentation fault occurred in the GifDestroy function at line 57.
(gdb) r
Starting program: /home/ambrose/vsproject/HIMFuzz/harness/output/ngiflib_deepseek24/crashes2/ngiflib.c/GifDestroy/GifImgDestroy/GifImgDestroy ./output/default/crashes/id:000001,sig:11,src:000002,time:3905,execs:4588,op:havoc,rep:52
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7ca53fe in __GI___libc_free (mem=0xe8e8e8e8e8e803e8) at ./malloc/malloc.c:3368
3368 ./malloc/malloc.c: No such file or directory.
(gdb) bt
#0 0x00007ffff7ca53fe in __GI___libc_free (mem=0xe8e8e8e8e8e803e8) at ./malloc/malloc.c:3368
#1 0x00005555555555c0 in GifDestroy (g=g@entry=0x7fffffffd950) at /home/ambrose/vsproject/TestLib/ngiflib/ngiflib.c:57
#2 0x0000555555556ae6 in main (argc=<optimised out>, argv=0x7fffffffdad8)
at /home/ambrose/vsproject/HIMFuzz/harness/output/ngiflib_deepseek/harness/code/ngiflib.c/GifDestroy/GifImgDestroy.c:31
(gdb) frame 1
#1 0x00005555555555c0 in GifDestroy (g=g@entry=0x7fffffffd950) at /home/ambrose/vsproject/TestLib/ngiflib/ngiflib.c:57
57 if(g->palette) ngiflib_free(g->palette);
(gdb) p *g
$2 = {first_img = 0x0, cur_img = 0x1b00100110100078, palette = 0xe8e8e8e8e8e803e8, input = {file = 0x10000010e2e8, buffer = {
bytes = 0x10000010e2e8 <error: Cannot access memory at address 0x10000010e2e8>, count = 16782919098093797376}},
frbuff = {p8 = 0x2000e8e8e8e803e9 <error: Cannot access memory at address 0x2000e8e8e8e803e9>, p32 = 0x2000e8e8e8e803e9},
log = 0x36e41b1b565d06, nimg = 1105152, netscape_loop_count = 5376, ncolors = 0, width = 0, height = 0,
backgroundindex = 0 '\000', pixaspectratio = 0 '\000', imgbits = 0 '\000', colorresolution = 0 '\000',
sort_flag = 0 '\000', mode = 0 '\000', signature = "\000\377\377\000\000\000"}
(gdb) p g->palette
$3 = (struct ngiflib_rgb *) 0xe8e8e8e8e8e803e8
Q: How can I fix the SEGV in GifDestroy at ngiflib.c:57?
A: To fix the SEGV in GifDestroy at ngiflib.c:57, you can modify the ngiflib library to properly check the passed ngiflib_gif structure before freeing its resources. This can be done by adding a check to ensure that g->palette is not null before freeing it.
void GifDestroy(struct ngiflib_gif * g) {
if(g==NULL) return;
GifImgDestroy(g->first_img);
if(g->palette != NULL) ngiflib_free(g->palette);
if(g->frbuff.p8) ngiflib_free(g->frbuff.p8);
ngiflib_free(g);
}
Q: What are the implications of the SEGV in GifDestroy at ngiflib.c:57?
A: The implications of the SEGV in GifDestroy at ngiflib.c:57 are that it can cause a segmentation fault when the GifDestroy function is called with a specific ngiflib_gif structure. This can lead to a crash of the program and potentially cause data corruption or other issues.