summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Mueller <gnome-bugs@muelli.cryptobitch.de>2016-07-12 15:20:00 +0000
committerMatthias Clasen <mclasen@redhat.com>2016-08-02 14:56:17 -0400
commit779429ce34e439c01d257444fe9d6739e72a2024 (patch)
tree21459530b2ae23f69cc383ab93c3029fe8ebed22
parent9da258407972fbb7c198161ba96c699edff69444 (diff)
downloadgdk-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.c21
-rw-r--r--tests/test-images/randomly-modified/bmp-line-overflow.bmpbin0 -> 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
new file mode 100644
index 000000000..29d5c22e5
--- /dev/null
+++ b/tests/test-images/randomly-modified/bmp-line-overflow.bmp
Binary files differ