sqlite: fix use-after-free in StatementSync due to premature GC · nodejs/node@8410c95

@@ -535,7 +535,8 @@ void DatabaseSync::Prepare(const FunctionCallbackInfo<Value>& args) {

535535

sqlite3_stmt* s = nullptr;

536536

int r = sqlite3_prepare_v2(db->connection_, *sql, -1, &s, 0);

537537

CHECK_ERROR_OR_THROW(env->isolate(), db, r, SQLITE_OK, void());

538-

BaseObjectPtr<StatementSync> stmt = StatementSync::Create(env, db, s);

538+

BaseObjectPtr<StatementSync> stmt =

539+

StatementSync::Create(env, BaseObjectPtr<DatabaseSync>(db), s);

539540

db->statements_.insert(stmt.get());

540541

args.GetReturnValue().Set(stmt->object());

541542

}

@@ -946,11 +947,10 @@ void DatabaseSync::LoadExtension(const FunctionCallbackInfo<Value>& args) {

946947947948

StatementSync::StatementSync(Environment* env,

948949

Local<Object> object,

949-

DatabaseSync* db,

950+

BaseObjectPtr<DatabaseSync> db,

950951

sqlite3_stmt* stmt)

951-

: BaseObject(env, object) {

952+

: BaseObject(env, object), db_(std::move(db)) {

952953

MakeWeak();

953-

db_ = db;

954954

statement_ = stmt;

955955

// In the future, some of these options could be set at the database

956956

// connection level and inherited by statements to reduce boilerplate.

@@ -977,7 +977,7 @@ inline bool StatementSync::IsFinalized() {

977977978978

bool StatementSync::BindParams(const FunctionCallbackInfo<Value>& args) {

979979

int r = sqlite3_clear_bindings(statement_);

980-

CHECK_ERROR_OR_THROW(env()->isolate(), db_, r, SQLITE_OK, false);

980+

CHECK_ERROR_OR_THROW(env()->isolate(), db_.get(), r, SQLITE_OK, false);

981981982982

int anon_idx = 1;

983983

int anon_start = 0;

@@ -1107,7 +1107,7 @@ bool StatementSync::BindValue(const Local<Value>& value, const int index) {

11071107

return false;

11081108

}

110911091110-

CHECK_ERROR_OR_THROW(env()->isolate(), db_, r, SQLITE_OK, false);

1110+

CHECK_ERROR_OR_THROW(env()->isolate(), db_.get(), r, SQLITE_OK, false);

11111111

return true;

11121112

}

11131113

@@ -1173,7 +1173,7 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {

11731173

env, stmt->IsFinalized(), "statement has been finalized");

11741174

Isolate* isolate = env->isolate();

11751175

int r = sqlite3_reset(stmt->statement_);

1176-

CHECK_ERROR_OR_THROW(isolate, stmt->db_, r, SQLITE_OK, void());

1176+

CHECK_ERROR_OR_THROW(isolate, stmt->db_.get(), r, SQLITE_OK, void());

1177117711781178

if (!stmt->BindParams(args)) {

11791179

return;

@@ -1202,7 +1202,7 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {

12021202

rows.emplace_back(row);

12031203

}

120412041205-

CHECK_ERROR_OR_THROW(isolate, stmt->db_, r, SQLITE_DONE, void());

1205+

CHECK_ERROR_OR_THROW(isolate, stmt->db_.get(), r, SQLITE_DONE, void());

12061206

args.GetReturnValue().Set(Array::New(isolate, rows.data(), rows.size()));

12071207

}

12081208

@@ -1270,7 +1270,8 @@ void StatementSync::IterateNextCallback(

1270127012711271

int r = sqlite3_step(stmt->statement_);

12721272

if (r != SQLITE_ROW) {

1273-

CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_, r, SQLITE_DONE, void());

1273+

CHECK_ERROR_OR_THROW(

1274+

env->isolate(), stmt->db_.get(), r, SQLITE_DONE, void());

1274127512751276

// cleanup when no more rows to fetch

12761277

sqlite3_reset(stmt->statement_);

@@ -1322,7 +1323,7 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {

13221323

auto isolate = env->isolate();

13231324

auto context = env->context();

13241325

int r = sqlite3_reset(stmt->statement_);

1325-

CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_, r, SQLITE_OK, void());

1326+

CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_.get(), r, SQLITE_OK, void());

1326132713271328

if (!stmt->BindParams(args)) {

13281329

return;

@@ -1386,7 +1387,7 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {

13861387

env, stmt->IsFinalized(), "statement has been finalized");

13871388

Isolate* isolate = env->isolate();

13881389

int r = sqlite3_reset(stmt->statement_);

1389-

CHECK_ERROR_OR_THROW(isolate, stmt->db_, r, SQLITE_OK, void());

1390+

CHECK_ERROR_OR_THROW(isolate, stmt->db_.get(), r, SQLITE_OK, void());

1390139113911392

if (!stmt->BindParams(args)) {

13921393

return;

@@ -1396,7 +1397,7 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {

13961397

r = sqlite3_step(stmt->statement_);

13971398

if (r == SQLITE_DONE) return;

13981399

if (r != SQLITE_ROW) {

1399-

THROW_ERR_SQLITE_ERROR(isolate, stmt->db_);

1400+

THROW_ERR_SQLITE_ERROR(isolate, stmt->db_.get());

14001401

return;

14011402

}

14021403

@@ -1432,7 +1433,7 @@ void StatementSync::Run(const FunctionCallbackInfo<Value>& args) {

14321433

THROW_AND_RETURN_ON_BAD_STATE(

14331434

env, stmt->IsFinalized(), "statement has been finalized");

14341435

int r = sqlite3_reset(stmt->statement_);

1435-

CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_, r, SQLITE_OK, void());

1436+

CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_.get(), r, SQLITE_OK, void());

1436143714371438

if (!stmt->BindParams(args)) {

14381439

return;

@@ -1441,7 +1442,7 @@ void StatementSync::Run(const FunctionCallbackInfo<Value>& args) {

14411442

auto reset = OnScopeLeave([&]() { sqlite3_reset(stmt->statement_); });

14421443

r = sqlite3_step(stmt->statement_);

14431444

if (r != SQLITE_ROW && r != SQLITE_DONE) {

1444-

THROW_ERR_SQLITE_ERROR(env->isolate(), stmt->db_);

1445+

THROW_ERR_SQLITE_ERROR(env->isolate(), stmt->db_.get());

14451446

return;

14461447

}

14471448

@@ -1597,9 +1598,8 @@ Local<FunctionTemplate> StatementSync::GetConstructorTemplate(

15971598

return tmpl;

15981599

}

159916001600-

BaseObjectPtr<StatementSync> StatementSync::Create(Environment* env,

1601-

DatabaseSync* db,

1602-

sqlite3_stmt* stmt) {

1601+

BaseObjectPtr<StatementSync> StatementSync::Create(

1602+

Environment* env, BaseObjectPtr<DatabaseSync> db, sqlite3_stmt* stmt) {

16031603

Local<Object> obj;

16041604

if (!GetConstructorTemplate(env)

16051605

->InstanceTemplate()

@@ -1608,7 +1608,7 @@ BaseObjectPtr<StatementSync> StatementSync::Create(Environment* env,

16081608

return BaseObjectPtr<StatementSync>();

16091609

}

161016101611-

return MakeBaseObject<StatementSync>(env, obj, db, stmt);

1611+

return MakeBaseObject<StatementSync>(env, obj, std::move(db), stmt);

16121612

}

1613161316141614

Session::Session(Environment* env,

@@ -1675,7 +1675,7 @@ void Session::Changeset(const FunctionCallbackInfo<Value>& args) {

16751675

void* pChangeset;

16761676

int r = sqliteChangesetFunc(session->session_, &nChangeset, &pChangeset);

16771677

CHECK_ERROR_OR_THROW(

1678-

env->isolate(), session->database_, r, SQLITE_OK, void());

1678+

env->isolate(), session->database_.get(), r, SQLITE_OK, void());

1679167916801680

auto freeChangeset = OnScopeLeave([&] { sqlite3_free(pChangeset); });

16811681