From 4dc08c85439850281b9889999d9028971442d70a Mon Sep 17 00:00:00 2001 From: Haruka Takatsuka Date: Thu, 24 Apr 2025 13:46:20 +0900 Subject: [PATCH 1/2] SQLFreeStmt(stmt,SQL_DROP) now returns an error before trying to free statement resources when its connection already has been closed. A crash occurred when the PostgreSQL server terminated and a connection was subsequently attempted from an application when connection pooling by the driver manager was enabled and several pooled connections existed. In such cases, an invalid memory access would occur in ENTER_CONN_CS(conn) in SQLFreeStmt(), or an invalid address free() would be attempted in SC_clear_error() via PGAPI_FreeStmt(). "CC_cleanup()" doing "conn->status = CONN_NOT_CONNECTED" releases all statements belonging to the connection, so this change will probably not cause a resource leak. --- odbcapi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/odbcapi.c b/odbcapi.c index a29092a3..20b27f44 100644 --- a/odbcapi.c +++ b/odbcapi.c @@ -399,6 +399,8 @@ SQLFreeStmt(HSTMT StatementHandle, if (Option == SQL_DROP) { conn = stmt->hdbc; + if (!conn || conn->status == CONN_NOT_CONNECTED) + return SQL_INVALID_HANDLE; if (conn) ENTER_CONN_CS(conn); } From de6194e898bf61fd6e3f5c3ff0d6b3c368becf7d Mon Sep 17 00:00:00 2001 From: Haruka Takatsuka Date: Thu, 24 Apr 2025 18:10:53 +0900 Subject: [PATCH 2/2] Make 4dc08c85439850281b9889999d9028971442d70a more robust. After continued testing, I found that the earlier fix alone caused crashes in similar attempts, so we improved the fix. --- odbcapi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/odbcapi.c b/odbcapi.c index 20b27f44..494b08dc 100644 --- a/odbcapi.c +++ b/odbcapi.c @@ -399,10 +399,12 @@ SQLFreeStmt(HSTMT StatementHandle, if (Option == SQL_DROP) { conn = stmt->hdbc; - if (!conn || conn->status == CONN_NOT_CONNECTED) + if (!conn || (conn->status != CONN_CONNECTED && conn->status != CONN_EXECUTING)) return SQL_INVALID_HANDLE; if (conn) ENTER_CONN_CS(conn); + if (!conn || (conn->status != CONN_CONNECTED && conn->status != CONN_EXECUTING)) + return SQL_INVALID_HANDLE; } else ENTER_STMT_CS(stmt);