diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc index c3b7d279f4dca0..6428828b093a39 100644 --- a/src/node_sqlite.cc +++ b/src/node_sqlite.cc @@ -1584,6 +1584,13 @@ void DatabaseSync::Exec(const FunctionCallbackInfo& args) { return; } + // Keep the database alive during sqlite3_exec(), which may call + // user-defined SQLite functions that trigger JavaScript callbacks. + // If the JavaScript callback drops all references to the database, + // the DatabaseSync could otherwise be garbage-collected while the + // SQLite callback is still executing, causing a use-after-free. + BaseObjectPtr guard(db); + Utf8Value sql(env->isolate(), args[0].As()); int r = sqlite3_exec(db->connection_, *sql, nullptr, nullptr, nullptr); CHECK_ERROR_OR_THROW(env->isolate(), db, r, SQLITE_OK, void()); @@ -2358,6 +2365,13 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo& args) { } } + // Keep the database alive during sqlite3changeset_apply(), which may + // call conflict or filter callbacks that trigger JavaScript execution. + // If the JavaScript callback drops all references to the database, + // the DatabaseSync could otherwise be garbage-collected while the + // callback is still executing, causing a use-after-free. + BaseObjectPtr guard(db); + ArrayBufferViewContents buf(args[0]); int r = sqlite3changeset_apply( db->connection_,