Skip to content

WeakTag crash via unchecked ObjectInfo::Unwrap #35

Description

@theosotr
const { WeakTag, ObjectInfo } = require('./build/Release/weakref.node');
require('v8').setFlagsFromString('--expose-gc');
const gc = require('vm').runInNewContext('gc');

const wt = new WeakTag(new ObjectInfo({}, () => {}));
new WeakTag(wt);
gc();

Result:

FATAL ERROR: v8::HandleScope::CreateHandle() Cannot create a handle without a HandleScope
----- Native stack trace -----

 1: 0xe3605b node::OnFatalError(char const*, char const*) [node]
 2: 0x123eaa6 v8::Utils::ReportApiFailure(char const*, char const*) [node]
 3: 0x13eb8ba v8::internal::HandleScope::Extend(v8::internal::Isolate*) [node]
 4: 0x1240360 v8::EscapableHandleScopeBase::EscapableHandleScopeBase(v8::Isolate*) [node]
 5: 0xf308fa napi_open_escapable_handle_scope [node]
 6: 0x...      [weak-napi/build/Release/weakref.node]   // ObjectInfo::OnFree()'s callback
 7: 0x1d351a9  [node]
 8: 0x1d2d2cc uv_run [node]
 9: 0xe906d6 node::SpinEventLoopInternal(node::Environment*) [node]
10: 0xfe5661 node::NodeMainInstance::Run() [node]
11: 0xf480cb node::Start(int, char**) [node]
12: 0x7f...  [/lib/x86_64-linux-gnu/libc.so.6]
13: 0x7f...  __libc_start_main [/lib/x86_64-linux-gnu/libc.so.6]
14: 0xe8c9fe _start [node]

I think the problem is that WeakTag's constructor only checks IsObject(); ObjectInfo::Unwrap() then does a static_cast that returns a non-null WeakTag* mis-typed as ObjectInfo*, so the info_ == nullptr guard passes. The destructor of WeakTag later dereferences it in OnFree().

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