diff options
author | Tobias Mueller <gnome-bugs@muelli.cryptobitch.de> | 2016-07-12 15:20:00 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2016-08-02 14:56:17 -0400 |
commit | 779429ce34e439c01d257444fe9d6739e72a2024 (patch) | |
tree | 21459530b2ae23f69cc383ab93c3029fe8ebed22 | |
parent | 9da258407972fbb7c198161ba96c699edff69444 (diff) | |
download | gdk-pixbuf-779429ce34e439c01d257444fe9d6739e72a2024.tar.gz |
bmp: Detect integer overflow of the line width
Instead of risking crashes or OOM, return an error if
we detect integer overflow.
The commit also includes a test image that triggers
this overflow when used with pixbuf-read.
https://bugzilla.gnome.org/show_bug.cgi?id=768738
-rw-r--r-- | gdk-pixbuf/io-bmp.c | 21 | ||||
-rw-r--r-- | tests/test-images/randomly-modified/bmp-line-overflow.bmp | bin | 0 -> 74 bytes |
2 files changed, 12 insertions, 9 deletions
diff --git a/gdk-pixbuf/io-bmp.c b/gdk-pixbuf/io-bmp.c index 748ebae57..08e3c768c 100644 --- a/gdk-pixbuf/io-bmp.c +++ b/gdk-pixbuf/io-bmp.c @@ -254,6 +254,7 @@ static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH, GError **error) { gint clrUsed; + guint bytesPerPixel; /* First check for the two first bytes content. A sane BMP file must start with bytes 0x42 0x4D. */ @@ -380,15 +381,17 @@ static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH, return FALSE; } - if (State->Type == 32) - State->LineWidth = State->Header.width * 4; - else if (State->Type == 24) - State->LineWidth = State->Header.width * 3; - else if (State->Type == 16) - State->LineWidth = State->Header.width * 2; - else if (State->Type == 8) - State->LineWidth = State->Header.width * 1; - else if (State->Type == 4) + if ((State->Type >= 8) && (State->Type <= 32) && (State->Type % 8 == 0)) { + bytesPerPixel = State->Type / 8; + State->LineWidth = State->Header.width * bytesPerPixel; + if (State->Header.width != State->LineWidth / bytesPerPixel) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("BMP image width too large")); + return FALSE; + } + } else if (State->Type == 4) State->LineWidth = (State->Header.width + 1) / 2; else if (State->Type == 1) { State->LineWidth = State->Header.width / 8; diff --git a/tests/test-images/randomly-modified/bmp-line-overflow.bmp b/tests/test-images/randomly-modified/bmp-line-overflow.bmp Binary files differnew file mode 100644 index 000000000..29d5c22e5 --- /dev/null +++ b/tests/test-images/randomly-modified/bmp-line-overflow.bmp |