Skip to content

Commit

Permalink
Fix crash in firebird statement dtor
Browse files Browse the repository at this point in the history
If both the driver object and statement end up in the GC buffer and are
freed by the GC, then the destruction order is not deterministic and it
is possible that the driver object is freed before the statement. In
that case, accessing S->H will cause a UAF. As the resources are already
released we simply skip the destruction if the driver object is already
destroyed.
  • Loading branch information
nielsdos committed Jan 24, 2025
1 parent c20ddd2 commit 4eaf084
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions ext/pdo_firebird/firebird_statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,15 @@ static int firebird_stmt_dtor(pdo_stmt_t *stmt) /* {{{ */
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
int result = 1;

/* release the statement */
if (isc_dsql_free_statement(S->H->isc_status, &S->stmt, DSQL_drop)) {
/* TODO: for master, move this check to a separate function shared between pdo drivers.
* pdo_pgsql and pdo_mysql do this exact same thing */
bool server_obj_usable = !Z_ISUNDEF(stmt->database_object_handle)
&& IS_OBJ_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE(stmt->database_object_handle)])
&& !(OBJ_FLAGS(Z_OBJ(stmt->database_object_handle)) & IS_OBJ_FREE_CALLED);

/* release the statement.
* Note: if the server object is already gone then the statement was closed already as well. */
if (server_obj_usable && isc_dsql_free_statement(S->H->isc_status, &S->stmt, DSQL_drop)) {
RECORD_ERROR(stmt);
result = 0;
}
Expand Down

0 comments on commit 4eaf084

Please sign in to comment.