Skip to content

Commit 2ae897f

Browse files
nielsdosGirgias
authored andcommitted
Fix crash in firebird statement dtor
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.
1 parent 99f8ec3 commit 2ae897f

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

ext/pdo_firebird/firebird_statement.c

+9-2
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,15 @@ static int firebird_stmt_dtor(pdo_stmt_t *stmt) /* {{{ */
8787
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
8888
int result = 1;
8989

90-
/* release the statement */
91-
if (isc_dsql_free_statement(S->H->isc_status, &S->stmt, DSQL_drop)) {
90+
/* TODO: for master, move this check to a separate function shared between pdo drivers.
91+
* pdo_pgsql and pdo_mysql do this exact same thing */
92+
bool server_obj_usable = !Z_ISUNDEF(stmt->database_object_handle)
93+
&& IS_OBJ_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE(stmt->database_object_handle)])
94+
&& !(OBJ_FLAGS(Z_OBJ(stmt->database_object_handle)) & IS_OBJ_FREE_CALLED);
95+
96+
/* release the statement.
97+
* Note: if the server object is already gone then the statement was closed already as well. */
98+
if (server_obj_usable && isc_dsql_free_statement(S->H->isc_status, &S->stmt, DSQL_drop)) {
9299
RECORD_ERROR(stmt);
93100
result = 0;
94101
}

0 commit comments

Comments
 (0)