From 1bf91fcd2663d7281c2e92ec22d32c3730a379a5 Mon Sep 17 00:00:00 2001 From: Nils Philippsen <nils@redhat.com> Date: Wed, 18 May 2011 20:45:57 +0200 Subject: [PATCH] patch: bmp-hardening Squashed commit of the following: commit 80256e04092ce89ce7d7e7cc5e792b3ab525cb1e Author: Nils Philippsen <nils@redhat.com> Date: Fri Mar 18 16:51:37 2011 +0100 Harden BMP plugin against various vulnerabilities. Consolidated commit of backported fixes: commit 16e6a37687bb4b9748c5a5d166d90f5d5bd2e9f3 Author: Nils Philippsen <nils@redhat.com> Date: Mon Nov 16 18:16:38 2009 +0100 Ensure valid bit depths when reading BMP files. commit f63ba36dd9cc01ca6da83fa05ddd12419ad8953e Author: Nils Philippsen <nils@redhat.com> Date: Mon Nov 16 17:16:09 2009 +0100 Use more defensive coding in plausibility check. Use an equivalent division instead of multiplying values and checking if they are more than G_MAXINT32, because divisions cannot overflow. commit 43d57c666346320436a0b668de5525387952784e Author: Nils Philippsen <nils@redhat.com> Date: Mon Nov 16 17:15:32 2009 +0100 Make plausibility check easier to understand. Explicitly check that Bitmap_Head.biHeight is not G_MININT32 instead of relying on ABS(G_MININT32) being negative. commit e3afc99b2fa7aeddf0dba4778663160a5bc682d3 Author: Simon Budig <simon@gimp.org> Date: Tue Nov 10 00:08:59 2009 +0100 Harden the BMP plugin against integer overflows. Issues discovered by Stefan Cornelius, Secunia Research, advisory SA37232 and CVE identifier CVE-2009-1570. Fixes bug #600484. --- plug-ins/bmp/bmpread.c | 30 ++++++++++++++++++++++++++++-- 1 files changed, 28 insertions(+), 2 deletions(-) diff --git a/plug-ins/bmp/bmpread.c b/plug-ins/bmp/bmpread.c index a445be1..387c2cc 100644 --- a/plug-ins/bmp/bmpread.c +++ b/plug-ins/bmp/bmpread.c @@ -281,9 +281,23 @@ ReadBMP (const gchar *name) return -1; } - /* Valid bitpdepthis 1, 4, 8, 16, 24, 32 */ + /* Valid bit depth is 1, 4, 8, 16, 24, 32 */ /* 16 is awful, we should probably shoot whoever invented it */ + switch (Bitmap_Head.biBitCnt) + { + case 1: + case 2: + case 4: + case 8: + case 16: + case 24: + case 32: + break; + default: + return -1; + } + /* There should be some colors used! */ ColormapSize = (Bitmap_File_Head.bfOffs - Bitmap_File_Head.biSize - 14) / Maps; @@ -302,7 +316,10 @@ ReadBMP (const gchar *name) return -1; } - if (Bitmap_Head.biWidth < 0) + /* biHeight may be negative, but G_MININT32 is dangerous because: + G_MININT32 == -(G_MININT32) */ + if (Bitmap_Head.biWidth < 0 || + Bitmap_Head.biHeight == G_MININT32) { g_message (_("'%s' is not a valid BMP file"), gimp_filename_to_utf8 (filename)); @@ -321,6 +338,15 @@ ReadBMP (const gchar *name) return -1; } + /* protect against integer overflows caused by malicious BMPs */ + /* use divisions in comparisons to avoid type overflows */ + + if (((guint64) Bitmap_Head.biWidth) > G_MAXINT32 / Bitmap_Head.biBitCnt || + ((guint64) Bitmap_Head.biWidth) > (G_MAXINT32 / ABS (Bitmap_Head.biHeight)) / 4) + { + return -1; + } + /* Windows and OS/2 declare filler so that rows are a multiple of * word length (32 bits == 4 bytes) */ -- 1.7.5.1