From f01c13a619a3c87608a425b2500637a417ca7954 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 2 May 2022 23:26:46 -0600 Subject: [PATCH] gh-89289: Harden sqlite3.Connection init - Make sure SQLite resources are freed if database open fails - Remove unneeded branches if init is aborted --- Modules/_sqlite/connection.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index fe244c8b22771a..00421165922670 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -226,27 +226,27 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, pysqlite_state *state = pysqlite_get_state_by_type(Py_TYPE(self)); if (rc != SQLITE_OK) { _pysqlite_seterror(state, db); - return -1; + goto error; } // Create LRU statement cache; returns a new reference. PyObject *statement_cache = new_statement_cache(self, state, cache_size); if (statement_cache == NULL) { - return -1; + goto error; } /* Create lists of weak references to cursors and blobs */ PyObject *cursors = PyList_New(0); if (cursors == NULL) { - Py_XDECREF(statement_cache); - return -1; + Py_DECREF(statement_cache); + goto error; } PyObject *blobs = PyList_New(0); if (blobs == NULL) { - Py_XDECREF(statement_cache); - Py_XDECREF(cursors); - return -1; + Py_DECREF(statement_cache); + Py_DECREF(cursors); + goto error; } // Init connection state members. @@ -279,11 +279,18 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, self->NotSupportedError = state->NotSupportedError; if (PySys_Audit("sqlite3.connect/handle", "O", self) < 0) { - return -1; + return -1; // Don't goto error; at this point, dealloc will clean up. } self->initialized = 1; return 0; + +error: + // There are no statements or other SQLite objects attached to the + // database, so sqlite3_close() should always return SQLITE_OK. + rc = sqlite3_close(db); + assert(rc == SQLITE_OK), rc; + return -1; } #define VISIT_CALLBACK_CONTEXT(ctx) \