gimp/SOURCES/gimp-CVE-2026-58379.patch
2026-07-13 20:49:54 -04:00

74 lines
3.2 KiB
Diff

From a2ea43a6a1d265c89f203cbad9adafa7d5ba5b4d Mon Sep 17 00:00:00 2001
From: Jacob Boerema <jgboerema@gmail.com>
Date: Wed, 22 Apr 2026 11:09:36 -0400
Subject: [PATCH] plug-ins: Fix #16205 PSP File Parsing Heap Buffer Overflow
A heap buffer overflow write vulnerability exists in GIMP's PSP file
format parser. When parsing a specially crafted .psp file, the
read_channel_data() function in file-psp.c writes beyond the bounds of
a heap-allocated buffer due to an inconsistency between the buffer
allocation size (line_width) and the read size (width). Opening a
crafted PSP file causes memory corruption during parsing.
The first part of the fix corrects the computation of the line_width,
which was incorrect for 1-bit per pixel. Since it needs to be on a
4 byte boundary, always add 3 instead of depending on bit depth.
Second, use the line_width instead of width to determine the number
of bytes to read and process because that is the correct number to use.
---
plug-ins/common/file-psp.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/plug-ins/common/file-psp.c b/plug-ins/common/file-psp.c
index 0dd6ff27a1..61259e1e76 100644
--- a/plug-ins/common/file-psp.c
+++ b/plug-ins/common/file-psp.c
@@ -1530,7 +1530,7 @@ upscale_indexed_sub_8 (FILE *f,
guchar *tmpbuf, *buf_start, *src;
/* Scanlines for 1 and 4 bit only end on a 4-byte boundary. */
- line_width = (((width * bpp + 7) / 8) + bpp_zero_based) / 4 * 4;
+ line_width = (((width * bpp + 7) / 8) + 3) / 4 * 4;
buf_start = g_malloc0 (width * height);
tmpbuf = buf_start;
@@ -1576,7 +1576,7 @@ read_channel_data (FILE *f,
if (ia->depth < 8)
{
/* Scanlines for 1 and 4 bit only end on a 4-byte boundary. */
- line_width = (((width * ia->depth + 7) / 8) + ia->depth - 1) / 4 * 4;
+ line_width = ((width * ia->depth + 7) / 8 + 3) / 4 * 4;
}
else
{
@@ -1599,12 +1599,17 @@ read_channel_data (FILE *f,
{
guchar *p, *q;
- fread (buf, width, 1, f);
+ if (fread (buf, 1, line_width, f) != line_width)
+ {
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ _("Error reading data. Most likely unexpected end of file."));
+ return -1;
+ }
/* Contrary to what the PSP specification seems to suggest
scanlines are not stored on a 4-byte boundary. */
p = buf;
q = pixels[y] + offset;
- for (i = 0; i < width; i++)
+ for (i = 0; i < line_width; i++)
{
*q = *p++;
q += bytespp;
@@ -2097,7 +2102,7 @@ read_layer_block (FILE *f,
if (ia->depth < 8)
{
- gint min_line_width = (((width * ia->depth + 7) / 8) + (ia->depth - 1)) / 4 * 4;
+ gint min_line_width = (((width * ia->depth + 7) / 8) + 3) / 4 * 4;
/* For small widths, when depth is 1, or 4, the number of bytes
* used can be larger than the width * bytespp. Adjust for that. */