summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Joye <pajoye@php.net>2007-03-10 13:06:37 +0000
committerPierre Joye <pajoye@php.net>2007-03-10 13:06:37 +0000
commit33323771a494aa0b89e343e0eefbf84ba1193c9e (patch)
treecfe6554fdf6e7dc2dba2c677c8f41c75723767e7
parent0edbc8d5011aec3a0f6c0b1dca368994413f9177 (diff)
downloadphp-git-33323771a494aa0b89e343e0eefbf84ba1193c9e.tar.gz
- MFH: CVE-2007-1001, integer overflow with invalid wbmp images
-rw-r--r--NEWS1
-rw-r--r--ext/gd/config.m42
-rw-r--r--ext/gd/gd.dsp4
-rw-r--r--ext/gd/libgd/gd_security.c33
-rw-r--r--ext/gd/libgd/gdhelpers.h7
-rw-r--r--ext/gd/libgd/wbmp.c16
-rw-r--r--ext/gd/tests/createfromwbmp2.phpt47
7 files changed, 109 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index a23563291a..11e22718fa 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
PHP 4 NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2007, Version 4.4.7
+- Fixed CVE-2007-1001, GD wbmp used with invalid image size (Pierre)
- Fixed bug #40747 (possible crash in session when save_path is out of
open_basedir). (Tony)
diff --git a/ext/gd/config.m4 b/ext/gd/config.m4
index b1617ef92f..086fdd5b83 100644
--- a/ext/gd/config.m4
+++ b/ext/gd/config.m4
@@ -273,7 +273,7 @@ if test "$PHP_GD" = "yes"; then
libgd/gdxpm.c libgd/gdfontt.c libgd/gdfonts.c libgd/gdfontmb.c libgd/gdfontl.c \
libgd/gdfontg.c libgd/gdtables.c libgd/gdft.c libgd/gdcache.c libgd/gdkanji.c \
libgd/wbmp.c libgd/gd_wbmp.c libgd/gdhelpers.c libgd/gd_topal.c libgd/gd_gif_in.c \
- libgd/xbm.c libgd/gd_gif_out.c "
+ libgd/xbm.c libgd/gd_gif_out.c libgd/gd_security.c"
dnl check for fabsf and floorf which are available since C99
AC_CHECK_FUNCS(fabsf floorf)
diff --git a/ext/gd/gd.dsp b/ext/gd/gd.dsp
index 56365164d7..782a396ccd 100644
--- a/ext/gd/gd.dsp
+++ b/ext/gd/gd.dsp
@@ -104,6 +104,10 @@ SOURCE=.\gd.c
# End Source File
# Begin Source File
+SOURCE=.\gd_security.c
+# End Source File
+# Begin Source File
+
SOURCE=.\gdttf.c
# End Source File
# End Group
diff --git a/ext/gd/libgd/gd_security.c b/ext/gd/libgd/gd_security.c
new file mode 100644
index 0000000000..a5fea34c14
--- /dev/null
+++ b/ext/gd/libgd/gd_security.c
@@ -0,0 +1,33 @@
+/*
+ * gd_security.c
+ *
+ * Implements buffer overflow check routines.
+ *
+ * Written 2004, Phil Knirsch.
+ * Based on netpbm fixes by Alan Cox.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "gd.h"
+
+int overflow2(int a, int b)
+{
+ if(a < 0 || b < 0) {
+ php_gd_error("gd warning: one parameter to a memory allocation multiplication is negative, failing operation gracefully\n");
+ return 1;
+ }
+ if(b == 0)
+ return 0;
+ if(a > INT_MAX / b) {
+ php_gd_error("gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/ext/gd/libgd/gdhelpers.h b/ext/gd/libgd/gdhelpers.h
index 33223318f1..11041febed 100644
--- a/ext/gd/libgd/gdhelpers.h
+++ b/ext/gd/libgd/gdhelpers.h
@@ -21,6 +21,13 @@ extern char *gd_strtok_r(char *s, char *sep, char **state);
#define gdPFree(ptr) pefree(ptr, 1)
#define gdPEstrdup(ptr) pestrdup(ptr, 1)
+/* Returns nonzero if multiplying the two quantities will
+ result in integer overflow. Also returns nonzero if
+ either quantity is negative. By Phil Knirsch based on
+ netpbm fixes by Alan Cox. */
+
+int overflow2(int a, int b);
+
#ifdef ZTS
#define gdMutexDeclare(x) MUTEX_T x
#define gdMutexSetup(x) x = tsrm_mutex_alloc()
diff --git a/ext/gd/libgd/wbmp.c b/ext/gd/libgd/wbmp.c
index e115e80b82..53603639ca 100644
--- a/ext/gd/libgd/wbmp.c
+++ b/ext/gd/libgd/wbmp.c
@@ -116,6 +116,15 @@ createwbmp (int width, int height, int color)
if ((wbmp = (Wbmp *) gdMalloc (sizeof (Wbmp))) == NULL)
return (NULL);
+ if (overflow2(sizeof (int), width)) {
+ gdFree(wbmp);
+ return NULL;
+ }
+ if (overflow2(sizeof (int) * width, height)) {
+ gdFree(wbmp);
+ return NULL;
+ }
+
if ((wbmp->bitmap = (int *) safe_emalloc(sizeof(int), (width * height), 0)) == NULL)
{
gdFree (wbmp);
@@ -176,6 +185,13 @@ readwbmp (int (*getin) (void *in), void *in, Wbmp ** return_wbmp)
printf ("W: %d, H: %d\n", wbmp->width, wbmp->height);
#endif
+ if (overflow2(sizeof (int), wbmp->width) ||
+ overflow2(sizeof (int) * wbmp->width, wbmp->height))
+ {
+ gdFree(wbmp);
+ return (-1);
+ }
+
if ((wbmp->bitmap = (int *) safe_emalloc(sizeof(int), (wbmp->width * wbmp->height), 0)) == NULL)
{
gdFree (wbmp);
diff --git a/ext/gd/tests/createfromwbmp2.phpt b/ext/gd/tests/createfromwbmp2.phpt
new file mode 100644
index 0000000000..4c679130b6
--- /dev/null
+++ b/ext/gd/tests/createfromwbmp2.phpt
@@ -0,0 +1,47 @@
+--TEST--
+imagecreatefromwbmp with invalid wbmp
+--SKIPIF--
+<?php
+ if (!function_exists('imagecreatefromwbmp')) die("skip gd extension not available\n");
+?>
+--FILE--
+<?php
+$filename = dirname(__FILE__) . '/_tmp.wbmp';
+$fp = fopen($filename,"wb");
+if (!$fp) {
+ exit("Failed to create <$filename>");
+}
+
+//write header
+$c = 0;
+fputs($fp, chr($c), 1);
+fputs($fp, $c, 1);
+
+//write width = 2^32 / 4 + 1
+$c = 0x84;
+fputs($fp, chr($c), 1);
+$c = 0x80;
+fputs($fp, chr($c), 1);
+fputs($fp, chr($c), 1);
+fputs($fp, chr($c), 1);
+$c = 0x01;
+fputs($fp, chr($c), 1);
+
+/*write height = 4*/
+$c = 0x04;
+fputs($fp, chr($c), 1);
+
+/*write some data to cause overflow*/
+for ($i=0; $i<10000; $i++) {
+ fwrite($fp, chr($c), 1);
+}
+
+fclose($fp);
+$im = imagecreatefromwbmp($filename);
+unlink($filename);
+?>
+--EXPECTF--
+Warning: imagecreatefromwbmp() [/phpmanual/function.imagecreatefromwbmp.html]: gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully
+ in %s on line %d
+
+Warning: imagecreatefromwbmp() [/phpmanual/function.imagecreatefromwbmp.html]: '%s' is not a valid WBMP file in %s on line %d