diff options
Diffstat (limited to 'php-cve-2024-8932.patch')
-rw-r--r-- | php-cve-2024-8932.patch | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/php-cve-2024-8932.patch b/php-cve-2024-8932.patch new file mode 100644 index 0000000..88e2e9f --- /dev/null +++ b/php-cve-2024-8932.patch @@ -0,0 +1,130 @@ +From 9f367d847989b339c33369737daf573e30bab5f1 Mon Sep 17 00:00:00 2001 +From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> +Date: Thu, 26 Sep 2024 22:22:27 +0200 +Subject: [PATCH 4/8] Fix GHSA-g665-fm4p-vhff: OOB access in ldap_escape + +(cherry picked from commit f9ecf90070a11dad09ca7671a712f81cc2a7d52f) +--- + ext/ldap/ldap.c | 20 ++++++++++++++-- + ext/ldap/tests/GHSA-g665-fm4p-vhff-1.phpt | 28 ++++++++++++++++++++++ + ext/ldap/tests/GHSA-g665-fm4p-vhff-2.phpt | 29 +++++++++++++++++++++++ + 3 files changed, 75 insertions(+), 2 deletions(-) + create mode 100644 ext/ldap/tests/GHSA-g665-fm4p-vhff-1.phpt + create mode 100644 ext/ldap/tests/GHSA-g665-fm4p-vhff-2.phpt + +diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c +index c4dfe0c5b07..6661310d055 100644 +--- a/ext/ldap/ldap.c ++++ b/ext/ldap/ldap.c +@@ -3760,13 +3760,23 @@ static zend_string* php_ldap_do_escape(const zend_bool *map, const char *value, + zend_string *ret; + + for (i = 0; i < valuelen; i++) { +- len += (map[(unsigned char) value[i]]) ? 3 : 1; ++ size_t addend = (map[(unsigned char) value[i]]) ? 3 : 1; ++ if (len > ZSTR_MAX_LEN - addend) { ++ return NULL; ++ } ++ len += addend; + } + /* Per RFC 4514, a leading and trailing space must be escaped */ + if ((flags & PHP_LDAP_ESCAPE_DN) && (value[0] == ' ')) { ++ if (len > ZSTR_MAX_LEN - 2) { ++ return NULL; ++ } + len += 2; + } + if ((flags & PHP_LDAP_ESCAPE_DN) && ((valuelen > 1) && (value[valuelen - 1] == ' '))) { ++ if (len > ZSTR_MAX_LEN - 2) { ++ return NULL; ++ } + len += 2; + } + +@@ -3833,7 +3843,13 @@ PHP_FUNCTION(ldap_escape) + php_ldap_escape_map_set_chars(map, ignores, ignoreslen, 0); + } + +- RETURN_NEW_STR(php_ldap_do_escape(map, value, valuelen, flags)); ++ zend_string *result = php_ldap_do_escape(map, value, valuelen, flags); ++ if (UNEXPECTED(!result)) { ++ zend_argument_value_error(1, "is too long"); ++ RETURN_THROWS(); ++ } ++ ++ RETURN_NEW_STR(result); + } + + #ifdef STR_TRANSLATION +diff --git a/ext/ldap/tests/GHSA-g665-fm4p-vhff-1.phpt b/ext/ldap/tests/GHSA-g665-fm4p-vhff-1.phpt +new file mode 100644 +index 00000000000..8e2c4fb160d +--- /dev/null ++++ b/ext/ldap/tests/GHSA-g665-fm4p-vhff-1.phpt +@@ -0,0 +1,28 @@ ++--TEST-- ++GHSA-g665-fm4p-vhff (OOB access in ldap_escape) ++--EXTENSIONS-- ++ldap ++--INI-- ++memory_limit=-1 ++--SKIPIF-- ++<?php ++if (PHP_INT_SIZE !== 4) die("skip only for 32-bit"); ++if (getenv("SKIP_SLOW_TESTS")) die("skip slow test"); ++?> ++--FILE-- ++<?php ++try { ++ ldap_escape(' '.str_repeat("#", 1431655758), "", LDAP_ESCAPE_DN); ++} catch (ValueError $e) { ++ echo $e->getMessage(), "\n"; ++} ++ ++try { ++ ldap_escape(str_repeat("#", 1431655758).' ', "", LDAP_ESCAPE_DN); ++} catch (ValueError $e) { ++ echo $e->getMessage(), "\n"; ++} ++?> ++--EXPECT-- ++ldap_escape(): Argument #1 ($value) is too long ++ldap_escape(): Argument #1 ($value) is too long +diff --git a/ext/ldap/tests/GHSA-g665-fm4p-vhff-2.phpt b/ext/ldap/tests/GHSA-g665-fm4p-vhff-2.phpt +new file mode 100644 +index 00000000000..a69597084be +--- /dev/null ++++ b/ext/ldap/tests/GHSA-g665-fm4p-vhff-2.phpt +@@ -0,0 +1,29 @@ ++--TEST-- ++GHSA-g665-fm4p-vhff (OOB access in ldap_escape) ++--EXTENSIONS-- ++ldap ++--INI-- ++memory_limit=-1 ++--SKIPIF-- ++<?php ++if (PHP_INT_SIZE !== 4) die("skip only for 32-bit"); ++if (getenv("SKIP_SLOW_TESTS")) die("skip slow test"); ++?> ++--FILE-- ++<?php ++try { ++ ldap_escape(str_repeat("*", 1431655759), "", LDAP_ESCAPE_FILTER); ++} catch (ValueError $e) { ++ echo $e->getMessage(), "\n"; ++} ++ ++// would allocate a string of length 2 ++try { ++ ldap_escape(str_repeat("*", 1431655766), "", LDAP_ESCAPE_FILTER); ++} catch (ValueError $e) { ++ echo $e->getMessage(), "\n"; ++} ++?> ++--EXPECT-- ++ldap_escape(): Argument #1 ($value) is too long ++ldap_escape(): Argument #1 ($value) is too long +-- +2.47.0 + |