summaryrefslogtreecommitdiffstats
path: root/php-cve-2024-8932.patch
diff options
context:
space:
mode:
Diffstat (limited to 'php-cve-2024-8932.patch')
-rw-r--r--php-cve-2024-8932.patch140
1 files changed, 140 insertions, 0 deletions
diff --git a/php-cve-2024-8932.patch b/php-cve-2024-8932.patch
new file mode 100644
index 0000000..44b863a
--- /dev/null
+++ b/php-cve-2024-8932.patch
@@ -0,0 +1,140 @@
+From 9822bfae85607dffc13848d40a2340daf090f39b 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 5/8] Fix GHSA-g665-fm4p-vhff: OOB access in ldap_escape
+
+(cherry picked from commit f9ecf90070a11dad09ca7671a712f81cc2a7d52f)
+(cherry picked from commit 9f367d847989b339c33369737daf573e30bab5f1)
+(cherry picked from commit 50e9e72530a4805980384b8ea6672877af816145)
+---
+ ext/ldap/ldap.c | 21 ++++++++++++++--
+ ext/ldap/tests/GHSA-g665-fm4p-vhff-1.phpt | 28 ++++++++++++++++++++++
+ ext/ldap/tests/GHSA-g665-fm4p-vhff-2.phpt | 29 +++++++++++++++++++++++
+ 3 files changed, 76 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 d5a90b879e..748b0a6ff5 100644
+--- a/ext/ldap/ldap.c
++++ b/ext/ldap/ldap.c
+@@ -54,6 +54,7 @@
+
+ #include "ext/standard/php_string.h"
+ #include "ext/standard/info.h"
++#include "Zend/zend_exceptions.h"
+
+ #ifdef HAVE_LDAP_SASL_H
+ #include <sasl.h>
+@@ -3868,13 +3869,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;
+ }
+
+@@ -3941,7 +3952,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_throw_exception(NULL, "Argument #1 ($value) is too long", 0);
++ return;
++ }
++
++ 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 0000000000..734bbe91d4
+--- /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 (Exception $e) {
++ echo $e->getMessage(), "\n";
++}
++
++try {
++ ldap_escape(str_repeat("#", 1431655758).' ', "", LDAP_ESCAPE_DN);
++} catch (Exception $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 0000000000..5c1b0fb661
+--- /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 (Exception $e) {
++ echo $e->getMessage(), "\n";
++}
++
++// would allocate a string of length 2
++try {
++ ldap_escape(str_repeat("*", 1431655766), "", LDAP_ESCAPE_FILTER);
++} catch (Exception $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
+