From c6ee9a7d0385e4cd6cf9dcd0104dd6714e2a968d Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 24 Oct 2024 22:02:17 +0200 Subject: [PATCH 1/9] Fix GHSA-5hqh-c84r-qjcv: Integer overflow in the dblib quoter causing OOB writes (cherry picked from commit d9baa9fed8c3ba692a36b388c0c7762e5102e2e0) (cherry picked from commit 5d9e54065ed18c51e4f25d8900635f90810c7394) (cherry picked from commit 97546df8d6900b115536c17af9213f1da837b82e) (cherry picked from commit 5e7cd3e7ed7c894550ca35514708ffe1874a31ad) --- ext/pdo_dblib/dblib_driver.c | 8 ++++++- ext/pdo_dblib/tests/GHSA-5hqh-c84r-qjcv.phpt | 24 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 ext/pdo_dblib/tests/GHSA-5hqh-c84r-qjcv.phpt diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c index 13526092ea..6fa650e4da 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -156,6 +156,7 @@ static int dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unqu size_t i; char * q; + size_t extralen = 0; *quotedlen = 0; if (H->assume_national_character_set_strings) { @@ -170,7 +171,7 @@ static int dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unqu /* Detect quoted length, adding extra char for doubled single quotes */ for (i = 0; i < unquotedlen; i++) { - if (unquoted[i] == '\'') ++*quotedlen; + if (unquoted[i] == '\'') ++extralen; ++*quotedlen; } @@ -178,6 +179,11 @@ static int dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unqu if (use_national_character_set) { ++*quotedlen; /* N prefix */ } + if (UNEXPECTED(*quotedlen > ZSTR_MAX_LEN - extralen)) { + return 0; + } + + *quotedlen += extralen; q = *quoted = emalloc(*quotedlen + 1); /* Add byte for terminal null */ if (use_national_character_set) { *q++ = 'N'; diff --git a/ext/pdo_dblib/tests/GHSA-5hqh-c84r-qjcv.phpt b/ext/pdo_dblib/tests/GHSA-5hqh-c84r-qjcv.phpt new file mode 100644 index 0000000000..431c61951e --- /dev/null +++ b/ext/pdo_dblib/tests/GHSA-5hqh-c84r-qjcv.phpt @@ -0,0 +1,24 @@ +--TEST-- +GHSA-5hqh-c84r-qjcv (Integer overflow in the dblib quoter causing OOB writes) +--EXTENSIONS-- +pdo_dblib +--SKIPIF-- + +--INI-- +memory_limit=-1 +--FILE-- +quote(str_repeat("'", 2147483646))); + +?> +--EXPECT-- +bool(false) -- 2.47.0 From 8a4f389396493a43f9de9ba48920b6a82b6d1370 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 24 Oct 2024 22:02:36 +0200 Subject: [PATCH 2/9] Fix GHSA-5hqh-c84r-qjcv: Integer overflow in the firebird quoter causing OOB writes (cherry picked from commit 69c5f68fdc3deed9ebce2cc44b4bf5e0c47cd28f) (cherry picked from commit b4f73be75dbdde970a18cc7a636898b10400fb3f) (cherry picked from commit 0530cbfe5c3044537de52d8382eba5d69dbac726) (cherry picked from commit 72d4c4e435544c2d87d634188d480099345b601b) --- ext/pdo_firebird/firebird_driver.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index 1e2e7746fa..b238ea630e 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -243,7 +243,7 @@ free_statement: static int firebird_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, /* {{{ */ char **quoted, size_t *quotedlen, enum pdo_param_type paramtype) { - int qcount = 0; + size_t qcount = 0; char const *co, *l, *r; char *c; @@ -258,6 +258,10 @@ static int firebird_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t u /* count the number of ' characters */ for (co = unquoted; (co = strchr(co,'\'')); qcount++, co++); + if (UNEXPECTED(unquotedlen + 2 > ZSTR_MAX_LEN - qcount)) { + return 0; + } + *quotedlen = unquotedlen + qcount + 2; *quoted = c = emalloc(*quotedlen+1); *c++ = '\''; -- 2.47.0 From ff868946218d6d1661a0c35757e2058cb3ed23ec Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Fri, 22 Nov 2024 15:24:16 +0100 Subject: [PATCH 3/9] backport ZSTR_MAX_LEN (cherry picked from commit 37056ad634d9c44bac0d6c8e730eafaec1344840) --- Zend/zend_string.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Zend/zend_string.h b/Zend/zend_string.h index 784b88ea6a..5f7a9ea2b3 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -74,6 +74,9 @@ END_EXTERN_C() #define _ZSTR_STRUCT_SIZE(len) (_ZSTR_HEADER_SIZE + len + 1) +#define ZSTR_MAX_OVERHEAD (ZEND_MM_ALIGNED_SIZE(_ZSTR_HEADER_SIZE + 1)) +#define ZSTR_MAX_LEN (SIZE_MAX - ZSTR_MAX_OVERHEAD) + #define ZSTR_ALLOCA_ALLOC(str, _len, use_heap) do { \ (str) = (zend_string *)do_alloca(ZEND_MM_ALIGNED_SIZE_EX(_ZSTR_STRUCT_SIZE(_len), 8), (use_heap)); \ GC_REFCOUNT(str) = 1; \ -- 2.47.0