diff --git a/CVE-2025-48797-1.patch b/CVE-2025-48797-1.patch new file mode 100644 index 0000000000000000000000000000000000000000..3382ba61342d56430dc2145fb354049ddc8b35dd --- /dev/null +++ b/CVE-2025-48797-1.patch @@ -0,0 +1,123 @@ +From 49755f085a6fcc9c692b14e67856e91a79245688 Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Tue, 16 Jul 2024 18:30:21 +0200 +Subject: [PATCH] tga: always convert colour-mapped images to RGBA if image + claims to contain alpha + +Origin: https://gitlab.gnome.org/GNOME/gimp/-/commit/49755f085a6fcc9c692b14e67856e91a79245688 + +If the colourmap contains more than 256 items AND has alpha, it should always +be promoted to RGBA. Therefore we move the "if (info->alphaBits)" check into +the first if clause, to avoid accidentally demoting to RGB in this scenario. + +Other parts of the tga parser assume that the destination array is RGBA +when alphaBits is not zero. For example, upsample() will always write 4 bytes +per pixel when alpha is set - (even if we only allocated 3 because we thought +we should use RGB). Erronously allocating only 3 bytes makes it easy to induce +a heap-buffer-overflow write, see ASAN output below. (apply_colormap makes the +same assumption and would probably do the same thing, but upsample is the +first location that we'd hit this issue.) + +ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61700002ae00 at pc 0x000000563d97 bp 0x7ffde8677890 sp 0x7ffde8677888 +WRITE of size 1 at 0x61700002ae00 thread T0 + #0 0x563d96 in upsample /home/ahunt/git/gimp/plug-ins/common/file-tga.c:830:15 + #1 0x560b59 in ReadImage /home/ahunt/git/gimp/plug-ins/common/file-tga.c + #2 0x55f4ee in load_image /home/ahunt/git/gimp/plug-ins/common/file-tga.c:647:11 + #3 0x5652ab in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/plug-ins/common/file-tga_fuzzer.c:69:17 + #4 0x461624 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 0x460b2a 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 0x462847 in fuzzer::Fuzzer::MutateAndTestOne() /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:745:19 + #7 0x4633d5 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:883:5 + #8 0x451686 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 0x47b662 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 + #10 0x7fd894a94349 in __libc_start_main (/lib64/libc.so.6+0x24349) + #11 0x424a39 in _start /home/abuild/rpmbuild/BUILD/glibc-2.26/csu/../sysdeps/x86_64/start.S:120 + +0x61700002ae00 is located 0 bytes to the right of 768-byte region [0x61700002ab00,0x61700002ae00) +allocated by thread T0 here: + #0 0x52ca8d in malloc /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3 + #1 0x7fd895b14cf2 in g_malloc /home/ahunt/git/glib/_build/../glib/gmem.c:106:13 + #2 0x55fce9 in ReadImage /home/ahunt/git/gimp/plug-ins/common/file-tga.c:1039:26 + #3 0x55f4ee in load_image /home/ahunt/git/gimp/plug-ins/common/file-tga.c:647:11 + #4 0x5652ab in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/plug-ins/common/file-tga_fuzzer.c:69:17 + #5 0x461624 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 + #6 0x460b2a 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 + #7 0x462847 in fuzzer::Fuzzer::MutateAndTestOne() /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:745:19 + #8 0x4633d5 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:883:5 + #9 0x451686 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 + #10 0x47b662 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 + #11 0x7fd894a94349 in __libc_start_main (/lib64/libc.so.6+0x24349) + +SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ahunt/git/gimp/plug-ins/common/file-tga.c:830:15 in upsample +Shadow bytes around the buggy address: + 0x0c2e7fffd570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x0c2e7fffd580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x0c2e7fffd590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x0c2e7fffd5a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x0c2e7fffd5b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x0c2e7fffd5c0:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c2e7fffd5d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x0c2e7fffd5e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x0c2e7fffd5f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x0c2e7fffd600: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x0c2e7fffd610: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd +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 +==12179==ABORTING + +( crash-f65fd5404bff32c1d9d10ee049d9c98d02bbbdc2 ) +--- + plug-ins/common/file-tga.c | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +diff --git a/plug-ins/common/file-tga.c b/plug-ins/common/file-tga.c +index f6f24a13194..c0d7ad94c20 100644 +--- a/plug-ins/common/file-tga.c ++++ b/plug-ins/common/file-tga.c +@@ -982,9 +982,9 @@ ReadImage (FILE *fp, + cmap_bytes = (info->colorMapSize + 7 ) / 8; + tga_cmap = g_new (guchar, info->colorMapLength * cmap_bytes); + +- if (info->colorMapSize > 24) ++ if (info->colorMapSize > 24 || info->alphaBits > 0) + { +- /* indexed + full alpha => promoted to RGBA */ ++ /* indexed + full alpha, or alpha exists => promoted to RGBA */ + itype = GIMP_RGB; + dtype = GIMP_RGBA_IMAGE; + convert_cmap = g_new (guchar, info->colorMapLength * 4); +@@ -996,13 +996,6 @@ ReadImage (FILE *fp, + dtype = GIMP_RGB_IMAGE; + convert_cmap = g_new (guchar, info->colorMapLength * 3); + } +- else if (info->alphaBits > 0) +- { +- /* if alpha exists here, promote to RGB */ +- itype = GIMP_RGB; +- dtype = GIMP_RGBA_IMAGE; +- convert_cmap = g_new (guchar, info->colorMapLength * 4); +- } + else + { + itype = GIMP_INDEXED; +-- +GitLab + diff --git a/CVE-2025-48797-2.patch b/CVE-2025-48797-2.patch new file mode 100644 index 0000000000000000000000000000000000000000..e8f855c854e96a2d89a1cafe1fc391ebc14d60f5 --- /dev/null +++ b/CVE-2025-48797-2.patch @@ -0,0 +1,167 @@ +From 723d383e57e8f599c4a44ab8541ea6902e29579e Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Tue, 16 Jul 2024 18:30:22 +0200 +Subject: [PATCH] tga: check for valid color ID in apply_colormap + +Origin: https://gitlab.gnome.org/GNOME/gimp/-/commit/723d383e57e8f599c4a44ab8541ea6902e29579e + +A malformed colourmapped tga file could specify color IDs that are not +contained in the colourmap. Therefore we add some bounds checking to +ensure that we only use entries that actually exist. + +We could completely give up on such files, but it's just as easy to fall +back to the first colour in the map in this case. However we can only +fall back to the first colour in the map IF the colourmap contains +at least one entry. Therefore we add an up-front check to verify that +colourmapped images actually do contain at least one entry. + +Without this bounds-checking, it's possible to induce a heap-buffer-overflow +read in apply-colormap(), see ASAN output below: + +ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61900002257c at pc 0x000000564f99 bp 0x7ffe65fdb040 sp 0x7ffe65fdb038 +READ of size 1 at 0x61900002257c thread T0 + #0 0x564f98 in apply_colormap /home/ahunt/git/gimp/plug-ins/common/file-tga.c:901:23 + #1 0x56411a in read_line /home/ahunt/git/gimp/plug-ins/common/file-tga.c:975:7 + #2 0x560648 in ReadImage /home/ahunt/git/gimp/plug-ins/common/file-tga.c:1202:15 + #3 0x55f4ee in load_image /home/ahunt/git/gimp/plug-ins/common/file-tga.c:647:11 + #4 0x5653ab in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/plug-ins/common/file-tga_fuzzer.c:69:17 + #5 0x461624 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 + #6 0x460b2a 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 + #7 0x462847 in fuzzer::Fuzzer::MutateAndTestOne() /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:745:19 + #8 0x4633d5 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:883:5 + #9 0x451686 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 + #10 0x47b662 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 + #11 0x7fe76a5dc349 in __libc_start_main (/lib64/libc.so.6+0x24349) + #12 0x424a39 in _start /home/abuild/rpmbuild/BUILD/glibc-2.26/csu/../sysdeps/x86_64/start.S:120 + +0x61900002257c is located 0 bytes to the right of 1020-byte region [0x619000022180,0x61900002257c) +allocated by thread T0 here: + #0 0x52ca8d in malloc /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3 + #1 0x7fe76b65ccf2 in g_malloc /home/ahunt/git/glib/_build/../glib/gmem.c:106:13 + #2 0x55fdc6 in ReadImage /home/ahunt/git/gimp/plug-ins/common/file-tga.c:1049:26 + #3 0x55f4ee in load_image /home/ahunt/git/gimp/plug-ins/common/file-tga.c:647:11 + #4 0x5653ab in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/plug-ins/common/file-tga_fuzzer.c:69:17 + #5 0x461624 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 + #6 0x460b2a 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 + #7 0x462847 in fuzzer::Fuzzer::MutateAndTestOne() /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:745:19 + #8 0x4633d5 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:883:5 + #9 0x451686 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 + #10 0x47b662 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 + #11 0x7fe76a5dc349 in __libc_start_main (/lib64/libc.so.6+0x24349) + +SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ahunt/git/gimp/plug-ins/common/file-tga.c:901:23 in apply_colormap +Shadow bytes around the buggy address: + 0x0c327fffc450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x0c327fffc460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x0c327fffc470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x0c327fffc480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x0c327fffc490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x0c327fffc4a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00[04] + 0x0c327fffc4b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c327fffc4c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c327fffc4d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c327fffc4e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c327fffc4f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +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 +==16309==ABORTING + +( crash-f70628d4df7a65babc8e57d890425771a1d67e06 ) +--- + plug-ins/common/file-tga.c | 47 +++++++++++++++++++------------------- + 1 file changed, 23 insertions(+), 24 deletions(-) + +diff --git a/plug-ins/common/file-tga.c b/plug-ins/common/file-tga.c +index 3e91ba1..0b68aca 100644 +--- a/plug-ins/common/file-tga.c ++++ b/plug-ins/common/file-tga.c +@@ -555,7 +555,7 @@ load_image (const gchar *filename, + switch (info.imageType) + { + case TGA_TYPE_MAPPED: +- if (info.bpp != 8) ++ if (info.bpp != 8 || !info.colorMapLength) + { + g_message ("Unhandled sub-format in '%s' (type = %u, bpp = %u)", + gimp_filename_to_utf8 (filename), +@@ -870,32 +870,31 @@ apply_colormap (guchar *dest, + guint width, + const guchar *cmap, + gboolean alpha, +- guint16 index) ++ guint16 colorMapIndex, ++ guint16 colorMapLength) + { + guint x; + +- if (alpha) +- { +- for (x = 0; x < width; x++) +- { +- *(dest++) = cmap[(*src - index) * 4]; +- *(dest++) = cmap[(*src - index) * 4 + 1]; +- *(dest++) = cmap[(*src - index) * 4 + 2]; +- *(dest++) = cmap[(*src - index) * 4 + 3]; +- +- src++; +- } +- } +- else ++ for (x = 0; x < width; x++) + { +- for (x = 0; x < width; x++) +- { +- *(dest++) = cmap[(*src - index) * 3]; +- *(dest++) = cmap[(*src - index) * 3 + 1]; +- *(dest++) = cmap[(*src - index) * 3 + 2]; +- +- src++; +- } ++ guchar entryIndex = src[x] - colorMapIndex; ++ ++ if (src[x] < colorMapIndex || entryIndex >= colorMapLength) { ++ g_message ("Unsupported colormap entry: %u", ++ src[x]); ++ entryIndex = 0; ++ } ++ ++ if (alpha) { ++ *(dest++) = cmap[entryIndex * 4]; ++ *(dest++) = cmap[entryIndex * 4 + 1]; ++ *(dest++) = cmap[entryIndex * 4 + 2]; ++ *(dest++) = cmap[entryIndex * 4 + 3]; ++ } else { ++ *(dest++) = cmap[entryIndex * 3]; ++ *(dest++) = cmap[entryIndex * 3 + 1]; ++ *(dest++) = cmap[entryIndex * 3 + 2]; ++ } + } + } + +@@ -951,7 +950,7 @@ read_line (FILE *fp, + gboolean has_alpha = (info->alphaBits > 0); + + apply_colormap (row, buf, info->width, convert_cmap, has_alpha, +- info->colorMapIndex); ++ info->colorMapIndex, info->colorMapLength); + } + else if (info->imageType == TGA_TYPE_MAPPED) + { diff --git a/CVE-2025-48797-3.patch b/CVE-2025-48797-3.patch new file mode 100644 index 0000000000000000000000000000000000000000..51d9ac6020188210ebbc5a357b80b1c4e27e61c2 --- /dev/null +++ b/CVE-2025-48797-3.patch @@ -0,0 +1,101 @@ +From 2ba35e5b3d43d881b0623f47b8068d9ee19d1d70 Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Tue, 16 Jul 2024 18:30:24 +0200 +Subject: [PATCH] tga: don't copy more bytes than necessary + +Origin: https://gitlab.gnome.org/GNOME/gimp/-/commit/2ba35e5b3d43d881b0623f47b8068d9ee19d1d70 + +We are trying to copy all bytes in the current row, which is the width times +the number of bytes per pixel (stored in info->bytes), not width times bits +per pixel. + +Copying too much data allows certain inputs to induce a heap-buffer-buffer +overflow read, and probably also a write, see ASAN output below: + +ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61d000008088 at pc 0x00000052be17 bp 0x7ffd8bbe8e20 sp 0x7ffd8bbe85e8 +READ of size 16448 at 0x61d000008088 thread T0 + #0 0x52be16 in __asan_memcpy /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3 + #1 0x5641ca in read_line /home/ahunt/git/gimp/plug-ins/common/file-tga.c:982:7 + #2 0x560218 in ReadImage /home/ahunt/git/gimp/plug-ins/common/file-tga.c:1147:15 + #3 0x55f526 in load_image /home/ahunt/git/gimp/plug-ins/common/file-tga.c:646:11 + #4 0x56519b in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/plug-ins/common/file-tga_fuzzer.c:69:17 + #5 0x461624 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 + #6 0x460b2a 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 + #7 0x462ec4 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__Fuzzer::vector >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:814:7 + #8 0x4630d9 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:845:3 + #9 0x451686 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 + #10 0x47b662 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 + #11 0x7fdbd277c349 in __libc_start_main (/lib64/libc.so.6+0x24349) + #12 0x424a39 in _start /home/abuild/rpmbuild/BUILD/glibc-2.26/csu/../sysdeps/x86_64/start.S:120 + +0x61d000008088 is located 0 bytes to the right of 2056-byte region [0x61d000007880,0x61d000008088) +allocated by thread T0 here: + #0 0x52ca8d in malloc /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3 + #1 0x7fdbd37fccf2 in g_malloc /home/ahunt/git/glib/_build/../glib/gmem.c:106:13 + #2 0x56009b in ReadImage /home/ahunt/git/gimp/plug-ins/common/file-tga.c:1134:10 + #3 0x55f526 in load_image /home/ahunt/git/gimp/plug-ins/common/file-tga.c:646:11 + #4 0x56519b in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/plug-ins/common/file-tga_fuzzer.c:69:17 + #5 0x461624 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 + #6 0x460b2a 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 + #7 0x462ec4 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__Fuzzer::vector >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:814:7 + #8 0x4630d9 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:845:3 + #9 0x451686 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 + #10 0x47b662 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 + #11 0x7fdbd277c349 in __libc_start_main (/lib64/libc.so.6+0x24349) + +SUMMARY: AddressSanitizer: heap-buffer-overflow /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3 in __asan_memcpy +Shadow bytes around the buggy address: + 0x0c3a7fff8fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x0c3a7fff8fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x0c3a7fff8fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x0c3a7fff8ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x0c3a7fff9000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x0c3a7fff9010: 00[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c3a7fff9020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c3a7fff9030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c3a7fff9040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c3a7fff9050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c3a7fff9060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +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 +==26560==ABORTING + +crash-4b13aca1db7bb795a815431b86cc20284f3aa6da +--- + plug-ins/common/file-tga.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/plug-ins/common/file-tga.c b/plug-ins/common/file-tga.c +index 433410ff471..a171a264772 100644 +--- a/plug-ins/common/file-tga.c ++++ b/plug-ins/common/file-tga.c +@@ -952,7 +952,7 @@ read_line (FILE *fp, + } + else + { +- memcpy (row, buf, info->width * bpp); ++ memcpy (row, buf, info->width * info->bytes); + } + } + +-- +GitLab + diff --git a/CVE-2025-48797-4.patch b/CVE-2025-48797-4.patch new file mode 100644 index 0000000000000000000000000000000000000000..27830c272f4c86cb68ff1c4f6dbc779b889c3fa4 --- /dev/null +++ b/CVE-2025-48797-4.patch @@ -0,0 +1,63 @@ +From 1f062867172d5c68b858a6efa3011686aa32bb38 Mon Sep 17 00:00:00 2001 +From: Jacob Boerema +Date: Fri, 19 Jul 2024 14:42:17 -0400 +Subject: [PATCH] plug-ins, tga: don't crash when generating a huge amount of + messages + +Origin: https://gitlab.gnome.org/GNOME/gimp/-/commit/1f062867172d5c68b858a6efa3011686aa32bb38 + +A follow-up to the previous commits, that address the tga issues from +issue #11822. + +On Windows, when using the error console for messages, a huge amount +of error messages, that can be generated with special fuzzed images, +like crash-f65fd5404bff32c1d9d10ee049d9c98d02bbbdc2.tga from +the above mentioned issue, can cause GIMP to crash. + +Although this is most likely caused in the error console or its +dependencies, we should not let it cause problems here until that is +fixed. There is also no real need to generate a huge amount of similar +repeated error messages, so let's limit it to 10 per read line of input. +--- + plug-ins/common/file-tga.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/plug-ins/common/file-tga.c b/plug-ins/common/file-tga.c +index a171a264772..abecde86857 100644 +--- a/plug-ins/common/file-tga.c ++++ b/plug-ins/common/file-tga.c +@@ -866,14 +866,29 @@ apply_colormap (guchar *dest, + guint16 colorMapLength) + { + guint x; ++ gint errcnt = 0; + + for (x = 0; x < width; x++) + { + guchar entryIndex = src[x] - colorMapIndex; + + if (src[x] < colorMapIndex || entryIndex >= colorMapLength) { +- g_message ("Unsupported colormap entry: %u", +- src[x]); ++ /* On Windows the error console can run out of resources when ++ * producing a huge amount of messages. This can happen when using ++ * fuzzed test images. This causes unresponsiveness at first and ++ * finally crashes GIMP. Eventually this needs to be fixed at the ++ * source, but for now let's limit the error messages to 10 ++ * per line (this function is called once per read_line). */ ++ if (errcnt < 10) ++ { ++ g_message ("Unsupported colormap entry: %u", ++ src[x]); ++ } ++ else if (errcnt == 10) ++ { ++ g_message ("Too many colormap errors. Image may be corrupt."); ++ } ++ errcnt++; + entryIndex = 0; + } + +-- +GitLab + diff --git a/CVE-2025-48798-1.patch b/CVE-2025-48798-1.patch new file mode 100644 index 0000000000000000000000000000000000000000..36cb8b5f1a315c933d244486bd64abacac31e7df --- /dev/null +++ b/CVE-2025-48798-1.patch @@ -0,0 +1,150 @@ +From 7d949423ed2231dd463968d86b58e0a3e01e6266 Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Tue, 16 Jul 2024 18:30:25 +0200 +Subject: [PATCH] xcf-load: avoid use-after-free for layers with multiple + PROP_ACTIVE_LAYER + +Origin: https://gitlab.gnome.org/GNOME/gimp/-/commit/7d949423ed2231dd463968d86b58e0a3e01e6266 + +If a given layer's properties contain multiple PROP_ACTIVE_LAYER entries, we +could add multiple entries for the same layer in info->selected_layers. + +However, xcf_load_layer_props and xcf_load_layer both contain logic that +overwrites the layer pointer - they do take care of updating +info->selected_layers and and info->floating_sel (both of which could contain +or point to the current layer). Crucially, they both assume that +info->selected_layers can only contain this layer once - hence they only +remove it from the list once. This logic also frees the old layer because it +thinks that it's no longer in use. + +But if we've added the original layer to selected_layers multiple times, +and then use the logic that overwrites layer, selected_layers will still +contain an invalid pointer to the now-freed original layer. Any later +code that tries to read info->selected_layers will hit a user-after-free. + +Therefore we need to check if the current layer is already in the +selected_layers list, and avoid adding it again if it's already there. +(It also seems illogical to say that a layer is selected twice, but I'm + focusing on the code-correctness aspect in my analysis.) + +Adjustment by Jacob Boerema: the correct way to test that a value does +not exist in a list is to check for the value being negative. Also add +a message to warn users. + +ASAN output: + +==21241==ERROR: AddressSanitizer: heap-use-after-free on address 0x615000012150 at pc 0x000000d54dbf bp 0x7ffcf813bb60 sp 0x7ffcf813bb58 +READ of size 8 at 0x615000012150 thread T0 + #0 0xd54dbe in gimp_image_set_selected_layers /home/ahunt/git/gimp/app/core/gimpimage.c:4743:7 + #1 0xb146c6 in xcf_load_image /home/ahunt/git/gimp/app/xcf/xcf-load.c:690:7 + #2 0xb1199b in xcf_load_stream /home/ahunt/git/gimp/app/xcf/xcf.c:305:19 + #3 0x619cad in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/app/fuzzers/xcf_fuzzer.c:35:17 + #4 0x51d2e4 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 0x506f62 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:323:6 + #6 0x50d2d0 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:856:9 + #7 0x537322 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 + #8 0x7f064a594349 in __libc_start_main (/lib64/libc.so.6+0x24349) + #9 0x4e06f9 in _start /home/abuild/rpmbuild/BUILD/glibc-2.26/csu/../sysdeps/x86_64/start.S:120 + +0x615000012150 is located 336 bytes inside of 504-byte region [0x615000012000,0x6150000121f8) +freed by thread T0 here: + #0 0x5e84e2 in free /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:127:3 + #1 0x7f064b3f81c8 in g_free (/usr/lib64/libglib-2.0.so.0+0x581c8) + #2 0x7f064b41133f in g_slice_free1 (/usr/lib64/libglib-2.0.so.0+0x7133f) + #3 0x7f064b7015c0 in g_type_free_instance /usr/src/debug/glib2-2.62.6-lp152.2.3.1.x86_64/build/../gobject/gtype.c:1946 + #4 0xb187d8 in xcf_load_layer /home/ahunt/git/gimp/app/xcf/xcf-load.c:2146:3 + #5 0xb13997 in xcf_load_image /home/ahunt/git/gimp/app/xcf/xcf-load.c:504:15 + #6 0xb1199b in xcf_load_stream /home/ahunt/git/gimp/app/xcf/xcf.c:305:19 + #7 0x619cad in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/app/fuzzers/xcf_fuzzer.c:35:17 + #8 0x51d2e4 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 + #9 0x506f62 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:323:6 + #10 0x50d2d0 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:856:9 + #11 0x537322 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 + #12 0x7f064a594349 in __libc_start_main (/lib64/libc.so.6+0x24349) + #13 0x4e06f9 in _start /home/abuild/rpmbuild/BUILD/glibc-2.26/csu/../sysdeps/x86_64/start.S:120 + +previously allocated by thread T0 here: + #0 0x5e874d in malloc /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3 + #1 0x7f064b3f80c8 in g_malloc (/usr/lib64/libglib-2.0.so.0+0x580c8) + #2 0x7f064b410da5 in g_slice_alloc (/usr/lib64/libglib-2.0.so.0+0x70da5) + #3 0x7f064b411258 in g_slice_alloc0 (/usr/lib64/libglib-2.0.so.0+0x71258) + #4 0x7f064b7011d5 in g_type_create_instance /usr/src/debug/glib2-2.62.6-lp152.2.3.1.x86_64/build/../gobject/gtype.c:1849 + #5 0x7f064b6e164f in g_object_new_internal /usr/src/debug/glib2-2.62.6-lp152.2.3.1.x86_64/build/../gobject/gobject.c:1827 + #6 0x7f064b6e354d in g_object_new_valist /usr/src/debug/glib2-2.62.6-lp152.2.3.1.x86_64/build/../gobject/gobject.c:2152 + #7 0x7f064b6e38c8 in g_object_new /usr/src/debug/glib2-2.62.6-lp152.2.3.1.x86_64/build/../gobject/gobject.c:1670 + #8 0xdb5b90 in gimp_item_new /home/ahunt/git/gimp/app/core/gimpitem.c:723:10 + #9 0xce0358 in gimp_drawable_new /home/ahunt/git/gimp/app/core/gimpdrawable.c:1067:14 + #10 0xddd8db in gimp_layer_new /home/ahunt/git/gimp/app/core/gimplayer-new.c:65:11 + #11 0xb182a6 in xcf_load_layer /home/ahunt/git/gimp/app/xcf/xcf-load.c:2027:11 + #12 0xb13997 in xcf_load_image /home/ahunt/git/gimp/app/xcf/xcf-load.c:504:15 + #13 0xb1199b in xcf_load_stream /home/ahunt/git/gimp/app/xcf/xcf.c:305:19 + #14 0x619cad in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/app/fuzzers/xcf_fuzzer.c:35:17 + #15 0x51d2e4 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 + #16 0x506f62 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:323:6 + #17 0x50d2d0 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:856:9 + #18 0x537322 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 + #19 0x7f064a594349 in __libc_start_main (/lib64/libc.so.6+0x24349) + #20 0x4e06f9 in _start /home/abuild/rpmbuild/BUILD/glibc-2.26/csu/../sysdeps/x86_64/start.S:120 + +SUMMARY: AddressSanitizer: heap-use-after-free /home/ahunt/git/gimp/app/core/gimpimage.c:4743:7 in gimp_image_set_selected_layers +Shadow bytes around the buggy address: + 0x0c2a7fffa3d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x0c2a7fffa3e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x0c2a7fffa3f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c2a7fffa400: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x0c2a7fffa410: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd +=>0x0c2a7fffa420: fd fd fd fd fd fd fd fd fd fd[fd]fd fd fd fd fd + 0x0c2a7fffa430: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa + 0x0c2a7fffa440: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c2a7fffa450: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x0c2a7fffa460: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x0c2a7fffa470: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd +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 +==21241==ABORTING + +( crash-f37f84bd7072e65348ca0e2c920d1e08165356fd ) +--- + app/xcf/xcf-load.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c +index a7fc85e..52e0c63 100644 +--- a/app/xcf/xcf-load.c ++++ b/app/xcf/xcf-load.c +@@ -1065,6 +1065,13 @@ xcf_load_layer_props (XcfInfo *info, + + case PROP_ACTIVE_LAYER: +- info->active_layer = *layer; ++ { ++ if (g_list_index (info->active_layer, *layer) < 0) ++ info->active_layer = *layer; ++ else ++ gimp_message_literal (info->gimp, G_OBJECT (info->progress), ++ GIMP_MESSAGE_WARNING, ++ "Invalid duplicate selected layer detected"); ++ } + break; + + case PROP_FLOATING_SELECTION: +-- +2.49.0 + diff --git a/CVE-2025-48798-2.patch b/CVE-2025-48798-2.patch new file mode 100644 index 0000000000000000000000000000000000000000..3c918287991b16a38de9be1e1fd53bc1e4c51801 --- /dev/null +++ b/CVE-2025-48798-2.patch @@ -0,0 +1,180 @@ +From fe26086e16943860f3852120f546ce913a7a73ee Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Tue, 16 Jul 2024 18:30:28 +0200 +Subject: [PATCH] xcf: don't use potentially dangling pointer in + xcf_load_layer_mask + +Origin: https://gitlab.gnome.org/GNOME/gimp/-/commit/fe26086e16943860f3852120f546ce913a7a73ee + +layer_mask points to the original mask created by xcf_load_layer_mask. We copy +this pointer into channel, and xcf_load_channel_props can overwrite this +pointer and free the original mask. If this happens, layer_mask points to +the now-freed original mask, and should not be used. + +Therefore we need to change later parts of xcf_load_layer_mask to use channel +instead of layer_mask. Additionally, we add a block and move layer_mask into +this block to guarantee that layer_mask cannot be used after it has +potentially been freed. + +Adjustments by Jacob Boerema: +Follow GIMP's code style regarding variables, comment style and +position of braces + +See also ASAN output below: + +==5247==ERROR: AddressSanitizer: heap-use-after-free on address 0x615000010fd0 at pc 0x7f4e2dbbf31b bp 0x7ffca8a95cd0 sp 0x7ffca8a95cc8 +READ of size 8 at 0x615000010fd0 thread T0 + #0 0x7f4e2dbbf31a in g_type_check_instance_cast /home/ahunt/git/glib/_build/../gobject/gtype.c:4117:26 + #1 0xb200fe in xcf_load_layer_mask /home/ahunt/git/gimp/app/xcf/xcf-load.c:2305:52 + #2 0xb18eea in xcf_load_layer /home/ahunt/git/gimp/app/xcf/xcf-load.c:2133:20 + #3 0xb13d91 in xcf_load_image /home/ahunt/git/gimp/app/xcf/xcf-load.c:499:15 + #4 0xb11deb in xcf_load_stream /home/ahunt/git/gimp/app/xcf/xcf.c:305:19 + #5 0x619dfd in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/app/fuzzers/xcf_fuzzer.c:50:17 + #6 0x51d364 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 + #7 0x506fe2 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:323:6 + #8 0x50d350 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:856:9 + #9 0x5373a2 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 + #10 0x7f4e2c84c349 in __libc_start_main (/lib64/libc.so.6+0x24349) + #11 0x4e0779 in _start /home/abuild/rpmbuild/BUILD/glibc-2.26/csu/../sysdeps/x86_64/start.S:120 + +0x615000010fd0 is located 336 bytes inside of 504-byte region [0x615000010e80,0x615000011078) +freed by thread T0 here: + #0 0x5e8562 in free /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:127:3 + #1 0x7f4e2d76ce08 in g_free /home/ahunt/git/glib/_build/../glib/gmem.c:199:3 + #2 0x7f4e2d797a6b in g_slice_free1 /home/ahunt/git/glib/_build/../glib/gslice.c:1183:7 + #3 0x7f4e2dbb7b04 in g_type_free_instance /home/ahunt/git/glib/_build/../gobject/gtype.c:2008:5 + #4 0x7f4e2db8fe3a in g_object_unref /home/ahunt/git/glib/_build/../gobject/gobject.c:3604:11 + #5 0xb22fff in xcf_load_channel_props /home/ahunt/git/gimp/app/xcf/xcf-load.c:1738:13 + #6 0xb20037 in xcf_load_layer_mask /home/ahunt/git/gimp/app/xcf/xcf-load.c:2292:9 + #7 0xb18eea in xcf_load_layer /home/ahunt/git/gimp/app/xcf/xcf-load.c:2133:20 + #8 0xb13d91 in xcf_load_image /home/ahunt/git/gimp/app/xcf/xcf-load.c:499:15 + #9 0xb11deb in xcf_load_stream /home/ahunt/git/gimp/app/xcf/xcf.c:305:19 + #10 0x619dfd in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/app/fuzzers/xcf_fuzzer.c:50:17 + #11 0x51d364 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 + #12 0x506fe2 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:323:6 + #13 0x50d350 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:856:9 + #14 0x5373a2 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 + #15 0x7f4e2c84c349 in __libc_start_main (/lib64/libc.so.6+0x24349) + +previously allocated by thread T0 here: + #0 0x5e87cd in malloc /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3 + #1 0x7f4e2d76ccf2 in g_malloc /home/ahunt/git/glib/_build/../glib/gmem.c:106:13 + #2 0x7f4e2d7972e0 in g_slice_alloc /home/ahunt/git/glib/_build/../glib/gslice.c:1072:11 + #3 0x7f4e2d7978ae in g_slice_alloc0 /home/ahunt/git/glib/_build/../glib/gslice.c:1098:18 + #4 0x7f4e2dbb6e0a in g_type_create_instance /home/ahunt/git/glib/_build/../gobject/gtype.c:1911:17 + #5 0x7f4e2db9215e in g_object_new_internal /home/ahunt/git/glib/_build/../gobject/gobject.c:1945:24 + #6 0x7f4e2db91d1f in g_object_new_valist /home/ahunt/git/glib/_build/../gobject/gobject.c:2288:16 + #7 0x7f4e2db90e8b in g_object_new /home/ahunt/git/glib/_build/../gobject/gobject.c:1788:12 + #8 0xdb69e0 in gimp_item_new /home/ahunt/git/gimp/app/core/gimpitem.c:723:10 + #9 0xce11c8 in gimp_drawable_new /home/ahunt/git/gimp/app/core/gimpdrawable.c:1067:14 + #10 0xddf5d8 in gimp_layer_mask_new /home/ahunt/git/gimp/app/core/gimplayermask.c:254:5 + #11 0xb1ffc5 in xcf_load_layer_mask /home/ahunt/git/gimp/app/xcf/xcf-load.c:2279:31 + #12 0xb18eea in xcf_load_layer /home/ahunt/git/gimp/app/xcf/xcf-load.c:2133:20 + #13 0xb13d91 in xcf_load_image /home/ahunt/git/gimp/app/xcf/xcf-load.c:499:15 + #14 0xb11deb in xcf_load_stream /home/ahunt/git/gimp/app/xcf/xcf.c:305:19 + #15 0x619dfd in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/app/fuzzers/xcf_fuzzer.c:50:17 + #16 0x51d364 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 + #17 0x506fe2 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:323:6 + #18 0x50d350 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:856:9 + #19 0x5373a2 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 + #20 0x7f4e2c84c349 in __libc_start_main (/lib64/libc.so.6+0x24349) + +SUMMARY: AddressSanitizer: heap-use-after-free /home/ahunt/git/glib/_build/../gobject/gtype.c:4117:26 in g_type_check_instance_cast +Shadow bytes around the buggy address: + 0x0c2a7fffa1a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x0c2a7fffa1b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x0c2a7fffa1c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c2a7fffa1d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x0c2a7fffa1e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd +=>0x0c2a7fffa1f0: fd fd fd fd fd fd fd fd fd fd[fd]fd fd fd fd fd + 0x0c2a7fffa200: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa + 0x0c2a7fffa210: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c2a7fffa220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x0c2a7fffa230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x0c2a7fffa240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +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 +==5247==ABORTING +./crash-0507799c3e4291570e060f53332b58b8a96f95e5 +--- + app/xcf/xcf-load.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c +index 52e0c63..38cd4b1 100644 +--- a/app/xcf/xcf-load.c ++++ b/app/xcf/xcf-load.c +@@ -98,7 +98,8 @@ static gboolean xcf_load_layer_props (XcfInfo *info, + guint32 *group_layer_flags); + static gboolean xcf_load_channel_props (XcfInfo *info, + GimpImage *image, +- GimpChannel **channel); ++ GimpChannel **channel, ++ gboolean is_mask); + static gboolean xcf_load_prop (XcfInfo *info, + PropType *prop_type, + guint32 *prop_size); +@@ -1409,7 +1410,8 @@ xcf_load_layer_props (XcfInfo *info, + static gboolean + xcf_load_channel_props (XcfInfo *info, + GimpImage *image, +- GimpChannel **channel) ++ GimpChannel **channel, ++ gboolean is_mask) + { + PropType prop_type; + guint32 prop_size; +@@ -1432,6 +1434,14 @@ xcf_load_channel_props (XcfInfo *info, + { + GimpChannel *mask; + ++ if (is_mask) ++ { ++ /* PROP_SELECTION is not valid for masks, and we have to avoid ++ * overwriting the channel. ++ */ ++ continue; ++ } ++ + /* We're going to delete *channel, Don't leave its pointer + * in @info. See bug #767873. + */ +@@ -1851,7 +1861,7 @@ xcf_load_channel (XcfInfo *info, + return NULL; + + /* read in the channel properties */ +- if (! xcf_load_channel_props (info, image, &channel)) ++ if (! xcf_load_channel_props (info, image, &channel, FALSE)) + goto error; + + xcf_progress_update (info); +@@ -1916,7 +1926,7 @@ xcf_load_layer_mask (XcfInfo *info, + + /* read in the layer_mask properties */ + channel = GIMP_CHANNEL (layer_mask); +- if (! xcf_load_channel_props (info, image, &channel)) ++ if (! xcf_load_channel_props (info, image, &channel, TRUE)) + goto error; + + xcf_progress_update (info); +-- +2.49.0 + diff --git a/CVE-2025-48798-3.patch b/CVE-2025-48798-3.patch new file mode 100644 index 0000000000000000000000000000000000000000..027a244d05b6e84f5b25aac4161ca0dc20505f23 --- /dev/null +++ b/CVE-2025-48798-3.patch @@ -0,0 +1,196 @@ +From e7523ed41271e48a909011b8598d496c1be642e2 Mon Sep 17 00:00:00 2001 +From: Jehan +Date: Mon, 4 Nov 2024 00:04:40 +0100 +Subject: [PATCH] Issue #11822: fix double-free in edge cases of broken XCF. + +Origin: https://gitlab.gnome.org/GNOME/gimp/-/commit/e7523ed41271e48a909011b8598d496c1be642e2 + +A patch was originally contributed by Andrzej Hunt in #11822 (cf. +0002-xcf-fix-channel-s-reference-counts.patch in the report). + +The diagnostic of the double PROP_SELECTION issue is right, but not the +fix which was over-reffing, hence leaking channels and buffers, in the +normal cases, just to avoid double-free in broken edge cases. + +The other issue is not possible though (unreffing the image's selection +when encountering an error in xcf_load_channel()) because we explicitly +check it it's the image mask AFAICS. + +I added a second test which was not double-freeing yet which deserves a +bit of stderr messaging: when 2 different channels have PROP_SELECTION +set. + +Relevant text from the commit message originally contributed by Andrzej +Hunt is the following (diagnostic and ASAN output still of interest): + +---------------- + +xcf_load_channel creates a new channel using gimp_channel_new. This +channel has a floating reference (because GimpChannel is a subclass of +GimpItem, and gimp_item_init uses g_object_force_floating()). + +Next, three different scenarios can occur: + - xcf_load_channel_props does nothing, and we either return channel, OR + in the error case we g_object_unref (channel) which frees channel. + The returned channel is either silently dropped (in the case where + it's already been set as the mask), or added to the image using + gimp_image_add_channel if not (which sinks the floating reference). + - xcf_load_channel_props encounters a single PROP_SELECTION. We create + a selection using gimp_selection_new (which again has a floating + reference), transfer ownership of the new selection to the image + using gimp_image_take_mask(), free the old channel, and finally set + channel to point to this new selection. Back in xcf_load_channel, IF + we hit the error case, we call g_object_unref (channel), which frees + the new selection - but we're still using it as the image's mask, + meaning we could eventually hit a use-after-free whenever someone + reads the mask. + - xcf_load_channel_props encounters 2 PROP_SELECTION's. After the first + PROP_SELECTION, channel is pointing to the image mask, which has + reference count == 1 (as explained above). When we hit the second + PROP_SELECTION: we create another new selection, followed by calling + gimp_image_take_mask() again. gimp_image_take_mask() call + g_object_unref() on the old mask, which frees it - but channel is still + pointing to this mask. We then call g_object_unref() on channel, which + is effectively a double-free. + +We fix this by making sure to always ref_sink whatever object is put +into channel. gimp_image_take_mask also calls ref_sink, which means +we'll now bump the refcount up to 2 when the channel is being used as +the image's mask (and drop back to 1 if the mask is replaced, and down +to 0 when channel is unref'd). + +See also ASAN output below from the 2x PROP_SELECTION scenario: + +==6381==ERROR: AddressSanitizer: heap-use-after-free on address 0x6150000047d0 at pc 0x7fb5531ef31b bp 0x7ffe81e86cb0 sp 0x7ffe81e86ca8 +READ of size 8 at 0x6150000047d0 thread T0 + #0 0x7fb5531ef31a in g_type_check_instance_cast /home/ahunt/git/glib/_build/../gobject/gtype.c:4117:26 + #1 0xb2346b in xcf_load_channel_props /home/ahunt/git/gimp/app/xcf/xcf-load.c:1742:41 + #2 0xb1a3cc in xcf_load_channel /home/ahunt/git/gimp/app/xcf/xcf-load.c:2219:9 + #3 0xb147eb in xcf_load_image /home/ahunt/git/gimp/app/xcf/xcf-load.c:653:17 + #4 0xb121bb in xcf_load_stream /home/ahunt/git/gimp/app/xcf/xcf.c:305:19 + #5 0x619ead in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/app/fuzzers/xcf_fuzzer.c:50:17 + #6 0x51d414 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 + #7 0x507092 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:323:6 + #8 0x50d400 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:856:9 + #9 0x537452 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 + #10 0x7fb551e7c349 in __libc_start_main (/lib64/libc.so.6+0x24349) + #11 0x4e0829 in _start /home/abuild/rpmbuild/BUILD/glibc-2.26/csu/../sysdeps/x86_64/start.S:120 + +0x6150000047d0 is located 336 bytes inside of 504-byte region [0x615000004680,0x615000004878) +freed by thread T0 here: + #0 0x5e8612 in free /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:127:3 + #1 0x7fb552d9ce08 in g_free /home/ahunt/git/glib/_build/../glib/gmem.c:199:3 + #2 0x7fb552dc7a6b in g_slice_free1 /home/ahunt/git/glib/_build/../glib/gslice.c:1183:7 + #3 0x7fb5531e7b04 in g_type_free_instance /home/ahunt/git/glib/_build/../gobject/gtype.c:2008:5 + #4 0x7fb5531bfe3a in g_object_unref /home/ahunt/git/glib/_build/../gobject/gobject.c:3604:11 + #5 0xd4d4d4 in gimp_image_take_mask /home/ahunt/git/gimp/app/core/gimpimage.c:3267:5 + #6 0xb23438 in xcf_load_channel_props /home/ahunt/git/gimp/app/xcf/xcf-load.c:1739:13 + #7 0xb1a3cc in xcf_load_channel /home/ahunt/git/gimp/app/xcf/xcf-load.c:2219:9 + #8 0xb147eb in xcf_load_image /home/ahunt/git/gimp/app/xcf/xcf-load.c:653:17 + #9 0xb121bb in xcf_load_stream /home/ahunt/git/gimp/app/xcf/xcf.c:305:19 + #10 0x619ead in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/app/fuzzers/xcf_fuzzer.c:50:17 + #11 0x51d414 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 + #12 0x507092 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:323:6 + #13 0x50d400 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:856:9 + #14 0x537452 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 + #15 0x7fb551e7c349 in __libc_start_main (/lib64/libc.so.6+0x24349) + +previously allocated by thread T0 here: + #0 0x5e887d in malloc /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3 + #1 0x7fb552d9ccf2 in g_malloc /home/ahunt/git/glib/_build/../glib/gmem.c:106:13 + #2 0x7fb552dc72e0 in g_slice_alloc /home/ahunt/git/glib/_build/../glib/gslice.c:1072:11 + #3 0x7fb552dc78ae in g_slice_alloc0 /home/ahunt/git/glib/_build/../glib/gslice.c:1098:18 + #4 0x7fb5531e6e0a in g_type_create_instance /home/ahunt/git/glib/_build/../gobject/gtype.c:1911:17 + #5 0x7fb5531c215e in g_object_new_internal /home/ahunt/git/glib/_build/../gobject/gobject.c:1945:24 + #6 0x7fb5531c1d1f in g_object_new_valist /home/ahunt/git/glib/_build/../gobject/gobject.c:2288:16 + #7 0x7fb5531c0e8b in g_object_new /home/ahunt/git/glib/_build/../gobject/gobject.c:1788:12 + #8 0xdb7260 in gimp_item_new /home/ahunt/git/gimp/app/core/gimpitem.c:722:10 + #9 0xce1668 in gimp_drawable_new /home/ahunt/git/gimp/app/core/gimpdrawable.c:1067:14 + #10 0xe283e9 in gimp_selection_new /home/ahunt/git/gimp/app/core/gimpselection.c:626:13 + #11 0xb2342a in xcf_load_channel_props /home/ahunt/git/gimp/app/xcf/xcf-load.c:1735:15 + #12 0xb1a3cc in xcf_load_channel /home/ahunt/git/gimp/app/xcf/xcf-load.c:2219:9 + #13 0xb147eb in xcf_load_image /home/ahunt/git/gimp/app/xcf/xcf-load.c:653:17 + #14 0xb121bb in xcf_load_stream /home/ahunt/git/gimp/app/xcf/xcf.c:305:19 + #15 0x619ead in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/app/fuzzers/xcf_fuzzer.c:50:17 + #16 0x51d414 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 + #17 0x507092 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:323:6 + #18 0x50d400 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:856:9 + #19 0x537452 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 + #20 0x7fb551e7c349 in __libc_start_main (/lib64/libc.so.6+0x24349) + +SUMMARY: AddressSanitizer: heap-use-after-free /home/ahunt/git/glib/_build/../gobject/gtype.c:4117:26 in g_type_check_instance_cast +Shadow bytes around the buggy address: + 0x0c2a7fff88a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x0c2a7fff88b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa + 0x0c2a7fff88c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c2a7fff88d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x0c2a7fff88e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd +=>0x0c2a7fff88f0: fd fd fd fd fd fd fd fd fd fd[fd]fd fd fd fd fd + 0x0c2a7fff8900: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa + 0x0c2a7fff8910: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c2a7fff8920: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x0c2a7fff8930: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x0c2a7fff8940: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd +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 +==6381==ABORTING + +( crash-c35bcae86d35ce7d0cd8ffcb41a470f37354e018 ) +--- + app/xcf/xcf-load.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c +index 1fb07528322..3b1bcc872a8 100644 +--- a/app/xcf/xcf-load.c ++++ b/app/xcf/xcf-load.c +@@ -2176,6 +2176,28 @@ xcf_load_channel_props (XcfInfo *info, + continue; + } + ++ if (*channel == gimp_image_get_mask (image)) ++ { ++ /* PROP_SELECTION was already seen once for this ++ * channel. Let's silently ignore the second identical ++ * property to avoid a double free. ++ */ ++ continue; ++ } ++ else if (gimp_image_get_mask (image) != NULL && ++ ! gimp_channel_is_empty (gimp_image_get_mask (image))) ++ { ++ /* This would happen when PROP_SELECTION was already set ++ * on a previous channel. This is a minor case of data ++ * loss (we don't know which selection was the right one ++ * and we drop the non-first ones), and also means it's ++ * a broken XCF, though it's not a major bug either. So ++ * let's go with a stderr print. ++ */ ++ g_printerr ("PROP_SELECTION property was set on 2 channels (skipping)\n"); ++ continue; ++ } ++ + /* We're going to delete *channel, Don't leave its pointer + * in @info. See bug #767873. + */ +-- +GitLab + diff --git a/gimp.spec b/gimp.spec index 29cf9864a5304eb990bbe4aad77f90099da28710..fd53626f8e5e310f68f340ea5580ec2c92673061 100644 --- a/gimp.spec +++ b/gimp.spec @@ -1,6 +1,6 @@ Name: gimp Version: 2.10.6 -Release: 12 +Release: 13 Epoch: 2 Summary: A versatile graphics manipulation package License: GPLv3+ and GPLv3 @@ -14,6 +14,13 @@ Patch6002: CVE-2023-44442.patch # https://gitlab.gnome.org/GNOME/gimp/-/commit/e1bfd87195e4fe60a92df70cde65464d032dd3c1 Patch6003: CVE-2023-44444.patch Patch6004: CVE-2025-2761.patch +Patch6005: CVE-2025-48797-1.patch +Patch6006: CVE-2025-48797-2.patch +Patch6007: CVE-2025-48797-3.patch +Patch6008: CVE-2025-48797-4.patch +Patch6009: CVE-2025-48798-1.patch +Patch6010: CVE-2025-48798-2.patch +Patch6011: CVE-2025-48798-3.patch %global apiversion 2.0 %global textversion 20 @@ -260,6 +267,9 @@ make check %{?_smp_mflags} %{_mandir}/man*/* %changelog +* Fri May 30 2025 wangkai <13474090681@163.com> - 2:2.10.6-13 +- Fix CVE-2025-48797 CVE-2025-48798 + * Tue May 06 2025 wangkai <13474090681@163.com> - 2:2.10.6-12 - Fix CVE-2025-2761