mirror of
https://abf.rosa.ru/djam/php7.git
synced 2025-02-23 14:52:47 +00:00
security fixed
This commit is contained in:
parent
60004c6bc7
commit
9a37b5e6a1
5 changed files with 313 additions and 1 deletions
|
@ -0,0 +1,72 @@
|
||||||
|
From 404e8bdb68350931176a5bdc86fc417b34fb583d Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Christoph M. Becker" <cmbecker69@gmx.de>
|
||||||
|
Date: Mon, 25 Jul 2022 15:58:59 +0200
|
||||||
|
Subject: [PATCH] Fix #81726: phar wrapper: DOS when using quine gzip file
|
||||||
|
|
||||||
|
The phar wrapper needs to uncompress the file; the uncompressed file
|
||||||
|
might be compressed, so the wrapper implementation loops. This raises
|
||||||
|
potential DOS issues regarding too deep or even infinite recursion (the
|
||||||
|
latter are called compressed file quines[1]). We avoid that by
|
||||||
|
introducing a recursion limit; we choose the somewhat arbitrary limit
|
||||||
|
`3`.
|
||||||
|
|
||||||
|
This issue has been reported by real_as3617 and gPayl0ad.
|
||||||
|
|
||||||
|
[1] <https://honno.dev/gzip-quine/>
|
||||||
|
---
|
||||||
|
NEWS | 1 +
|
||||||
|
ext/phar/phar.c | 16 +++++++++++-----
|
||||||
|
ext/phar/tests/bug81726.gz | Bin 0 -> 204 bytes
|
||||||
|
ext/phar/tests/bug81726.phpt | 14 ++++++++++++++
|
||||||
|
4 files changed, 26 insertions(+), 5 deletions(-)
|
||||||
|
create mode 100644 ext/phar/tests/bug81726.gz
|
||||||
|
create mode 100644 ext/phar/tests/bug81726.phpt
|
||||||
|
|
||||||
|
diff --git a/ext/phar/phar.c b/ext/phar/phar.c
|
||||||
|
index 7cb1b06363..4a761ef799 100644
|
||||||
|
--- a/ext/phar/phar.c
|
||||||
|
+++ b/ext/phar/phar.c
|
||||||
|
@@ -1584,7 +1584,8 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char
|
||||||
|
const char zip_magic[] = "PK\x03\x04";
|
||||||
|
const char gz_magic[] = "\x1f\x8b\x08";
|
||||||
|
const char bz_magic[] = "BZh";
|
||||||
|
- char *pos, test = '\0';
|
||||||
|
+ char *pos;
|
||||||
|
+ int recursion_count = 3; // arbitrary limit to avoid too deep or even infinite recursion
|
||||||
|
const int window_size = 1024;
|
||||||
|
char buffer[1024 + sizeof(token)]; /* a 1024 byte window + the size of the halt_compiler token (moving window) */
|
||||||
|
const zend_long readsize = sizeof(buffer) - sizeof(token);
|
||||||
|
@@ -1612,8 +1613,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char
|
||||||
|
MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (truncated entry)")
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!test) {
|
||||||
|
- test = '\1';
|
||||||
|
+ if (recursion_count) {
|
||||||
|
pos = buffer+tokenlen;
|
||||||
|
if (!memcmp(pos, gz_magic, 3)) {
|
||||||
|
char err = 0;
|
||||||
|
@@ -1673,7 +1673,10 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char
|
||||||
|
compression = PHAR_FILE_COMPRESSED_GZ;
|
||||||
|
|
||||||
|
/* now, start over */
|
||||||
|
- test = '\0';
|
||||||
|
+ if (!--recursion_count) {
|
||||||
|
+ MAPPHAR_ALLOC_FAIL("unable to decompress gzipped phar archive \"%s\"");
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
continue;
|
||||||
|
} else if (!memcmp(pos, bz_magic, 3)) {
|
||||||
|
php_stream_filter *filter;
|
||||||
|
@@ -1711,7 +1714,10 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char
|
||||||
|
compression = PHAR_FILE_COMPRESSED_BZ2;
|
||||||
|
|
||||||
|
/* now, start over */
|
||||||
|
- test = '\0';
|
||||||
|
+ if (!--recursion_count) {
|
||||||
|
+ MAPPHAR_ALLOC_FAIL("unable to decompress bzipped phar archive \"%s\"");
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
57
0060-Fix-regression-introduced-by-fixing-bug-81726.patch
Normal file
57
0060-Fix-regression-introduced-by-fixing-bug-81726.patch
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
From 432bf196d59bcb661fcf9cb7029cea9b43f490af Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Christoph M. Becker" <cmbecker69@gmx.de>
|
||||||
|
Date: Tue, 27 Sep 2022 17:43:40 +0200
|
||||||
|
Subject: [PATCH] Fix regression introduced by fixing bug 81726
|
||||||
|
|
||||||
|
When a tar phar is created, `phar_open_from_fp()` is also called, but
|
||||||
|
since the file has just been created, none of the format checks can
|
||||||
|
succeed, so we continue to loop, but must not check again for the
|
||||||
|
format. Therefore, we bring back the old `test` variable.
|
||||||
|
|
||||||
|
Closes GH-9620.
|
||||||
|
---
|
||||||
|
ext/phar/phar.c | 7 +++++--
|
||||||
|
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ext/phar/phar.c b/ext/phar/phar.c
|
||||||
|
index 4a761ef799..ecab9162fa 100644
|
||||||
|
--- a/ext/phar/phar.c
|
||||||
|
+++ b/ext/phar/phar.c
|
||||||
|
@@ -1584,7 +1584,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char
|
||||||
|
const char zip_magic[] = "PK\x03\x04";
|
||||||
|
const char gz_magic[] = "\x1f\x8b\x08";
|
||||||
|
const char bz_magic[] = "BZh";
|
||||||
|
- char *pos;
|
||||||
|
+ char *pos, test = '\0';
|
||||||
|
int recursion_count = 3; // arbitrary limit to avoid too deep or even infinite recursion
|
||||||
|
const int window_size = 1024;
|
||||||
|
char buffer[1024 + sizeof(token)]; /* a 1024 byte window + the size of the halt_compiler token (moving window) */
|
||||||
|
@@ -1613,7 +1613,8 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char
|
||||||
|
MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (truncated entry)")
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (recursion_count) {
|
||||||
|
+ if (!test && recursion_count) {
|
||||||
|
+ test = '\1';
|
||||||
|
pos = buffer+tokenlen;
|
||||||
|
if (!memcmp(pos, gz_magic, 3)) {
|
||||||
|
char err = 0;
|
||||||
|
@@ -1673,6 +1674,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char
|
||||||
|
compression = PHAR_FILE_COMPRESSED_GZ;
|
||||||
|
|
||||||
|
/* now, start over */
|
||||||
|
+ test = '\0';
|
||||||
|
if (!--recursion_count) {
|
||||||
|
MAPPHAR_ALLOC_FAIL("unable to decompress gzipped phar archive \"%s\"");
|
||||||
|
break;
|
||||||
|
@@ -1714,6 +1716,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char
|
||||||
|
compression = PHAR_FILE_COMPRESSED_BZ2;
|
||||||
|
|
||||||
|
/* now, start over */
|
||||||
|
+ test = '\0';
|
||||||
|
if (!--recursion_count) {
|
||||||
|
MAPPHAR_ALLOC_FAIL("unable to decompress bzipped phar archive \"%s\"");
|
||||||
|
break;
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
From 0611be4e82887cee0de6c4cbae320d34eec946ca Mon Sep 17 00:00:00 2001
|
||||||
|
From: Derick Rethans <github@derickrethans.nl>
|
||||||
|
Date: Fri, 9 Sep 2022 16:54:03 +0100
|
||||||
|
Subject: [PATCH] Fix #81727: Don't mangle HTTP variable names that clash with
|
||||||
|
ones that have a specific semantic meaning.
|
||||||
|
|
||||||
|
---
|
||||||
|
NEWS | 6 ++++++
|
||||||
|
ext/standard/tests/bug81727.phpt | 15 +++++++++++++++
|
||||||
|
main/php_variables.c | 14 ++++++++++++++
|
||||||
|
3 files changed, 35 insertions(+)
|
||||||
|
create mode 100644 ext/standard/tests/bug81727.phpt
|
||||||
|
|
||||||
|
diff --git a/ext/standard/tests/bug81727.phpt b/ext/standard/tests/bug81727.phpt
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..71a9cb46c8
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/ext/standard/tests/bug81727.phpt
|
||||||
|
@@ -0,0 +1,15 @@
|
||||||
|
+--TEST--
|
||||||
|
+Bug #81727: $_COOKIE name starting with ..Host/..Secure should be discarded
|
||||||
|
+--COOKIE--
|
||||||
|
+..Host-test=ignore; __Host-test=correct; . Secure-test=ignore; . Elephpant=Awesome;
|
||||||
|
+--FILE--
|
||||||
|
+<?php
|
||||||
|
+var_dump($_COOKIE);
|
||||||
|
+?>
|
||||||
|
+--EXPECT--
|
||||||
|
+array(2) {
|
||||||
|
+ ["__Host-test"]=>
|
||||||
|
+ string(7) "correct"
|
||||||
|
+ ["__Elephpant"]=>
|
||||||
|
+ string(7) "Awesome"
|
||||||
|
+}
|
||||||
|
diff --git a/main/php_variables.c b/main/php_variables.c
|
||||||
|
index cbdc7cf171..18f6b65a6c 100644
|
||||||
|
--- a/main/php_variables.c
|
||||||
|
+++ b/main/php_variables.c
|
||||||
|
@@ -115,6 +115,20 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||||
|
}
|
||||||
|
var_len = p - var;
|
||||||
|
|
||||||
|
+ /* Discard variable if mangling made it start with __Host-, where pre-mangling it did not start with __Host- */
|
||||||
|
+ if (strncmp(var, "__Host-", sizeof("__Host-")-1) == 0 && strncmp(var_name, "__Host-", sizeof("__Host-")-1) != 0) {
|
||||||
|
+ zval_ptr_dtor_nogc(val);
|
||||||
|
+ free_alloca(var_orig, use_heap);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Discard variable if mangling made it start with __Secure-, where pre-mangling it did not start with __Secure- */
|
||||||
|
+ if (strncmp(var, "__Secure-", sizeof("__Secure-")-1) == 0 && strncmp(var_name, "__Secure-", sizeof("__Secure-")-1) != 0) {
|
||||||
|
+ zval_ptr_dtor_nogc(val);
|
||||||
|
+ free_alloca(var_orig, use_heap);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (var_len==0) { /* empty variable name, or variable name with a space in it */
|
||||||
|
zval_ptr_dtor_nogc(val);
|
||||||
|
free_alloca(var_orig, use_heap);
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
109
0062-Fix-bug-81738-buffer-overflow-in-hash_update-on-long.patch
Normal file
109
0062-Fix-bug-81738-buffer-overflow-in-hash_update-on-long.patch
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
From 248f647724e385bfb8d83aa5b5a5ca3c4ee2c7fd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Stanislav Malyshev <smalyshev@gmail.com>
|
||||||
|
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 42a15aac6d..f8c42ff788 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 42a15aac6d..f8c42ff788 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);
|
14
php7.spec
14
php7.spec
|
@ -27,7 +27,7 @@
|
||||||
Summary: The PHP7 scripting language
|
Summary: The PHP7 scripting language
|
||||||
Name: php
|
Name: php
|
||||||
Version: 7.4.30
|
Version: 7.4.30
|
||||||
Release: 2
|
Release: 3
|
||||||
Source0: http://ch1.php.net/distributions/php-%{version}.tar.gz
|
Source0: http://ch1.php.net/distributions/php-%{version}.tar.gz
|
||||||
Source1: macros.php
|
Source1: macros.php
|
||||||
Group: Development/PHP
|
Group: Development/PHP
|
||||||
|
@ -81,6 +81,13 @@ Patch114: php-no_pam_in_c-client.diff
|
||||||
# Fix bugs
|
# Fix bugs
|
||||||
Patch121: php-bug43221.diff
|
Patch121: php-bug43221.diff
|
||||||
Patch122: php-not-use-libgd-const.patch
|
Patch122: php-not-use-libgd-const.patch
|
||||||
|
# CVE-2022-31628
|
||||||
|
Patch123: 0059-Fix-81726-phar-wrapper-DOS-when-using-quine-gzip-fil.patch
|
||||||
|
Patch124: 0060-Fix-regression-introduced-by-fixing-bug-81726.patch
|
||||||
|
# CVE-2022-31629
|
||||||
|
Patch125: 0061-Fix-81727-Don-t-mangle-HTTP-variable-names-that-clas.patch
|
||||||
|
# CVE-2022-37454
|
||||||
|
Patch126: 0062-Fix-bug-81738-buffer-overflow-in-hash_update-on-long.patch
|
||||||
|
|
||||||
BuildRequires: autoconf
|
BuildRequires: autoconf
|
||||||
BuildRequires: automake
|
BuildRequires: automake
|
||||||
|
@ -1272,6 +1279,11 @@ fi
|
||||||
%patch121 -p0 -b .bug43221.droplet
|
%patch121 -p0 -b .bug43221.droplet
|
||||||
%patch122 -p1
|
%patch122 -p1
|
||||||
|
|
||||||
|
%patch123 -p1
|
||||||
|
%patch124 -p1
|
||||||
|
%patch125 -p1
|
||||||
|
%patch126 -p1
|
||||||
|
|
||||||
cp %{SOURCE2} maxlifetime
|
cp %{SOURCE2} maxlifetime
|
||||||
cp %{SOURCE3} php.crond
|
cp %{SOURCE3} php.crond
|
||||||
cp %{SOURCE4} php-fpm.service
|
cp %{SOURCE4} php-fpm.service
|
||||||
|
|
Loading…
Add table
Reference in a new issue