diff --git a/NEWS b/NEWS index 367860feb471..6b1e857a8708 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,8 @@ PHP NEWS driver-reported display size). (iliaal) . Fixed bug GH-22666 (Heap buffer overflow when an output parameter value is longer than the declared maxlen). (iliaal) + . Fixed bug GH-22665 (Out-of-bounds write when the ODBC driver reports a + diagnostic message length beyond the error buffer). (iliaal) - Reflection: . Fixed bug GH-22681 (Reflection*::__toString() truncates on null bytes). diff --git a/ext/pdo_odbc/odbc_driver.c b/ext/pdo_odbc/odbc_driver.c index e499c2fd45b9..dbdb0066578b 100644 --- a/ext/pdo_odbc/odbc_driver.c +++ b/ext/pdo_odbc/odbc_driver.c @@ -93,6 +93,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..d6edc62288e8 --- /dev/null +++ b/ext/pdo_odbc/tests/gh22665.phpt @@ -0,0 +1,32 @@ +--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