[gimp] gif: perform bounds checking for table entries
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] gif: perform bounds checking for table entries
- Date: Tue, 12 Oct 2021 16:46:06 +0000 (UTC)
commit c4b4363dfd77f40bc1eeff042b5295b27b33be68
Author: Andrzej Hunt <andrzej ahunt org>
Date: Fri Sep 10 19:15:17 2021 +0200
gif: perform bounds checking for table entries
table is specified to have 2 x (1<<12) entries, this in turn is because table
entries are specified to be smaller than (1<<12). Therefore we need to check
that each entry is within the specified range.
Without this check, it's possible to induce a buffer overflow read, see ASAN
output below. However the value that we read is eventually clamped to a
safe range before being returned, hence this overflow seems pretty useless:
==10977==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000010a21c0 at pc 0x00000056187b
bp 0x7ffec915c550 sp 0x7ffec915c548
READ of size 4 at 0x0000010a21c0 thread T0
#0 0x56187a in LZWReadByte /home/ahunt/git/gimp/plug-ins/common/file-gif-load.c:913:19
#1 0x55fc4d in ReadImage /home/ahunt/git/gimp/plug-ins/common/file-gif-load.c:1183:15
#2 0x55e447 in load_image /home/ahunt/git/gimp/plug-ins/common/file-gif-load.c
#3 0x561ef0 in LLVMFuzzerTestOneInput
/home/ahunt/git/gimp/plug-ins/common/file-gif-load_fuzzer.c:79:17
#4 0x460e44 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long)
/home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:599:15
#5 0x46034a in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*,
bool, bool*)
/home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:505:3
#6 0x462067 in fuzzer::Fuzzer::MutateAndTestOne()
/home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:745:19
#7 0x462bf5 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile,
fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&)
/home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:883:5
#8 0x450ea6 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long))
/home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:906:6
#9 0x47ae82 in main
/home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#10 0x7f307beb4349 in __libc_start_main (/lib64/libc.so.6+0x24349)
#11 0x424259 in _start /home/abuild/rpmbuild/BUILD/glibc-2.26/csu/../sysdeps/x86_64/start.S:120
0x0000010a21c0 is located 1088 bytes to the right of global variable 'table' defined in
'file-gif-load.c:794:15' (0x1099d80) of size 32768
SUMMARY: AddressSanitizer: global-buffer-overflow
/home/ahunt/git/gimp/plug-ins/common/file-gif-load.c:913:19 in LZWReadByte
Shadow bytes around the buggy address:
0x00008020c3e0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x00008020c3f0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x00008020c400: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x00008020c410: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x00008020c420: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
=>0x00008020c430: f9 f9 f9 f9 f9 f9 f9 f9[f9]f9 f9 f9 f9 f9 f9 f9
0x00008020c440: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x00008020c450: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x00008020c460: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x00008020c470: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x00008020c480: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
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
==10977==ABORTING
( crash-911d5feb07551dd0313d204db4883838139820f5 )
plug-ins/common/file-gif-load.c | 4 ++++
1 file changed, 4 insertions(+)
---
diff --git a/plug-ins/common/file-gif-load.c b/plug-ins/common/file-gif-load.c
index 9708a8af6e..a10438482e 100644
--- a/plug-ins/common/file-gif-load.c
+++ b/plug-ins/common/file-gif-load.c
@@ -914,6 +914,10 @@ LZWReadByte (FILE *fd,
while (code >= clear_code && sp < &(stack[STACK_SIZE]))
{
+ if (code >= (1 << MAX_LZW_BITS)) {
+ g_message ("Invalid table entry. Corrupt file.");
+ return -1;
+ }
*sp++ = table[1][code];
if (code == table[0][code])
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]