Closed Bug 1833545 Opened 1 year ago Closed 1 year ago

Assertion failure: whyMagic() == why, at /builds/worker/workspace/obj-build/dist/include/js/Value.h:863

Categories

(Core :: JavaScript Engine, defect, P1)

defect

Tracking

()

RESOLVED FIXED
115 Branch
Tracking Status
firefox115 --- fixed

People

(Reporter: phambao1340, Assigned: mgaudet)

References

(Blocks 3 open bugs)

Details

(Whiteboard: [reporter-external] [client-bounty-form] [verif?])

Attachments

(1 file)

Run following javascript code

function* f1(a2, a3, ...a4) {
    const v6 = a4 ;
    return this;
}
const v10 = f1();
function f11(a12) {
    const v14 = [this];
    const o15 = {
        "start": a12,
    };
    return shortestPaths(v14, o15);
}
const v18 = `return ${f11}`;
const t16 = Function(v18.replaceAll(v18, v18));
const v22 = t16();
const v23 = v22(Function);
v23.reduce(v22).toSource();

Stack Trace

    #0 0x56552d092788 in isMagic /builds/worker/workspace/obj-build/dist/include/js/Value.h:863:5
    #1 0x56552d092788 in js::WrappedPtrOperations<JS::Value, JS::MutableHandle<JS::Value>, void>::isMagic(JSWhyMagic) const /builds/worker/workspace/obj-build/dist/include/js/Value.h:1332:55
    #2 0x56552d3c9caa in HasAndGetElement<unsigned long> /builds/worker/checkouts/gecko/js/src/builtin/Array.cpp:296:15
    #3 0x56552d3c9caa in bool HasAndGetElement<unsigned long>(JSContext*, JS::Handle<JSObject*>, unsigned long, bool*, JS::MutableHandle<JS::Value>) /builds/worker/checkouts/gecko/js/src/builtin/Array.cpp:333:10
    #4 0x56552d3c94da in js::ArrayToSource(JSContext*, JS::Handle<JSObject*>) /builds/worker/checkouts/gecko/js/src/builtin/Array.cpp:1086:10
    #5 0x56552d40fc7c in array_toSource(JSContext*, unsigned int, JS::Value*) /builds/worker/checkouts/gecko/js/src/builtin/Array.cpp:1135:19
    #6 0x56552d3707ae in CallJSNative /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:486:13
    #7 0x56552d3707ae in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:580:12
    #8 0x56552d37241f in InternalCall /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:647:10
    #9 0x56552d37241f in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:679:8
    #10 0x56552d5a6724 in js::Call(JSContext*, JS::Handle<JS::Value>, JSObject*, JS::MutableHandle<JS::Value>) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.h:109:10
    #11 0x56552d8f0014 in js::ValueToSource(JSContext*, JS::Handle<JS::Value>) /builds/worker/checkouts/gecko/js/src/vm/ToSource.cpp:189:14
    #12 0x56552d4789bd in js::ObjectToSource(JSContext*, JS::Handle<JSObject*>)::$_3::operator()(JS::Handle<JS::PropertyKey>, JS::Handle<JS::Value>, PropertyKind) const /builds/worker/checkouts/gecko/js/src/builtin/Object.cpp:361:32
    #13 0x56552d477d0f in js::ObjectToSource(JSContext*, JS::Handle<JSObject*>) /builds/worker/checkouts/gecko/js/src/builtin/Object.cpp
    #14 0x56552d4af0c7 in obj_toSource(JSContext*, unsigned int, JS::Value*) /builds/worker/checkouts/gecko/js/src/builtin/Object.cpp:177:19
    #15 0x56552d3707ae in CallJSNative /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:486:13
    #16 0x56552d3707ae in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:580:12
    #17 0x56552d37241f in InternalCall /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:647:10
    #18 0x56552d37241f in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:679:8
    #19 0x56552d5a6724 in js::Call(JSContext*, JS::Handle<JS::Value>, JSObject*, JS::MutableHandle<JS::Value>) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.h:109:10
    #20 0x56552d8f0014 in js::ValueToSource(JSContext*, JS::Handle<JS::Value>) /builds/worker/checkouts/gecko/js/src/vm/ToSource.cpp:189:14
    #21 0x56552d3c956e in js::ArrayToSource(JSContext*, JS::Handle<JSObject*>) /builds/worker/checkouts/gecko/js/src/builtin/Array.cpp:1095:13
    #22 0x56552d40fc7c in array_toSource(JSContext*, unsigned int, JS::Value*) /builds/worker/checkouts/gecko/js/src/builtin/Array.cpp:1135:19
    #23 0x56552d3707ae in CallJSNative /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:486:13
    #24 0x56552d3707ae in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:580:12
    #25 0x56552d37241f in InternalCall /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:647:10
    #26 0x56552d37241f in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:679:8
    #27 0x56552d5a6724 in js::Call(JSContext*, JS::Handle<JS::Value>, JSObject*, JS::MutableHandle<JS::Value>) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.h:109:10
    #28 0x56552d8f0014 in js::ValueToSource(JSContext*, JS::Handle<JS::Value>) /builds/worker/checkouts/gecko/js/src/vm/ToSource.cpp:189:14
    #29 0x56552d3c956e in js::ArrayToSource(JSContext*, JS::Handle<JSObject*>) /builds/worker/checkouts/gecko/js/src/builtin/Array.cpp:1095:13
    #30 0x56552d40fc7c in array_toSource(JSContext*, unsigned int, JS::Value*) /builds/worker/checkouts/gecko/js/src/builtin/Array.cpp:1135:19
    #31 0x56552d3707ae in CallJSNative /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:486:13
    #32 0x56552d3707ae in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:580:12
    #33 0x56552d392ad9 in InternalCall /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:647:10
    #34 0x56552d392ad9 in CallFromStack /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:652:10
    #35 0x56552d392ad9 in js::Interpret(JSContext*, js::RunState&) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:3395:16
    #36 0x56552d36fc07 in MaybeEnterInterpreterTrampoline /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:400:10
    #37 0x56552d36fc07 in js::RunScript(JSContext*, js::RunState&) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:458:13
    #38 0x56552d373fa9 in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JS::Handle<JSObject*>, js::AbstractFramePtr, JS::MutableHandle<JS::Value>) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:845:13
    #39 0x56552d54918d in JS_ExecuteScript(JSContext*, JS::Handle<JSScript*>) /builds/worker/checkouts/gecko/js/src/vm/CompilationAndEvaluation.cpp:496:10
    #40 0x56552d0b78e7 in RunFile(JSContext*, char const*, _IO_FILE*, CompileUtf8, bool, bool) /builds/worker/checkouts/gecko/js/src/shell/js.cpp:1098:10
    #41 0x56552d0b692e in Process(JSContext*, char const*, bool, FileKind) /builds/worker/checkouts/gecko/js/src/shell/js.cpp
    #42 0x56552d021baa in ProcessArgs /builds/worker/checkouts/gecko/js/src/shell/js.cpp:10591:10
    #43 0x56552d021baa in Shell(JSContext*, js::cli::OptionParser*) /builds/worker/checkouts/gecko/js/src/shell/js.cpp:10815:12
    #44 0x56552d016608 in main /builds/worker/checkouts/gecko/js/src/shell/js.cpp:11247:12
    #45 0x7fc2a2c29d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #46 0x7fc2a2c29e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #47 0x56552cf429d8 in _start (/home/zx/m-r-20230511191846-asan-opt/dist/bin/js+0x1eb59d8) (BuildId: 797afc6887b46f6022e82d4c49515c20ea5526d3)
Flags: sec-bounty?
Group: firefox-core-security → javascript-core-security
Component: Security → JavaScript Engine
Product: Firefox → Core

I'll take a closer look at this one today.

Flags: needinfo?(mgaudet)
Blocks: sm-runtime
Severity: -- → S4
Priority: -- → P1
// The crux of this bug is that Generators use real arrays as their
// stack storage, but we have some array helpers that do not imagine
// this to be possible.
//
// This should be entirely shell-only, and only possible with some of
// our testing functions. For example, the below test case is built out
// of `shortestPaths` which uses UBINode and GC mechanics to trace through
// paths user code can't.
//
// The fix here is mostly going to be to mark shortestPaths as fuzzing unsafe.

function* f1() {
    // At the initial yield v is our UninitializedLexical.
    const v = 10;
    return this;
}

// So at this point we have an uninitialized lexical accessible via shortestPaths
const v10 = f1();

function s() {
    const targets = [this];
    const options = { "start": Function }
    return shortestPaths(targets, options)
}
var paths = s();

// One of these paths include the saved stack for v10, which has
// on it a JS::MagicValue(JS_UNINITIALIZED_LEXICAL), which confuses and
// upsets the array object helper HasAndGetElement.
s().toSource();

Maybe generators shouldn't use real arrays stack storage, but for now, this is just a fuzzing unsafe API.

Flags: needinfo?(mgaudet)
Assignee: nobody → mgaudet
Status: NEW → ASSIGNED
Group: javascript-core-security
Blocks: 1835087
Pushed by mgaudet@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/4971297a8917 Mark shortestPaths as a fuzzing-unsafe function r=sfink
Status: ASSIGNED → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 115 Branch
Flags: sec-bounty? → sec-bounty-
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: