summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2018-12-12 16:00:59 +0100
committerChristoph M. Becker <cmbecker69@gmx.de>2019-01-07 13:26:24 +0100
commitc1edfc748b88ef025edd23553888536ed62dc38e (patch)
tree39ebdf713a16279b7d89deee15a47ee3bf0b75ff
parent9d388b95c54ea053ce6f194defe1ff6673195747 (diff)
downloadphp-git-c1edfc748b88ef025edd23553888536ed62dc38e.tar.gz
Fix #77269: Potential unsigned underflow in gdImageScale
Belatedly, we're porting the respective upstream patch[1]. [1] <https://github.com/libgd/libgd/commit/60bfb401ad5a4a8ae995dcd36372fe15c71e1a35> (cherry picked from commit a918020c03880e12ac9f38e11a4a3789491a5f85)
-rw-r--r--NEWS2
-rw-r--r--ext/gd/libgd/gd_interpolation.c18
-rw-r--r--ext/gd/tests/bug77269.phpt21
3 files changed, 32 insertions, 9 deletions
diff --git a/NEWS b/NEWS
index cb8cb4d043..b8c3198234 100644
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,8 @@ PHP NEWS
. Fixed bug #77198 (auto cropping has insufficient precision). (cmb)
. Fixed bug #77200 (imagecropauto(…, GD_CROP_SIDES) crops left but not right).
(cmb)
+ . Fixed bug #77269 (efree() on uninitialized Heap data in imagescale leads to
+ use-after-free). (cmb)
- OCI8:
. Fixed bug #76804 (oci_pconnect with OCI_CRED_EXT not working). (KoenigsKind)
diff --git a/ext/gd/libgd/gd_interpolation.c b/ext/gd/libgd/gd_interpolation.c
index 75ac4137a7..afe0d7b4bb 100644
--- a/ext/gd/libgd/gd_interpolation.c
+++ b/ext/gd/libgd/gd_interpolation.c
@@ -890,8 +890,13 @@ static inline LineContribType * _gdContributionsAlloc(unsigned int line_length,
{
unsigned int u = 0;
LineContribType *res;
- int overflow_error = 0;
+ size_t weights_size;
+ if (overflow2(windows_size, sizeof(double))) {
+ return NULL;
+ } else {
+ weights_size = windows_size * sizeof(double);
+ }
res = (LineContribType *) gdMalloc(sizeof(LineContribType));
if (!res) {
return NULL;
@@ -908,15 +913,10 @@ static inline LineContribType * _gdContributionsAlloc(unsigned int line_length,
return NULL;
}
for (u = 0 ; u < line_length ; u++) {
- if (overflow2(windows_size, sizeof(double))) {
- overflow_error = 1;
- } else {
- res->ContribRow[u].Weights = (double *) gdMalloc(windows_size * sizeof(double));
- }
- if (overflow_error == 1 || res->ContribRow[u].Weights == NULL) {
+ res->ContribRow[u].Weights = (double *) gdMalloc(weights_size);
+ if (res->ContribRow[u].Weights == NULL) {
unsigned int i;
- u--;
- for (i=0;i<=u;i++) {
+ for (i=0;i<u;i++) {
gdFree(res->ContribRow[i].Weights);
}
gdFree(res->ContribRow);
diff --git a/ext/gd/tests/bug77269.phpt b/ext/gd/tests/bug77269.phpt
new file mode 100644
index 0000000000..3bdc23e80a
--- /dev/null
+++ b/ext/gd/tests/bug77269.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #77269 (Potential unsigned underflow in gdImageScale)
+--SKIPIF--
+<?php
+if (!extension_loaded('gd')) die('skip gd extension not available');
+if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
+?>
+--INI--
+memory_limit=2G
+--FILE--
+<?php
+$im = imagecreate(2**28, 1);
+if(is_resource($im)) {
+ imagescale($im, 1, 1, IMG_TRIANGLE);
+}
+?>
+===DONE===
+--EXPECTF--
+Warning: imagecreate():%S product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully
+ in %s on line %d
+===DONE===