Skip to content

ext/mysqlnd: Fix crash after metadata EOF failure on prepared statements - #354

Closed
iliaal wants to merge 1 commit into
PHP-8.4from
fix/aph-mysqlnd-result-memset-null-deref-84
Closed

iliaal wants to merge 1 commit into
PHP-8.4from
fix/aph-mysqlnd-result-memset-null-deref-84

Conversation

@iliaal

@iliaal iliaal commented Sep 24, 2026 •

Copy link
Copy Markdown
Owner

When the EOF packet after result set metadata cannot be read, mysqlnd_stmt_prepare_read_eof() and mysqlnd_query_read_result_set_header() both memset the whole statement, clearing error_info, upsert_status, and conn. The next errno or error access on the statement then dereferences NULL. A server that sends a truncated EOF packet, or closes the connection after the column definitions, crashes mysqli_stmt::execute(), PDOStatement::execute(), and mysqli_stmt::prepare() after stmt_init().

Both sites now free only the result and keep the statement intact, matching the store-result failure handling in mysqlnd_ps.c. A short EOF packet sets CR_MALFORMED_PACKET, and a failed prepare copies the connection error to the statement, so the failure is reported instead of returning false with errno 0.

Reproduced with the fake_server.inc harness on an ASAN build of PHP-8.4: SEGV at 0x250 in mysqlnd_stmt_execute_parse_response() and at 0x208 in mysqlnd_stmt_errno_pub(). The five new tests are red before and green after; ghsa-r6x9-5r99-36j7-stmt-response-row-status.phpt now asserts the exception that was previously missing.

@iliaal
iliaal force-pushed the fix/aph-mysqlnd-result-memset-null-deref-84 branch from 45826ac to 99302f0 Compare November 7, 2026 18:24
@iliaal iliaal changed the title ext/mysqlnd: Preserve statement state on result EOF failure ext/mysqlnd: Fix crash after metadata EOF failure on prepared statements Nov 7, 2026
When the EOF packet after result set metadata could not be read, both
mysqlnd_stmt_prepare_read_eof() and mysqlnd_query_read_result_set_header()
memset the whole statement, clearing error_info, upsert_status and conn, so
the next errno or error access dereferenced NULL. Free only the result and
keep the statement intact. A short EOF packet now sets CR_MALFORMED_PACKET,
and a failed prepare copies the connection error to the statement, so the
failure is reported instead of returning false with errno 0.
@iliaal
iliaal force-pushed the fix/aph-mysqlnd-result-memset-null-deref-84 branch from 99302f0 to c79c11d Compare November 7, 2026 19:21
@iliaal

iliaal commented Nov 7, 2026

Copy link
Copy Markdown
Owner Author

Submitted upstream as php#25297.

@iliaal iliaal closed this Nov 7, 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