1
From 687ec47914ec08d6e460918cb641c196d80140a3 Mon Sep 17 00:00:00 2001
2
From: Simon Budig <simon@gimp.org>
3
Date: Tue, 17 Nov 2009 00:12:19 +0000
4
Subject: Fix the PSD structs to use signed ints for bounding box coordinates.
6
(cherry picked from commit 0e440cb6d4d6ee029667363d244aff61b154c33c)
8
diff --git a/plug-ins/file-psd/psd-load.c b/plug-ins/file-psd/psd-load.c
9
index d0a8455..5f43fa5 100644
10
--- a/plug-ins/file-psd/psd-load.c
11
+++ b/plug-ins/file-psd/psd-load.c
12
@@ -533,10 +533,10 @@ read_layer_block (PSDimage *img_a,
13
psd_set_error (feof (f), errno, error);
16
- lyr_a[lidx]->top = GUINT32_FROM_BE (lyr_a[lidx]->top);
17
- lyr_a[lidx]->left = GUINT32_FROM_BE (lyr_a[lidx]->left);
18
- lyr_a[lidx]->bottom = GUINT32_FROM_BE (lyr_a[lidx]->bottom);
19
- lyr_a[lidx]->right = GUINT32_FROM_BE (lyr_a[lidx]->right);
20
+ lyr_a[lidx]->top = GINT32_FROM_BE (lyr_a[lidx]->top);
21
+ lyr_a[lidx]->left = GINT32_FROM_BE (lyr_a[lidx]->left);
22
+ lyr_a[lidx]->bottom = GINT32_FROM_BE (lyr_a[lidx]->bottom);
23
+ lyr_a[lidx]->right = GINT32_FROM_BE (lyr_a[lidx]->right);
24
lyr_a[lidx]->num_channels = GUINT16_FROM_BE (lyr_a[lidx]->num_channels);
26
if (lyr_a[lidx]->num_channels > MAX_CHANNELS)
27
@@ -670,13 +670,13 @@ read_layer_block (PSDimage *img_a,
30
lyr_a[lidx]->layer_mask.top =
31
- GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.top);
32
+ GINT32_FROM_BE (lyr_a[lidx]->layer_mask.top);
33
lyr_a[lidx]->layer_mask.left =
34
- GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.left);
35
+ GINT32_FROM_BE (lyr_a[lidx]->layer_mask.left);
36
lyr_a[lidx]->layer_mask.bottom =
37
- GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.bottom);
38
+ GINT32_FROM_BE (lyr_a[lidx]->layer_mask.bottom);
39
lyr_a[lidx]->layer_mask.right =
40
- GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.right);
41
+ GINT32_FROM_BE (lyr_a[lidx]->layer_mask.right);
42
lyr_a[lidx]->layer_mask.mask_flags.relative_pos =
43
lyr_a[lidx]->layer_mask.flags & 1 ? TRUE : FALSE;
44
lyr_a[lidx]->layer_mask.mask_flags.disabled =
45
@@ -702,21 +702,21 @@ read_layer_block (PSDimage *img_a,
48
lyr_a[lidx]->layer_mask_extra.top =
49
- GUINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.top);
50
+ GINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.top);
51
lyr_a[lidx]->layer_mask_extra.left =
52
- GUINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.left);
53
+ GINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.left);
54
lyr_a[lidx]->layer_mask_extra.bottom =
55
- GUINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.bottom);
56
+ GINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.bottom);
57
lyr_a[lidx]->layer_mask_extra.right =
58
- GUINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.right);
59
+ GINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.right);
60
lyr_a[lidx]->layer_mask.top =
61
- GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.top);
62
+ GINT32_FROM_BE (lyr_a[lidx]->layer_mask.top);
63
lyr_a[lidx]->layer_mask.left =
64
- GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.left);
65
+ GINT32_FROM_BE (lyr_a[lidx]->layer_mask.left);
66
lyr_a[lidx]->layer_mask.bottom =
67
- GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.bottom);
68
+ GINT32_FROM_BE (lyr_a[lidx]->layer_mask.bottom);
69
lyr_a[lidx]->layer_mask.right =
70
- GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.right);
71
+ GINT32_FROM_BE (lyr_a[lidx]->layer_mask.right);
72
lyr_a[lidx]->layer_mask.mask_flags.relative_pos =
73
lyr_a[lidx]->layer_mask.flags & 1 ? TRUE : FALSE;
74
lyr_a[lidx]->layer_mask.mask_flags.disabled =
75
diff --git a/plug-ins/file-psd/psd.h b/plug-ins/file-psd/psd.h
76
index 6292747..b0c28ff 100644
77
--- a/plug-ins/file-psd/psd.h
78
+++ b/plug-ins/file-psd/psd.h
79
@@ -447,10 +447,10 @@ typedef struct
80
/* PSD Layer mask data (length 20) */
83
- guint32 top; /* Layer top */
84
- guint32 left; /* Layer left */
85
- guint32 bottom; /* Layer bottom */
86
- guint32 right; /* Layer right */
87
+ gint32 top; /* Layer top */
88
+ gint32 left; /* Layer left */
89
+ gint32 bottom; /* Layer bottom */
90
+ gint32 right; /* Layer right */
91
guchar def_color; /* Default background colour */
92
guchar flags; /* Layer flags */
93
guchar extra_def_color; /* Real default background colour */
94
@@ -461,20 +461,20 @@ typedef struct
95
/* PSD Layer mask data (length 36) */
98
- guint32 top; /* Layer top */
99
- guint32 left; /* Layer left */
100
- guint32 bottom; /* Layer bottom */
101
- guint32 right; /* Layer right */
102
+ gint32 top; /* Layer top */
103
+ gint32 left; /* Layer left */
104
+ gint32 bottom; /* Layer bottom */
105
+ gint32 right; /* Layer right */
108
/* PSD Layer data structure */
111
gboolean drop; /* Do not add layer to GIMP image */
112
- guint32 top; /* Layer top */
113
- guint32 left; /* Layer left */
114
- guint32 bottom; /* Layer bottom */
115
- guint32 right; /* Layer right */
116
+ gint32 top; /* Layer top */
117
+ gint32 left; /* Layer left */
118
+ gint32 bottom; /* Layer bottom */
119
+ gint32 right; /* Layer right */
120
guint16 num_channels; /* Number of channels */
121
ChannelLengthInfo *chn_info; /* Channel length info */
122
gchar mode_key[4]; /* Blend mode key */
125
From 88eccea84aa375197cc04a2a0e2e29debb56bfa5 Mon Sep 17 00:00:00 2001
126
From: Simon Budig <simon@gimp.org>
127
Date: Mon, 16 Nov 2009 23:41:39 +0000
128
Subject: Harden the PSD plugin against integer overflows.
130
Issues discovered by Stefan Cornelius, Secunia Research, advisory SA37232
131
and CVE identifier CVE-2009-3909. Fixes bug #600741.
132
(cherry picked from commit 9cc8d78ff33b7a36852b74e64b427489cad44d0e)
134
diff --git a/plug-ins/file-psd/psd-load.c b/plug-ins/file-psd/psd-load.c
135
index 5f43fa5..1b4e944 100644
136
--- a/plug-ins/file-psd/psd-load.c
137
+++ b/plug-ins/file-psd/psd-load.c
138
@@ -304,6 +304,15 @@ read_header_block (PSDimage *img_a,
142
+ /* img_a->rows is sanitized above, so a division by zero is avoided here */
143
+ if (img_a->columns > G_MAXINT32 / img_a->rows)
145
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
146
+ _("Unsupported or invalid image size: %dx%d"),
147
+ img_a->columns, img_a->rows);
151
if (img_a->color_mode != PSD_BITMAP
152
&& img_a->color_mode != PSD_GRAYSCALE
153
&& img_a->color_mode != PSD_INDEXED
154
@@ -546,14 +555,16 @@ read_layer_block (PSDimage *img_a,
155
lyr_a[lidx]->num_channels);
158
- if (lyr_a[lidx]->bottom - lyr_a[lidx]->top > GIMP_MAX_IMAGE_SIZE)
159
+ if (lyr_a[lidx]->bottom < lyr_a[lidx]->top ||
160
+ lyr_a[lidx]->bottom - lyr_a[lidx]->top > GIMP_MAX_IMAGE_SIZE)
162
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
163
_("Unsupported or invalid layer height: %d"),
164
lyr_a[lidx]->bottom - lyr_a[lidx]->top);
167
- if (lyr_a[lidx]->right - lyr_a[lidx]->left > GIMP_MAX_IMAGE_SIZE)
168
+ if (lyr_a[lidx]->right < lyr_a[lidx]->left ||
169
+ lyr_a[lidx]->right - lyr_a[lidx]->left > GIMP_MAX_IMAGE_SIZE)
171
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
172
_("Unsupported or invalid layer width: %d"),
173
@@ -561,6 +572,16 @@ read_layer_block (PSDimage *img_a,
177
+ if ((lyr_a[lidx]->right - lyr_a[lidx]->left) >
178
+ G_MAXINT32 / MAX (lyr_a[lidx]->bottom - lyr_a[lidx]->top, 1))
180
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
181
+ _("Unsupported or invalid layer size: %dx%d"),
182
+ lyr_a[lidx]->right - lyr_a[lidx]->left,
183
+ lyr_a[lidx]->bottom - lyr_a[lidx]->top);
187
IFDBG(2) g_debug ("Layer %d, Coords %d %d %d %d, channels %d, ",
188
lidx, lyr_a[lidx]->left, lyr_a[lidx]->top,
189
lyr_a[lidx]->right, lyr_a[lidx]->bottom,
190
@@ -734,6 +755,34 @@ read_layer_block (PSDimage *img_a,
194
+ /* sanity checks */
195
+ if (lyr_a[lidx]->layer_mask.bottom < lyr_a[lidx]->layer_mask.top ||
196
+ lyr_a[lidx]->layer_mask.bottom - lyr_a[lidx]->layer_mask.top > GIMP_MAX_IMAGE_SIZE)
198
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
199
+ _("Unsupported or invalid layer mask height: %d"),
200
+ lyr_a[lidx]->layer_mask.bottom - lyr_a[lidx]->layer_mask.top);
203
+ if (lyr_a[lidx]->layer_mask.right < lyr_a[lidx]->layer_mask.left ||
204
+ lyr_a[lidx]->layer_mask.right - lyr_a[lidx]->layer_mask.left > GIMP_MAX_IMAGE_SIZE)
206
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
207
+ _("Unsupported or invalid layer mask width: %d"),
208
+ lyr_a[lidx]->layer_mask.right - lyr_a[lidx]->layer_mask.left);
212
+ if ((lyr_a[lidx]->layer_mask.right - lyr_a[lidx]->layer_mask.left) >
213
+ G_MAXINT32 / MAX (lyr_a[lidx]->layer_mask.bottom - lyr_a[lidx]->layer_mask.top, 1))
215
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
216
+ _("Unsupported or invalid layer mask size: %dx%d"),
217
+ lyr_a[lidx]->layer_mask.right - lyr_a[lidx]->layer_mask.left,
218
+ lyr_a[lidx]->layer_mask.bottom - lyr_a[lidx]->layer_mask.top);
222
IFDBG(2) g_debug ("Layer mask coords %d %d %d %d, Rel pos %d",
223
lyr_a[lidx]->layer_mask.left,
224
lyr_a[lidx]->layer_mask.top,
225
@@ -1135,7 +1184,7 @@ add_layers (const gint32 image_id,
226
psd_set_error (feof (f), errno, error);
229
- rle_pack_len[rowi] = GUINT16_FROM_BE (rle_pack_len[rowi]);
230
+ rle_pack_len[rowi] = GUINT16_FROM_BE (rle_pack_len[rowi]);
233
IFDBG(3) g_debug ("RLE decode - data");
234
@@ -1761,6 +1810,16 @@ read_channel_data (PSDchannel *channel,
236
IFDBG(3) g_debug ("raw data size %d x %d = %d", readline_len,
237
channel->rows, readline_len * channel->rows);
239
+ /* sanity check, int overflow check (avoid divisions by zero) */
240
+ if ((channel->rows == 0) || (channel->columns == 0) ||
241
+ (channel->rows > G_MAXINT32 / channel->columns / MAX (bps >> 3, 1)))
243
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
244
+ _("Unsupported or invalid channel size"));
248
raw_data = g_malloc (readline_len * channel->rows);