[gimp] Bug 788870 - Abr corrupted files crashing GIMP
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 788870 - Abr corrupted files crashing GIMP
- Date: Tue, 2 Jan 2018 14:38:11 +0000 (UTC)
commit 221e18ab0924e0ed2f1c676579472d7c83e2b34a
Author: Michael Natterer <mitch gimp org>
Date: Tue Jan 2 15:36:07 2018 +0100
Bug 788870 - Abr corrupted files crashing GIMP
Add brush dimension/depth/compression sanity checks for v6 brushes,
and make sure we don't overrun the RLE decoder's destination buffer.
This properly rejects all brushes from the second zip in the bug.
app/core/gimpbrush-load.c | 47 +++++++++++++++++++++++++++++++++++++++++---
1 files changed, 43 insertions(+), 4 deletions(-)
---
diff --git a/app/core/gimpbrush-load.c b/app/core/gimpbrush-load.c
index 225e1f9..066a101 100644
--- a/app/core/gimpbrush-load.c
+++ b/app/core/gimpbrush-load.c
@@ -103,6 +103,7 @@ static gboolean abr_reach_8bim_section (GDataInputStream *input,
GError **error);
static gboolean abr_rle_decode (GDataInputStream *input,
gchar *buffer,
+ gsize buffer_size,
gint32 height,
GError **error);
@@ -726,7 +727,7 @@ gimp_brush_load_abr_brush_v12 (GDataInputStream *input,
}
else
{
- if (! abr_rle_decode (input, (gchar *) mask, height, error))
+ if (! abr_rle_decode (input, (gchar *) mask, size, height, error))
{
g_object_unref (brush);
brush = NULL;
@@ -812,9 +813,35 @@ gimp_brush_load_abr_brush_v6 (GDataInputStream *input,
depth = abr_read_short (input, error); if (error && *error) return NULL;
compress = abr_read_char (input, error); if (error && *error) return NULL;
+ depth = depth >> 3;
+
width = right - left;
height = bottom - top;
- size = width * (depth >> 3) * height;
+ size = width * depth * height;
+
+#if 0
+ g_printerr ("width %i height %i depth %i compress %i\n",
+ width, height, depth, compress);
+#endif
+
+ if (width < 1 || width > 10000 ||
+ height < 1 || height > 10000 ||
+ depth < 1 || depth > 1 ||
+ G_MAXSIZE / width / height / depth < 1)
+ {
+ g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
+ _("Fatal parse error in brush file: "
+ "Brush dimensions out of range."));
+ return NULL;
+ }
+
+ if (compress < 0 || compress > 1)
+ {
+ g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
+ _("Fatal parse error in brush file: "
+ "Unknown compression method."));
+ return NULL;
+ }
tmp = g_path_get_basename (gimp_file_get_utf8_name (file));
name = g_strdup_printf ("%s-%03d", tmp, index);
@@ -855,7 +882,7 @@ gimp_brush_load_abr_brush_v6 (GDataInputStream *input,
}
else
{
- if (! abr_rle_decode (input, (gchar *) mask, height, error))
+ if (! abr_rle_decode (input, (gchar *) mask, size, height, error))
{
g_object_unref (brush);
return NULL;
@@ -1007,6 +1034,7 @@ abr_reach_8bim_section (GDataInputStream *input,
static gboolean
abr_rle_decode (GDataInputStream *input,
gchar *buffer,
+ gsize buffer_size,
gint32 height,
GError **error)
{
@@ -1061,7 +1089,18 @@ abr_rle_decode (GDataInputStream *input,
j++;
for (c = 0; c < n; c++, data++)
- *data = ch;
+ {
+ if (data > buffer + buffer_size)
+ {
+ g_free (cscanline_len);
+ g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
+ _("Fatal parse error in brush file: "
+ "RLE compressed brush data corrupt."));
+ return FALSE;
+ }
+
+ *data = ch;
+ }
}
else
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]