Skip to content

sqlite: option getters run user JS mid-call, then stale state is used #65586

Description

@TrevorBurnham

Version

v27.0.0-pre (21f0f2786f0)

Platform

Darwin 25.6.0 arm64

Subsystem

sqlite

What steps will reproduce the bug?

Several DatabaseSync methods (function, aggregate, deserialize, and backup) validate the connection, then read their options
bag with Object::Get(). A user-supplied getter runs arbitrary JavaScript at
that point, so anything checked before the read can be invalidated before it's
used. For example:

const { DatabaseSync } = require('node:sqlite');
const db = new DatabaseSync(':memory:');
db.function('f', { get useBigIntArguments() { db.close(); return false; } }, () => 1);

How often does it reproduce? Is there a required condition?

It reproduces consistently.

What is the expected behavior? Why is that the expected behavior?

A TypeError or ERR_INVALID_STATE, not a crash.

CreateSession() already gets this right: it parses the entire options bag
first, and only then unwraps the database, checks IsOpen(), and checks the
authorizer.

What do you see instead?

SIGSEGV (exit 139)

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions