From cee60784e8c25da9a5be7c6012ffef483d124d33 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) (cherry picked from commit c6ee9a7d0385e4cd6cf9dcd0104dd6714e2a968d) --- 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 dce1039061..b3077cbc7f 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -154,15 +154,21 @@ 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; /* Detect quoted length, adding extra char for doubled single quotes */ for(i=0;i ZSTR_MAX_LEN - extralen)) { + return 0; + } + + *quotedlen += extralen; q = *quoted = emalloc(*quotedlen+1); /* Add byte for terminal null */ *q++ = '\''; 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 fe1067ac5b79aaa3b691e6ef7fb4d36dcf9a6fff 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) (cherry picked from commit 8a4f389396493a43f9de9ba48920b6a82b6d1370) --- 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 f9ec0eb847..24d7c42093 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -290,7 +290,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; @@ -305,6 +305,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 351dee5281697c14712e261f560d671e1661e51a 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) (cherry picked from commit ff868946218d6d1661a0c35757e2058cb3ed23ec) --- Zend/zend_string.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Zend/zend_string.h b/Zend/zend_string.h index dbc3f3be78..b15f78cb1f 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -62,6 +62,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