Skip to content

ext/sqlite3: fix use-after-free when replacing the authorizer from its own callback - #23813

Open
jvoisin wants to merge 1 commit into
php:masterfrom
jvoisin:uaf_sqlite
Open

jvoisin wants to merge 1 commit into
php:masterfrom
jvoisin:uaf_sqlite

Conversation

@jvoisin

@jvoisin jvoisin commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

SQLite3::setAuthorizer() frees the previously registered authorizer with zend_fcc_dtor(&db_obj->authorizer_fcc) before installing the new one. The authorizer callback is invoked during statement preparation with db_obj->in_callback incremented, so calling setAuthorizer() from inside the authorizer destroys the fcc that is still executing. For a non-closure callback such as [$obj, 'method'] whose object is only referenced by the fcc, this releases $this while its method is still on the stack, resulting in a use-after-free (closures are kept alive by the call frame, method receivers are not).

Reject the call while inside a callback, mirroring the existing guard in SQLite3::close(). createFunction()/createAggregate()/createCollation() append to linked lists and only free their fcc at database close, so they are not affected.

…s own callback

SQLite3::setAuthorizer() frees the previously registered authorizer with
zend_fcc_dtor(&db_obj->authorizer_fcc) before installing the new one. The
authorizer callback is invoked during statement preparation with
db_obj->in_callback incremented, so calling setAuthorizer() from inside the
authorizer destroys the fcc that is still executing. For a non-closure
callback such as [$obj, 'method'] whose object is only referenced by the fcc,
this releases $this while its method is still on the stack, resulting in a
use-after-free (closures are kept alive by the call frame, method receivers
are not).

Reject the call while inside a callback, mirroring the existing guard in
SQLite3::close(). createFunction()/createAggregate()/createCollation() append
to linked lists and only free their fcc at database close, so they are not
affected.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant