Assertion failure: pc_ <= static_cast<int>(buffer_.size()), at regexp-bytecode-generator-inl.h
Categories
(Core :: JavaScript Engine, defect, P2)
Tracking
()
Tracking | Status | |
---|---|---|
firefox142 | --- | fixed |
People
(Reporter: fazim.pentester, Assigned: iain)
References
(Blocks 1 open bug)
Details
(Keywords: reporter-external, Whiteboard: [client-bounty-form])
Attachments
(2 files)
Windows debug build from python3 -m fuzzfetch --target js --debug --os Windows --cpu x86_64
:
./m-c-20250615134948-debug/dist/bin/js.exe testcase.js
[5620] Assertion failure: pc_ <= static_cast<int>(buffer_.size()), at /builds/worker/checkouts/gecko/js/src/irregexp/imported/regexp-bytecode-generator-inl.h:45
#01: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0x511938]
#02: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0x511e38]
#03: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0x16c48a1]
#04: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0x16c5c32]
#05: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0x16cf2b7]
#06: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0x16ce80d]
#07: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0x16cc044]
#08: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0x16c2e0f]
#09: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0x50dbec]
#10: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0xc42588]
#11: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0x103f2c1]
#12: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0x10377e9]
#13: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0xc13f37]
#14: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0xfb9443]
#15: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0xfb8c24]
#16: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0xfcc50e]
#17: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0xfb8264]
#18: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0xfb8d27]
#19: ???[C:\Browser\fuzzer\m-c-20250615134948-debug\dist\bin\js.exe +0x149f9aa]
#20: ??? (???:???)
MacOS Firefox debug build crash:
[27666] Assertion failure: pc_ <= static_cast<int>(buffer_.size()), at /Users/macos/Desktop/fuzzer/firefox/js/src/irregexp/imported/regexp-bytecode-generator-inl.h:45
#01: v8::internal::RegExpBytecodeGenerator::GoTo(v8::internal::Label*)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xb9f1b8]
#02: v8::internal::Trace::Flush(v8::internal::RegExpCompiler*, v8::internal::RegExpNode*, v8::internal::Trace::FlushMode)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xb794d0]
#03: v8::internal::RegExpNode::LimitVersions(v8::internal::RegExpCompiler*, v8::internal::Trace*)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xb7a998]
#04: v8::internal::ActionNode::Emit(v8::internal::RegExpCompiler*, v8::internal::Trace*)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xb82ddc]
#05: v8::internal::ChoiceNode::EmitChoices(v8::internal::RegExpCompiler*, v8::internal::AlternativeGenerationList*, int, v8::internal::Trace*, v8::internal::PreloadState*)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xb826c4]
#06: v8::internal::ChoiceNode::Emit(v8::internal::RegExpCompiler*, v8::internal::Trace*)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xb80a30]
#07: v8::internal::RegExpCompiler::Assemble(v8::internal::Isolate*, v8::internal::RegExpMacroAssembler*, v8::internal::RegExpNode*, int, v8::internal::Handle<v8::internal::String>)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xb77a58]
#08: js::irregexp::CompilePattern(JSContext*, JS::MutableHandle<js::RegExpShared*>, JS::Handle<JSLinearString*>, js::RegExpShared::CodeKind)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xb9b3c8]
#09: js::RegExpShared::execute(JSContext*, JS::MutableHandle<js::RegExpShared*>, JS::Handle<JSLinearString*>, unsigned long, js::VectorMatchPairs*)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0x432db4]
#10: ExecuteRegExp(JSContext*, JS::Handle<JSObject*>, JS::Handle<JSString*>, int, js::VectorMatchPairs*)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xb0b84]
#11: js::RegExpBuiltinExec(JSContext*, JS::Handle<js::RegExpObject*>, JS::Handle<JSString*>, bool, JS::MutableHandle<JS::Value>)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xa30dc]
#12: bool intrinsic_RegExpExec<true>(JSContext*, unsigned int, JS::Value*)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0x490080]
#13: CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), js::CallReason, JS::CallArgs const&)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xc2d0c]
#14: js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xc23d4]
#15: js::Interpret(JSContext*, js::RunState&)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xd2a20]
#16: js::RunScript(JSContext*, js::RunState&)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xc1910]
#17: js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xc23e4]
#18: js::jit::DoCallFallback(JSContext*, js::jit::BaselineFrame*, js::jit::ICFallbackStub*, unsigned int, JS::Value*, JS::MutableHandle<JS::Value>)[/Users/macos/Desktop/fuzzer/firefox/objdir-debug/dist/bin/js +0xcb075c]
zsh: segmentation fault ./firefox/objdir-debug/dist/bin/js test1.js
On Linux, getting Killed
.
Reporter | ||
Comment 1•6 days ago
|
||
macOS is using xnu-11417.121.6~2/RELEASE_ARM64_T6041 arm64
.
Comment 2•6 days ago
|
||
Looks like a very large regexp.
Comment 3•6 days ago
|
||
Does this also cause the same issue in v8? We're using their regexp engine.
Reporter | ||
Comment 4•6 days ago
|
||
For v8, I am getting OOM
for now using the same testcase:
<--- Last few GCs --->
[2228:0x55758e009000] 379195 ms: Scavenge 927.2 (959.8) -> 927.2 (959.8) MB, pooled: 0.0 MB, 5003.29 / 0.00 ms (average mu = 0.795, current mu = 0.795) allocation failure;
[2228:0x55758e009000] 383321 ms: Scavenge 927.2 (959.8) -> 927.2 (991.8) MB, pooled: 0.0 MB, 4125.43 / 0.00 ms (average mu = 0.795, current mu = 0.795) allocation failure;
#
# Fatal process out of memory: Zone
#
==== C stack trace ===============================
/home/user/v8/v8/out/x64.debug/libv8_libbase.so(v8::base::debug::StackTrace::StackTrace()+0x1e) [0x7fc021c8392e]
/home/user/v8/v8/out/x64.debug/libv8_libplatform.so(+0x4b60d) [0x7fc021bf060d]
/home/user/v8/v8/out/x64.debug/libv8_libbase.so(v8::base::FatalOOM(v8::base::OOMType, char const*)+0x51) [0x7fc021c5c711]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, v8::OOMDetails const&)+0x6e) [0x7fc0296123ae]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, v8::OOMDetails const&)+0x1c2) [0x7fc0296122e2]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::Zone::Expand(unsigned long)+0x21a) [0x7fc02accf39a]
/home/user/v8/v8/out/x64.debug/libv8.so(void* v8::internal::Zone::Allocate<unsigned char []>(unsigned long)+0x57) [0x7fc029725d57]
/home/user/v8/v8/out/x64.debug/libv8.so(unsigned char* v8::internal::Zone::AllocateArray<unsigned char, unsigned char []>(unsigned long)+0x80) [0x7fc029725c20]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::ZoneVector<unsigned char>::Grow(unsigned long)+0x55) [0x7fc0299d2fd5]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::ZoneVector<unsigned char>::EnsureCapacity(unsigned long)+0x4b) [0x7fc029b13dbb]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::ZoneVector<unsigned char>::resize(unsigned long)+0x21) [0x7fc02a3002d1]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::RegExpBytecodeGenerator::ExpandBuffer()+0x33) [0x7fc02aa14af3]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::RegExpBytecodeGenerator::Emit32(unsigned int)+0x84) [0x7fc02aa14de4]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::RegExpBytecodeGenerator::EmitOrLink(v8::internal::Label*)+0xaa) [0x7fc02aa14f1a]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::RegExpBytecodeGenerator::PushBacktrack(v8::internal::Label*)+0x31) [0x7fc02aa138c1]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::Trace::Flush(v8::internal::RegExpCompiler*, v8::internal::RegExpNode*, v8::internal::Trace::FlushMode)+0x2c8) [0x7fc02aa388c8]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::RegExpNode::LimitVersions(v8::internal::RegExpCompiler*, v8::internal::Trace*)+0x13b) [0x7fc02aa3949b]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::ActionNode::Emit(v8::internal::RegExpCompiler*, v8::internal::Trace*)+0x43) [0x7fc02aa41403]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::ChoiceNode::EmitChoices(v8::internal::RegExpCompiler*, v8::internal::AlternativeGenerationList*, int, v8::internal::Trace*, v8::internal::PreloadState*)+0x430) [0x7fc02aa410c0]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::ChoiceNode::Emit(v8::internal::RegExpCompiler*, v8::internal::Trace*)+0x273) [0x7fc02aa3f303]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::RegExpCompiler::Assemble(v8::internal::Isolate*, v8::internal::RegExpMacroAssembler*, v8::internal::RegExpNode*, int, v8::internal::DirectHandle<v8::internal::String>)+0x194) [0x7fc02aa37a24]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::RegExpImpl::Compile(v8::internal::Isolate*, v8::internal::Zone*, v8::internal::RegExpCompileData*, v8::base::Flags<v8::internal::RegExpFlag, int, int>, v8::internal::DirectHandle<v8::internal::String>, v8::internal::DirectHandle<v8::internal::String>, bool, unsigned int&)+0x8b1) [0x7fc02aa8c5a1]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::RegExpImpl::CompileIrregexp(v8::internal::Isolate*, v8::internal::DirectHandle<v8::internal::IrRegExpData>, v8::internal::DirectHandle<v8::internal::String>, bool)+0x4f8) [0x7fc02aa8b368]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::RegExpImpl::EnsureCompiledIrregexp(v8::internal::Isolate*, v8::internal::DirectHandle<v8::internal::IrRegExpData>, v8::internal::DirectHandle<v8::internal::String>, bool)+0x305) [0x7fc02aa92875]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::RegExpImpl::IrregexpPrepare(v8::internal::Isolate*, v8::internal::DirectHandle<v8::internal::IrRegExpData>, v8::internal::DirectHandle<v8::internal::String>)+0xbb) [0x7fc02aa883cb]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::RegExpImpl::IrregexpExec(v8::internal::Isolate*, v8::internal::DirectHandle<v8::internal::IrRegExpData>, v8::internal::DirectHandle<v8::internal::String>, int, int*, unsigned int)+0x43d) [0x7fc02aa88dcd]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::RegExp::Exec(v8::internal::Isolate*, v8::internal::DirectHandle<v8::internal::JSRegExp>, v8::internal::DirectHandle<v8::internal::String>, int, int*, unsigned int)+0x240) [0x7fc02aa88800]
/home/user/v8/v8/out/x64.debug/libv8.so(+0x8ee6300) [0x7fc02ab7b300]
/home/user/v8/v8/out/x64.debug/libv8.so(+0x8edbcf7) [0x7fc02ab70cf7]
/home/user/v8/v8/out/x64.debug/libv8.so(v8::internal::Runtime_RegExpExec(int, unsigned long*, v8::internal::Isolate*)+0x151) [0x7fc02ab70841]
/home/user/v8/v8/out/x64.debug/libv8.so(+0x6fca53d) [0x7fc028c5f53d]
Received signal 6
Aborted (core dumped)
Reporter | ||
Comment 5•6 days ago
|
||
v8 on macOS as well:
<--- Last few GCs --->
[27951:0x110050000] 7329 ms: Scavenge 927.2 (960.0) -> 927.2 (960.0) MB, pooled: 0.0 MB, 76.71 / 0.00 ms (average mu = 0.641, current mu = 0.641) allocation failure;
[27951:0x110050000] 7398 ms: Scavenge 927.2 (960.0) -> 927.2 (992.0) MB, pooled: 0.0 MB, 68.38 / 0.00 ms (average mu = 0.641, current mu = 0.641) allocation failure;
#
# Fatal process out of memory: Zone
#
==== C stack trace ===============================
0 libv8_libbase.dylib 0x00000001003c9f04 v8::base::debug::StackTrace::StackTrace() + 24
1 libv8_libplatform.dylib 0x000000010040686c v8::platform::(anonymous namespace)::PrintStackTrace() + 116
2 libv8_libbase.dylib 0x00000001003acf1c v8::base::FatalOOM(v8::base::OOMType, char const*) + 68
3 libv8.dylib 0x000000010789fa0c v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, char const*) + 0
4 libv8.dylib 0x000000010789f878 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, v8::OOMDetails const&) + 256
5 libv8.dylib 0x0000000108c5f97c v8::internal::Zone::Expand(unsigned long) + 932
6 libv8.dylib 0x00000001079b24ec void* v8::internal::Zone::Allocate<unsigned char []>(unsigned long) + 220
7 libv8.dylib 0x0000000107bd56b4 v8::internal::ZoneVector<unsigned char>::Grow(unsigned long) + 84
8 libv8.dylib 0x00000001089dc6c4 v8::internal::RegExpBytecodeGenerator::EmitOrLink(v8::internal::Label*) + 444
9 libv8.dylib 0x00000001089f7a90 v8::internal::Trace::Flush(v8::internal::RegExpCompiler*, v8::internal::RegExpNode*, v8::internal::Trace::FlushMode) + 428
10 libv8.dylib 0x00000001089f8688 v8::internal::RegExpNode::LimitVersions(v8::internal::RegExpCompiler*, v8::internal::Trace*) + 180
11 libv8.dylib 0x0000000108a00dc0 v8::internal::ActionNode::Emit(v8::internal::RegExpCompiler*, v8::internal::Trace*) + 60
12 libv8.dylib 0x0000000108a00454 v8::internal::ChoiceNode::EmitChoices(v8::internal::RegExpCompiler*, v8::internal::AlternativeGenerationList*, int, v8::internal::Trace*, v8::internal::PreloadState*) + 360
13 libv8.dylib 0x00000001089fe1d8 v8::internal::ChoiceNode::Emit(v8::internal::RegExpCompiler*, v8::internal::Trace*) + 640
14 libv8.dylib 0x00000001089f68ec v8::internal::RegExpCompiler::Assemble(v8::internal::Isolate*, v8::internal::RegExpMacroAssembler*, v8::internal::RegExpNode*, int, v8::internal::DirectHandle<v8::internal::String>) + 372
15 libv8.dylib 0x0000000108a4a394 v8::internal::RegExpImpl::Compile(v8::internal::Isolate*, v8::internal::Zone*, v8::internal::RegExpCompileData*, v8::base::Flags<v8::internal::RegExpFlag, int, int>, v8::internal::DirectHandle<v8::internal::String>, v8::internal::DirectHandle<v8::internal::String>, bool, unsigned int&) + 1316
16 libv8.dylib 0x0000000108a491e8 v8::internal::RegExpImpl::CompileIrregexp(v8::internal::Isolate*, v8::internal::DirectHandle<v8::internal::IrRegExpData>, v8::internal::DirectHandle<v8::internal::String>, bool) + 1104
17 libv8.dylib 0x0000000108a4a894 v8::internal::RegExpImpl::EnsureCompiledIrregexp(v8::internal::Isolate*, v8::internal::DirectHandle<v8::internal::IrRegExpData>, v8::internal::DirectHandle<v8::internal::String>, bool) + 492
18 libv8.dylib 0x0000000108a45520 v8::internal::RegExpImpl::IrregexpPrepare(v8::internal::Isolate*, v8::internal::DirectHandle<v8::internal::IrRegExpData>, v8::internal::DirectHandle<v8::internal::String>) + 484
19 libv8.dylib 0x0000000108a464b8 v8::internal::RegExpImpl::IrregexpExec(v8::internal::Isolate*, v8::internal::DirectHandle<v8::internal::IrRegExpData>, v8::internal::DirectHandle<v8::internal::String>, int, int*, unsigned int) + 1000
20 libv8.dylib 0x0000000108a45cac v8::internal::RegExp::Exec(v8::internal::Isolate*, v8::internal::DirectHandle<v8::internal::JSRegExp>, v8::internal::DirectHandle<v8::internal::String>, int, int*, unsigned int) + 568
21 libv8.dylib 0x0000000108b3d3f0 v8::internal::__RT_impl_Runtime_RegExpExec(v8::internal::Arguments<(v8::internal::ArgumentsType)0>, v8::internal::Isolate*) + 584
22 libv8.dylib 0x0000000108b3ce28 v8::internal::Runtime_RegExpExec(int, unsigned long*, v8::internal::Isolate*) + 148
23 ??? 0x00000001578faa70 0x0 + 5764000368
24 ??? 0x0000000157c87f18 0x0 + 5767724824
25 ??? 0x00000001575820d0 0x0 + 5760360656
26 ??? 0x0000000157577080 0x0 + 5760315520
27 ??? 0x0000000157576cb4 0x0 + 5760314548
28 libv8.dylib 0x0000000107d5c088 v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) + 6308
29 libv8.dylib 0x0000000107d5d5b8 v8::internal::Execution::CallScript(v8::internal::Isolate*, v8::internal::DirectHandle<v8::internal::JSFunction>, v8::internal::DirectHandle<v8::internal::Object>, v8::internal::DirectHandle<v8::internal::Object>) + 708
30 libv8.dylib 0x00000001078b5860 v8::Script::Run(v8::Local<v8::Context>, v8::Local<v8::Data>) + 1384
31 d8 0x000000010024bf94 v8::Shell::ExecuteString(v8::Isolate*, v8::Local<v8::String>, v8::Local<v8::String>, v8::Shell::ReportExceptions, v8::Global<v8::Value>*) + 1536
32 d8 0x0000000100266d14 v8::SourceGroup::Execute(v8::Isolate*) + 392
33 d8 0x000000010026aee8 v8::Shell::RunMainIsolate(v8::Isolate*, bool) + 384
34 d8 0x000000010026a9a0 v8::Shell::RunMain(v8::Isolate*, bool) + 352
35 d8 0x000000010026c254 v8::Shell::Main(int, char**) + 3120
36 dyld 0x000000019ea4ab98 start + 6076
zsh: trace trap ./v8/v8/out/debug/d8 test1.js
Assignee | ||
Comment 6•6 days ago
|
||
Thanks for the report! However, upon investigation, this is actually just an overly aggressive assertion in the irregexp code we import from V8.
The testcase causes the bytecode buffer here to grow increasingly large. V8 apparently caps the size of a Zone allocation at INT_MAX, and crashes with OOM when that value is exceeded. Our LifoAlloc implementation is willing to allocate larger chunks. We allocate a chunk of size INT_MAX+1. We keep writing into it. At some point, pc_
reaches INT_MAX+1. The assertion casts the current size to an int, which wraps around to INT_MIN and triggers the assertion failure, even though pc_
is still within the actual size of the backing storage.
In the absence of the assertion, we instead proceed to call ExpandBuffer again. On my machine, that triggers a SIGKILL inside the malloc implementation. If malloc survived long enough to return a nullptr, we would catch it here and crash safely.
None of this is exploitable.
It's maybe worth adding a size check in our Zone shim to eagerly crash in the same place V8 does, just for consistency.
Assignee | ||
Comment 7•6 days ago
|
||
This matches V8's behaviour and avoids some spurious assertions in pathological cases.
I'm not adding the testcase because it's very slow and crashes with OOM even after the fix.
Updated•6 days ago
|
Updated•5 days ago
|
Comment 9•4 days ago
|
||
bugherder |
Updated•4 days ago
|
Description
•