Package: gimp / 2.10.34-1+deb12u3

CVE-2025-48798-1.patch Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
commit ebf0b569a63f15b5dc7532f16936104af1e09f02
Author: Andrzej Hunt <andrzej@ahunt.org>
Date:   Tue Jul 16 18:30:28 2024 +0200

    xcf: don't use potentially dangling pointer in xcf_load_layer_mask
    
    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
    
    (cherry picked from commit fe26086e16943860f3852120f546ce913a7a73ee)
    
    # Conflicts:
    #       app/xcf/xcf-load.c

diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c
index da196bcdb2..41e582719a 100644
--- a/app/xcf/xcf-load.c
+++ b/app/xcf/xcf-load.c
@@ -102,7 +102,8 @@ static gboolean        xcf_check_layer_props  (XcfInfo       *info,
                                                gboolean      *is_text_layer);
 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);
@@ -1656,7 +1657,8 @@ xcf_check_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;
@@ -1679,6 +1681,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.
              */
@@ -2151,7 +2161,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);
@@ -2238,7 +2248,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);