Closed
Bug 1455610
Opened 7 years ago
Closed 7 years ago
Crash [@ js::jit::Simulator::instructionDecode] with wasm GC
Categories
(Core :: JavaScript Engine, defect, P2)
Tracking
()
RESOLVED
FIXED
mozilla61
Tracking | Status | |
---|---|---|
firefox-esr52 | --- | unaffected |
firefox-esr60 | --- | unaffected |
firefox59 | --- | unaffected |
firefox60 | --- | unaffected |
firefox61 | --- | fixed |
People
(Reporter: decoder, Assigned: bbouvier)
References
Details
(4 keywords, Whiteboard: [jsbugmon:])
Crash Data
Attachments
(1 file, 1 obsolete file)
7.87 KB,
patch
|
lth
:
review+
|
Details | Diff | Splinter Review |
The following testcase crashes on mozilla-central revision cc0d7de218cb (build with --enable-posix-nspr-emulation --enable-valgrind --enable-gczeal --disable-tests --disable-profiling --enable-debug --without-intl-api --enable-optimize --target=i686-pc-linux-gnu --enable-simulator=arm, run with --fuzzing-safe --ion-offthread-compile=off --wasm-gc --arm-asm-nop-fill=1):
function wasmEvalText(str, imports) {
let binary = wasmTextToBinary(str);
m = new WebAssembly.Module(binary);
return new WebAssembly.Instance(m, imports);
}
var f = wasmEvalText(`(module (func (result i32) (param i32)
(block $0
(block $1
(block $2
(block $default
(br_table $0 $1 $2 $default (get_local 0))
)
)
)
)
(return (i32.const 0))
) (export "" 0))`).exports[""];
f(0);
Backtrace:
received signal SIGSEGV, Segmentation fault.
js::jit::Simulator::instructionDecode (this=0xf6e58000, instr=0xeaffffff) at js/src/jit/arm/Simulator-arm.cpp:4832
#0 js::jit::Simulator::instructionDecode (this=0xf6e58000, instr=0xeaffffff) at js/src/jit/arm/Simulator-arm.cpp:4832
#1 0x085f82ea in js::jit::Simulator::execute<false> (this=0xf6e58000) at js/src/jit/arm/Simulator-arm.cpp:4911
#2 js::jit::Simulator::callInternal (this=0xf6e58000, entry=0x40dca138 "\377\377\377\352\004\340-\345\377\377\377\352\360\037-\351\377\377\377\352\020\212-\355\377\377\377", <incomplete sequence \352>) at js/src/jit/arm/Simulator-arm.cpp:4991
#3 0x085f8509 in js::jit::Simulator::call (this=<optimized out>, entry=<optimized out>, argument_count=<optimized out>) at js/src/jit/arm/Simulator-arm.cpp:5074
#4 0x089c51e7 in js::wasm::Instance::callExport (this=<optimized out>, cx=<optimized out>, funcIndex=<optimized out>, args=...) at js/src/wasm/WasmInstance.cpp:780
#5 0x089c5b5b in WasmCall (cx=<optimized out>, argc=1, vp=0xf561d058) at js/src/wasm/WasmJS.cpp:1233
#6 0x081ed899 in js::CallJSNative (cx=0xf6e1d800, native=0x89c5ab0 <WasmCall(JSContext*, unsigned int, JS::Value*)>, args=...) at js/src/vm/JSContext-inl.h:280
[..]
#20 main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at js/src/shell/js.cpp:9234
eax 0x1 1
ebx 0xf6e58000 -152731648
ecx 0x0 0
edx 0xf579f6a0 -176556384
esi 0xeaffffff -352321537
edi 0x8e3aff4 149139444
ebp 0xffffbd28 4294950184
esp 0xffffbd00 4294950144
eip 0x85f432f <js::jit::Simulator::instructionDecode(js::jit::SimInstruction*)+47>
=> 0x85f432f <js::jit::Simulator::instructionDecode(js::jit::SimInstruction*)+47>: mov (%esi),%edx
0x85f4331 <js::jit::Simulator::instructionDecode(js::jit::SimInstruction*)+49>: mov %edx,%eax
Not s-s because it requires --wasm-gc which is disabled right now.
Comment 1•7 years ago
|
||
JSBugMon: Cannot process bug: Unable to automatically reproduce, please track manually.
Whiteboard: [jsbugmon:update,bisect] → [jsbugmon:bisect]
Updated•7 years ago
|
Whiteboard: [jsbugmon:bisect] → [jsbugmon:]
Comment 2•7 years ago
|
||
I guess we knew we might run into some of these issues. If it's only the debugger that's affected we probably shouldn't panic, but worth tracking these.
Blocks: 1444925
Comment 3•7 years ago
|
||
(Sigh, comment 2 pertained to another bug. This one is probably more serious but doesn't appear to be about the GC being disabled.)
Assignee | ||
Comment 4•7 years ago
|
||
For what it's worth, I've started investigating: it seems the issue happens during the table switch, where we read the case entry and write it into pc; the case entry contains a NOP fill instruction (not an address!), so we jump to the encoding of the NOP instruction, hence crash. Somebody needs to investigate a bit more there, but there might be places which lack AutoForbidPools, maybe.
Assignee | ||
Comment 5•7 years ago
|
||
Trivial patch, just took some time to investigate. We should not allow nop fills in the jump table, obviously.
Comment 6•7 years ago
|
||
Hm, probably not this. First, we need to worry about other platforms too (ARM64 in particular but I'm guessing also MIPS). There is a nopfill concept on ARM64 though it's poorly developed right now, and it would be better for us if it didn't bite us when it gets better. Second, Sean said (in Paris) that AutoFlushPools is severely limited on some platforms to a small instruction window, he guessed four instructions but didn't know for sure and I've not dug into it. So using that here might not be safe?
What we really want is explicitly to disable NOP fill, I expect. There must be a way to do that apart from AutoForbidPools, which has a lot of semantics associated with flushing and so on?
Assignee | ||
Comment 7•7 years ago
|
||
So something more like this? (added ARM64 support; the MIPS assemblers don't use the buffer which inserts nops)
Attachment #8970551 -
Attachment is obsolete: true
Attachment #8970551 -
Flags: review?(lhansen)
Attachment #8970593 -
Flags: review?(lhansen)
Updated•7 years ago
|
Priority: -- → P2
Updated•7 years ago
|
status-firefox59:
--- → unaffected
status-firefox60:
--- → unaffected
status-firefox-esr52:
--- → unaffected
status-firefox-esr60:
--- → unaffected
Updated•7 years ago
|
Comment 8•7 years ago
|
||
Comment on attachment 8970593 [details] [diff] [review]
autoforbidnops.patch
Review of attachment 8970593 [details] [diff] [review]:
-----------------------------------------------------------------
::: js/src/jit/shared/IonAssemblerBufferWithConstantPools.h
@@ +641,5 @@
> // checking that instruction locations are correctly referenced and/or
> // followed.
> const uint32_t nopFillInst_;
> const unsigned nopFill_;
> +
Looks like a spurious space at the beginning of the line.
::: js/src/wasm/WasmBaselineCompile.cpp
@@ +3835,5 @@
> // constant pool entries.
> masm.flush();
>
> +#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)
> + // Prevent nop slides to appear in the jump table.
Are we sure "nop slide" is the word we want here (also in the name of the test case)? To my mind, a "nop slide" is something that is created by careful manipulation of the compiler so as to create a sequence that can be used for an attack.
How about the more neutral "nop sequences" or even "fuzzing-requested nop sequences", since these nops only appear (I think) as a result of the shell's command line argument?
Attachment #8970593 -
Flags: review?(lhansen) → review+
Pushed by bbouvier@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/bc311a047273
Prevent nop fills from happening in jump tables; r=lth
Comment 10•7 years ago
|
||
bugherder |
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla61
You need to log in
before you can comment on or make changes to this bug.
Description
•