Skip to content

Fix GH-23741: pdo_dblib use-after-free of statement error state - #312

Closed
iliaal wants to merge 1 commit into
PHP-8.4from
fix/gh-23741-dblib-stmt-err-lifetime
Closed

iliaal wants to merge 1 commit into
PHP-8.4from
fix/gh-23741-dblib-stmt-err-lifetime

Conversation

@iliaal

@iliaal iliaal commented Sep 17, 2026

Copy link
Copy Markdown
Owner

pdo_dblib_stmt_execute() publishes the statement's error struct to the DBPROCESS with dbsetuserdata(), and FreeTDS keeps handing that pointer to the message handlers for the rest of the connection's life, long after the statement is freed. A statement cannot take the pointer back from its own destructor, since a GC cycle can free the connection handle first, so every function that hands the link to libdblib now installs the error struct it owns.

A failing beginTransaction(), commit(), rollBack() or lastInsertId() now reports its error; the stale SQLSTATE write previously left dbh->error_code untouched, so PDO stayed silent. rollBack() returns false in the reporter's script for an unrelated reason, SQL Server having already rolled the batch back itself, so the test does not assert its return value.

pdo_dblib_stmt_execute() published &S->err to the DBPROCESS through
dbsetuserdata(), but FreeTDS keeps handing that pointer to the error and
message handlers for the life of the connection, long after the statement is
freed. A statement cannot retract it from its own destructor, since a GC
cycle can free the connection handle first, so every function that hands
H->link to libdblib now installs the pdo_dblib_err it owns. get_column_meta()
also stops allocating return_value before the dbcoltypeinfo() check that can
fail, which the new test would otherwise leak.

Fixes phpGH-23741
@iliaal
iliaal force-pushed the fix/gh-23741-dblib-stmt-err-lifetime branch from a1eb33e to 32d1793 Compare September 17, 2026 23:08
@iliaal

iliaal commented Sep 18, 2026

Copy link
Copy Markdown
Owner Author

Submitted upstream as php#23751.

@iliaal iliaal closed this Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant