diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2018-12-12 16:00:59 +0100 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2019-01-07 13:26:24 +0100 |
commit | c1edfc748b88ef025edd23553888536ed62dc38e (patch) | |
tree | 39ebdf713a16279b7d89deee15a47ee3bf0b75ff | |
parent | 9d388b95c54ea053ce6f194defe1ff6673195747 (diff) | |
download | php-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-- | NEWS | 2 | ||||
-rw-r--r-- | ext/gd/libgd/gd_interpolation.c | 18 | ||||
-rw-r--r-- | ext/gd/tests/bug77269.phpt | 21 |
3 files changed, 32 insertions, 9 deletions
@@ -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=== |