From c8d90e7e18947084c003b0645718f8a40af94c58 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Tue, 30 Jun 2026 01:23:44 -0400 Subject: [PATCH 1/3] Fix GH-20726: crash in pdo_odbc with pooling and no credentials (#22512) When a DSN carries no credentials, dbh->username and dbh->password are NULL. With ODBC connection pooling enabled, the unixODBC driver manager compares the cached and requested credentials with strcmp() while matching a pooled connection, dereferencing the NULL pointers and crashing inside SQLConnect. Pass empty strings instead. This hardens the connect path; the pooling use-after-free in GH-20726 is a separate unixODBC defect. --- NEWS | 4 ++++ ext/pdo_odbc/odbc_driver.c | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 57d91e345457..d03a77b01d91 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,10 @@ PHP NEWS . Fixed IntlChar methods leaving stale global error state after successful calls. (Xuyang Zhang) +- PDO_ODBC: + . Fixed bug GH-20726 (Crash with ODBC connection pooling when the DSN + carries no credentials). (iliaal) + - Phar: . Fixed inconsistent handling of the magic ".phar" directory. Paths such as "/.phar" remain protected, while non-magic paths that merely start with diff --git a/ext/pdo_odbc/odbc_driver.c b/ext/pdo_odbc/odbc_driver.c index 1ddce74f3f92..2cdac30223c0 100644 --- a/ext/pdo_odbc/odbc_driver.c +++ b/ext/pdo_odbc/odbc_driver.c @@ -601,7 +601,11 @@ static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ dsnbuf, sizeof(dsnbuf)-1, &dsnbuflen, SQL_DRIVER_NOPROMPT); } if (!use_direct) { - rc = SQLConnect(H->dbc, (SQLCHAR *) dbh->data_source, SQL_NTS, (SQLCHAR *) dbh->username, SQL_NTS, (SQLCHAR *) dbh->password, SQL_NTS); + /* unixODBC pooling strcmp()s the credentials when matching a cached + * connection and crashes on a NULL username/password, so pass "". */ + rc = SQLConnect(H->dbc, (SQLCHAR *) dbh->data_source, SQL_NTS, + (SQLCHAR *) (dbh->username ? dbh->username : ""), SQL_NTS, + (SQLCHAR *) (dbh->password ? dbh->password : ""), SQL_NTS); } if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { From 004701d5aeba5e2e228c42fd4267449d751115e7 Mon Sep 17 00:00:00 2001 From: Matteo Beccati Date: Tue, 30 Jun 2026 11:28:05 +0000 Subject: [PATCH 2/3] [ci skip] Update NEWS for 8.6.0alpha2 --- NEWS | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 667a0bc591e3..650007b5a090 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.6.0alpha1 +?? ??? ????, PHP 8.6.0alpha2 + + +02 Jul 2026, PHP 8.6.0alpha1 - Core: . Added first-class callable cache to share instances for the duration of the From 2f3a1ec920054f7c658fa39e2d7e05fb0e041ae5 Mon Sep 17 00:00:00 2001 From: Weilin Du Date: Tue, 30 Jun 2026 21:14:58 +0800 Subject: [PATCH 3/3] [skip ci] docs/release-process.md: Update a link to php 8.6 release schedule Add the PHP 8.6 wiki TODO page to the release process schedule links. --- docs/release-process.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-process.md b/docs/release-process.md index c07f328f2d8c..570107492ac3 100644 --- a/docs/release-process.md +++ b/docs/release-process.md @@ -6,6 +6,7 @@ repository available according to the release schedule. The release schedule for each version is published on the [PHP wiki](https://wiki.php.net): +- [PHP 8.6](https://wiki.php.net/todo/php86) - [PHP 8.5](https://wiki.php.net/todo/php85) - [PHP 8.4](https://wiki.php.net/todo/php84) - [PHP 8.3](https://wiki.php.net/todo/php83)