This patch fixes 4 integer overflow vulnerabilities in giflib's core library and adds security testing infrastructure (sanitizer build targets + libFuzzer harness).
GifApplyTranslation (gifalloc.c:214)Height * Width is computed as int (signed 32-bit). For images where the product exceeds INT_MAX, this is undefined behavior per C99 §6.5/5.
UBSan trace on unpatched giflib 6.1.2:
gifalloc.c:214:15: runtime error: signed integer overflow:
46341 * 46341 cannot be represented in type 'int'
The loop bound RasterSize gets an unpredictable value due to UB, corrupting pixel translation. Fixed by using size_t with a new GifSafeMult() overflow-checked multiplication helper.
GifMakeSavedImage (gifalloc.c:372-384)Two independent overflow sites in the same function:
reallocarray(NULL, (Height * Width), sizeof(GifPixelType)) — the Height * Width multiplication happens in int arithmetic before being passed to reallocarray, defeating its overflow protection entirely. The overflowed int is implicitly converted to size_t, producing a wrong allocation size.
memcpy(dst, src, sizeof(GifPixelType) * Height * Width) — computes the copy size independently, also in int arithmetic. The memcpy size does not match the allocation size — on overflow, memcpy writes past the allocated buffer → heap buffer overflow.
Fixed by computing the size once with GifSafeMult() and using it for both allocation and copy. On overflow, the function returns NULL instead of allocating a wrong-sized buffer.
PixelCount overflow on 32-bit systems (dgif_lib.c:418, egif_lib.c:451)(long)Width * (long)Height overflows signed long on 32-bit platforms where long is 32 bits. For example: 65535 × 65535 = 4,294,836,225 > LONG_MAX (2,147,483,647) on 32-bit.
PixelCount gets a wrong value, causing the decoder/encoder to process the wrong number of pixels. Fixed by casting to size_t and changing the PixelCount field type from unsigned long to size_t.
Note:
PixelCountis inGifFilePrivateType(private headergif_lib_private.h), not the public API. Users access it throughvoid *PrivateinGifFileType. This is not an ABI break.
quantize.cmalloc(sizeof(QuantizedColorType *) * NumEntries) replaced with reallocarray(NULL, NumEntries, sizeof(QuantizedColorType *)) for consistent overflow-safe allocation.
GifSafeMult() — overflow-checked size_t multiplication helper in gif_lib_private.hmake check-asan, make check-ubsan, make check-sanitizersfuzz/gif_fuzz_dgif.c for the DGifSlurp decode pathMakefile | 18 changes
dgif_lib.c | 4 changes
egif_lib.c | 2 changes
gif_lib_private.h | 15 changes
gifalloc.c | 41 changes
quantize.c | 6 changes
fuzz/gif_fuzz_dgif.c | 63 lines (new file)
.gitignore | 2 lines (new file)
Patch attached. Apply with:
git am giflib-security-hardening.patch