diff --git a/NEWS b/NEWS index 7aada8213bb5..a813980b77b1 100644 --- a/NEWS +++ b/NEWS @@ -43,6 +43,8 @@ PHP NEWS - PDO_ODBC: . Fixed bug GH-20726 (Crash with ODBC connection pooling when the DSN carries no credentials). (iliaal) + . Fixed bug GH-22665 (Out-of-bounds write when the ODBC driver reports a + diagnostic message length beyond the error buffer). (iliaal) - Phar: . Fixed inconsistent handling of the magic ".phar" directory. Paths such as diff --git a/ext/pdo_odbc/odbc_driver.c b/ext/pdo_odbc/odbc_driver.c index 2cdac30223c0..3bb028ed6314 100644 --- a/ext/pdo_odbc/odbc_driver.c +++ b/ext/pdo_odbc/odbc_driver.c @@ -90,6 +90,8 @@ void pdo_odbc_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, PDO_ODBC_HSTMT statement, if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { errmsgsize = 0; + } else if ((size_t) errmsgsize >= sizeof(einfo->last_err_msg)) { + errmsgsize = sizeof(einfo->last_err_msg) - 1; } einfo->last_err_msg[errmsgsize] = '\0'; diff --git a/ext/pdo_odbc/tests/gh22665.phpt b/ext/pdo_odbc/tests/gh22665.phpt new file mode 100644 index 000000000000..aa3eaf914c93 --- /dev/null +++ b/ext/pdo_odbc/tests/gh22665.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-22665 (OOB write in pdo_odbc_error when the driver reports a long message) +--EXTENSIONS-- +pdo_odbc +--SKIPIF-- + +--FILE-- + PDO::ERRMODE_SILENT, +]); + +// A failing query with a long identifier makes the driver report a diagnostic +// message length >= the fixed last_err_msg buffer. The terminator write must +// stay inside the buffer. +$pdo->query('SELECT * FROM "' . str_repeat('A', 4096) . '"'); +$info = $pdo->errorInfo(); + +echo "sqlstate: ", $info[0], "\n"; +echo "done\n"; +?> +--EXPECT-- +sqlstate: HY000 +done