From 481be4358eae0ab5fdff7f22c7bbe05aa7c9d6b0 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 26 Oct 2022 11:59:28 +0200 Subject: add upstream fix for CVE-2022-31630 and CVE-2022-37454 --- php-bug81738.patch | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++ php-bug81739.patch | 70 +++++++++++++++++++++++++++++++++ php.spec | 9 ++++- 3 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 php-bug81738.patch create mode 100644 php-bug81739.patch diff --git a/php-bug81738.patch b/php-bug81738.patch new file mode 100644 index 0000000..9a3fa1c --- /dev/null +++ b/php-bug81738.patch @@ -0,0 +1,113 @@ +Cleanup from upstream + + + +From 248f647724e385bfb8d83aa5b5a5ca3c4ee2c7fd Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Thu, 20 Oct 2022 23:57:35 -0600 +Subject: [PATCH] Fix bug #81738 (buffer overflow in hash_update() on long + parameter) + +--- + NEWS | 4 ++++ + ext/hash/sha3/generic32lc/KeccakSponge.inc | 14 ++++++++------ + ext/hash/sha3/generic64lc/KeccakSponge.inc | 14 ++++++++------ + main/php_version.h | 10 +++++----- + 4 files changed, 25 insertions(+), 17 deletions(-) + +diff --git a/ext/hash/sha3/generic32lc/KeccakSponge.inc b/ext/hash/sha3/generic32lc/KeccakSponge.inc +index 42a15aac6d93..f8c42ff788b7 100644 +--- a/ext/hash/sha3/generic32lc/KeccakSponge.inc ++++ b/ext/hash/sha3/generic32lc/KeccakSponge.inc +@@ -160,7 +160,7 @@ int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dat + i = 0; + curData = data; + while(i < dataByteLen) { +- if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) { ++ if ((instance->byteIOIndex == 0) && (dataByteLen-i >= rateInBytes)) { + #ifdef SnP_FastLoop_Absorb + /* processing full blocks first */ + if ((rateInBytes % (SnP_width/200)) == 0) { +@@ -186,9 +186,10 @@ int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dat + } + else { + /* normal lane: using the message queue */ +- partialBlock = (unsigned int)(dataByteLen - i); +- if (partialBlock+instance->byteIOIndex > rateInBytes) ++ if (dataByteLen-i > rateInBytes-instance->byteIOIndex) + partialBlock = rateInBytes-instance->byteIOIndex; ++ else ++ partialBlock = (unsigned int)(dataByteLen - i); + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed (part)", curData, partialBlock); + #endif +@@ -263,7 +264,7 @@ int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByte + i = 0; + curData = data; + while(i < dataByteLen) { +- if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) { ++ if ((instance->byteIOIndex == rateInBytes) && (dataByteLen-i >= rateInBytes)) { + for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { + SnP_Permute(instance->state); + SnP_ExtractBytes(instance->state, curData, 0, rateInBytes); +@@ -280,9 +281,10 @@ int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByte + SnP_Permute(instance->state); + instance->byteIOIndex = 0; + } +- partialBlock = (unsigned int)(dataByteLen - i); +- if (partialBlock+instance->byteIOIndex > rateInBytes) ++ if (dataByteLen-i > rateInBytes-instance->byteIOIndex) + partialBlock = rateInBytes-instance->byteIOIndex; ++ else ++ partialBlock = (unsigned int)(dataByteLen - i); + i += partialBlock; + + SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock); +diff --git a/ext/hash/sha3/generic64lc/KeccakSponge.inc b/ext/hash/sha3/generic64lc/KeccakSponge.inc +index 42a15aac6d93..f8c42ff788b7 100644 +--- a/ext/hash/sha3/generic64lc/KeccakSponge.inc ++++ b/ext/hash/sha3/generic64lc/KeccakSponge.inc +@@ -160,7 +160,7 @@ int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dat + i = 0; + curData = data; + while(i < dataByteLen) { +- if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) { ++ if ((instance->byteIOIndex == 0) && (dataByteLen-i >= rateInBytes)) { + #ifdef SnP_FastLoop_Absorb + /* processing full blocks first */ + if ((rateInBytes % (SnP_width/200)) == 0) { +@@ -186,9 +186,10 @@ int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dat + } + else { + /* normal lane: using the message queue */ +- partialBlock = (unsigned int)(dataByteLen - i); +- if (partialBlock+instance->byteIOIndex > rateInBytes) ++ if (dataByteLen-i > rateInBytes-instance->byteIOIndex) + partialBlock = rateInBytes-instance->byteIOIndex; ++ else ++ partialBlock = (unsigned int)(dataByteLen - i); + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed (part)", curData, partialBlock); + #endif +@@ -263,7 +264,7 @@ int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByte + i = 0; + curData = data; + while(i < dataByteLen) { +- if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) { ++ if ((instance->byteIOIndex == rateInBytes) && (dataByteLen-i >= rateInBytes)) { + for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { + SnP_Permute(instance->state); + SnP_ExtractBytes(instance->state, curData, 0, rateInBytes); +@@ -280,9 +281,10 @@ int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByte + SnP_Permute(instance->state); + instance->byteIOIndex = 0; + } +- partialBlock = (unsigned int)(dataByteLen - i); +- if (partialBlock+instance->byteIOIndex > rateInBytes) ++ if (dataByteLen-i > rateInBytes-instance->byteIOIndex) + partialBlock = rateInBytes-instance->byteIOIndex; ++ else ++ partialBlock = (unsigned int)(dataByteLen - i); + i += partialBlock; + + SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock); diff --git a/php-bug81739.patch b/php-bug81739.patch new file mode 100644 index 0000000..f76e8c0 --- /dev/null +++ b/php-bug81739.patch @@ -0,0 +1,70 @@ +From d50532be91f054ef9beb1afca2ea94f4a70f7c4d Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Tue, 18 Oct 2022 12:13:16 +0200 +Subject: [PATCH] Fix #81739: OOB read due to insufficient validation in + imageloadfont() + +If we swap the byte order of the relevant header bytes, we need to make +sure again that the following multiplication does not overflow. +--- + ext/gd/gd.c | 7 +++++++ + ext/gd/tests/bug81739.phpt | 24 ++++++++++++++++++++++++ + 2 files changed, 31 insertions(+) + create mode 100644 ext/gd/tests/bug81739.phpt + +diff --git a/ext/gd/gd.c b/ext/gd/gd.c +index 336a73969267..fde93bba496f 100644 +--- a/ext/gd/gd.c ++++ b/ext/gd/gd.c +@@ -1485,6 +1485,12 @@ PHP_FUNCTION(imageloadfont) + font->w = FLIPWORD(font->w); + font->h = FLIPWORD(font->h); + font->nchars = FLIPWORD(font->nchars); ++ if (overflow2(font->nchars, font->h) || overflow2(font->nchars * font->h, font->w )) { ++ php_error_docref(NULL, E_WARNING, "Error reading font, invalid font header"); ++ efree(font); ++ php_stream_close(stream); ++ RETURN_FALSE; ++ } + body_size = font->w * font->h * font->nchars; + } + +@@ -1495,6 +1501,7 @@ PHP_FUNCTION(imageloadfont) + RETURN_FALSE; + } + ++ ZEND_ASSERT(body_size > 0); + font->data = emalloc(body_size); + b = 0; + while (b < body_size && (n = php_stream_read(stream, &font->data[b], body_size - b)) > 0) { +diff --git a/ext/gd/tests/bug81739.phpt b/ext/gd/tests/bug81739.phpt +new file mode 100644 +index 000000000000..cc2a90381bab +--- /dev/null ++++ b/ext/gd/tests/bug81739.phpt +@@ -0,0 +1,24 @@ ++--TEST-- ++Bug #81739 (OOB read due to insufficient validation in imageloadfont()) ++--SKIPIF-- ++ ++--FILE-- ++ ++--CLEAN-- ++ ++--EXPECTF-- ++Warning: imageloadfont(): %croduct of memory allocation multiplication would exceed INT_MAX, failing operation gracefully ++ in %s on line %d ++ ++Warning: imageloadfont(): Error reading font, invalid font header in %s on line %d ++bool(false) +\ No newline at end of file diff --git a/php.spec b/php.spec index 02c4131..f0d5b15 100644 --- a/php.spec +++ b/php.spec @@ -110,7 +110,7 @@ Summary: PHP scripting language for creating dynamic web sites Name: %{?scl_prefix}php Version: %{upver}%{?rcver:~%{rcver}}%{?gh_date:.%{gh_date}} -Release: 1%{?dist} +Release: 2%{?dist} # All files licensed under PHP version 3.01, except # Zend is licensed under Zend # TSRM is licensed under BSD @@ -175,6 +175,8 @@ Patch91: php-7.2.0-oci8conf.patch # Upstream fixes (100+) # Security fixes (200+) +Patch200: php-bug81738.patch +Patch201: php-bug81739.patch # Fixes for tests (300+) # Factory is droped from system tzdata @@ -953,6 +955,8 @@ rm ext/openssl/tests/p12_with_extra_certs.p12 # upstream patches # security patches +%patch200 -p1 -b .81738 +%patch201 -p1 -b .81739 # Fixes for tests %patch300 -p1 -b .datetests @@ -1829,6 +1833,9 @@ fi %changelog +* Wed Oct 26 2022 Remi Collet - 7.4.32-2 +- add upstream fix for CVE-2022-31630 and CVE-2022-37454 + * Wed Sep 28 2022 Remi Collet - 7.4.32-1 - Update to 7.4.32 - http://www.php.net/releases/7_4_32.php - use ICU 71.1 -- cgit