[StructuredClone] Remote Denial of Service via massive ArrayBuffer allocation from small input
Categories
(Core :: JavaScript Engine, defect, P3)
Tracking
()
People
(Reporter: uncleruc2075, Unassigned)
References
(Blocks 1 open bug)
Details
(Keywords: reporter-external)
Attachments
(1 file)
|
16 bytes,
text/plain
|
Details |
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36
Steps to reproduce:
-
Obtain a SpiderMonkey build with StructuredCloneReader fuzzer target enabled (observed in build 20260524-17702a114cde).
-
Run the fuzz-tests binary with the StructuredCloneReader target using the attached 16-byte PoC file:
FUZZER=StructuredCloneReader ./fuzz-tests oom-df8e8b87b88f9904b9f71d4e46dc1c0ed5bf2cb7 -
(Theoretical vector): A compromised content process could send a similar malformed IPC message to the parent process to trigger a crash.
Actual results:
The engine reads an attacker-controlled length (8,589,934,591 bytes) from the input stream and immediately attempts to allocate this amount using js::ImmutableArrayBufferObject::createZeroed before
checking if the input stream actually contains that much data. This results in an immediate out-of-memory (OOM) crash.
ERROR: libFuzzer: out-of-memory (malloc(8589934591))
#0 0x5cca616a3b0c in calloc
#1 0x5cca634e38e8 in AllocateArrayBufferContents js/src/vm/ArrayBufferObject.cpp:1235
#2 0x5cca634cc1be in js::ImmutableArrayBufferObject::createZeroed js/src/vm/ArrayBufferObject.cpp:2911
#3 0x5cca634901e3 in JSStructuredCloneReader::readArrayBuffer js/src/vm/StructuredClone.cpp:2902
Expected results:
The StructuredCloneReader should verify the consistency between the requested ArrayBuffer size and the actual number of bytes remaining in the input stream. If the requested size is larger than the
input source, it should fail validation immediately without attempting a massive memory allocation.
| Reporter | ||
Comment 1•5 months ago
|
||
full log
FUZZER=StructuredCloneReader ./fuzz-tests oom-df8e8b87b88f9904b9f71d4e46dc1c0ed5bf2cb7
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 269350183
INFO: Loaded 1 modules (512590 inline 8-bit counters): 512590 [0x5bf181560bc0, 0x5bf1815dde0e),
INFO: Loaded 1 PC tables (512590 PCs): 512590 [0x5bf1815dde10,0x5bf181db02f0),
./fuzz-tests: Running 1 inputs 1 time(s) each.
Running: oom-df8e8b87b88f9904b9f71d4e46dc1c0ed5bf2cb7
==34049== ERROR: libFuzzer: out-of-memory (malloc(8589934591))
To change the out-of-memory limit use -rss_limit_mb=<N>
#0 0x5bf17d96eec1 in __sanitizer_print_stack_trace /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_stack.cpp:87:3
#1 0x5bf17daff96e in fuzzer::PrintStackTrace() /builds/worker/checkouts/gecko/tools/fuzzing/libfuzzer/FuzzerUtil.cpp:210:5
#2 0x5bf17dae6356 in fuzzer::Fuzzer::HandleMalloc(unsigned long) /builds/worker/checkouts/gecko/tools/fuzzing/libfuzzer/FuzzerLoop.cpp:131:3
#3 0x5bf17dae61f2 in fuzzer::MallocHook(void const volatile*, unsigned long) /builds/worker/checkouts/gecko/tools/fuzzing/libfuzzer/FuzzerLoop.cpp:100:6
#4 0x5bf17d976c02 in __sanitizer::RunMallocHooks(void*, unsigned long) /builds/worker/fetches/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp:346:5
#5 0x5bf17d8c5d0f in __asan::Allocator::Allocate(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType, bool) /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_allocator.cpp:664:5
#6 0x5bf17d8c314b in Calloc /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_allocator.cpp:794:17
#7 0x5bf17d8c314b in __asan::asan_calloc(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*) /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_allocator.cpp:1024:34
#8 0x5bf17d962b0c in calloc /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:75:10
#9 0x5bf17f7a28e8 in js_arena_calloc /builds/worker/workspace/obj-build/dist/include/js/Utility.h:401:10
#10 0x5bf17f7a28e8 in js_pod_arena_calloc<unsigned char> /builds/worker/workspace/obj-build/dist/include/js/Utility.h:614:26
#11 0x5bf17f7a28e8 in maybe_pod_arena_calloc<unsigned char> /builds/worker/checkouts/gecko/js/src/vm/MallocProvider.h:64:12
#12 0x5bf17f7a28e8 in AllocateArrayBufferContents(JSContext*, unsigned long) /builds/worker/workspace/obj-build/js/src/vm/./../../../../../checkouts/gecko/js/src/vm/ArrayBufferObject.cpp:1235:11
#13 0x5bf17f7a5d95 in std::tuple<js::ImmutableArrayBufferObject*, unsigned char*> js::ArrayBufferObject::createUninitializedBufferAndData<js::ImmutableArrayBufferObject, (js::ArrayBufferObject::FillContents)0>(JSContext*, unsigned long, js::AutoSetNewObjectMetadata&, JS::Handle<JSObject*>) /builds/worker/workspace/obj-build/js/src/vm/./../../../../../checkouts/gecko/js/src/vm/ArrayBufferObject.cpp:2480:18
#14 0x5bf17f78b333 in std::tuple<js::ImmutableArrayBufferObject*, unsigned char*> js::ArrayBufferObject::createBufferAndData<js::ImmutableArrayBufferObject, (js::ArrayBufferObject::FillContents)0>(JSContext*, unsigned long, js::AutoSetNewObjectMetadata&, JS::Handle<JSObject*>) /builds/worker/workspace/obj-build/js/src/vm/./../../../../../checkouts/gecko/js/src/vm/ArrayBufferObject.cpp:2528:7
#15 0x5bf17f78b1be in js::ImmutableArrayBufferObject::createZeroed(JSContext*, unsigned long, JS::Handle<JSObject*>) /builds/worker/workspace/obj-build/js/src/vm/./../../../../../checkouts/gecko/js/src/vm/ArrayBufferObject.cpp:2911:7
#16 0x5bf17f74f1e3 in JSStructuredCloneReader::readArrayBuffer(StructuredDataType, unsigned int, JS::MutableHandle<JS::Value>) /builds/worker/checkouts/gecko/js/src/vm/StructuredClone.cpp:2902:11
#17 0x5bf17f7523a3 in JSStructuredCloneReader::startReadUnchecked(JS::MutableHandle<JS::Value>, JSStructuredCloneReader::ShouldAtomizeStrings, bool*) /builds/worker/checkouts/gecko/js/src/vm/StructuredClone.cpp:3315:12
#18 0x5bf17f732fc0 in startRead /builds/worker/checkouts/gecko/js/src/vm/StructuredClone.cpp:3463:8
#19 0x5bf17f732fc0 in JSStructuredCloneReader::read(JS::MutableHandle<JS::Value>, unsigned long) /builds/worker/checkouts/gecko/js/src/vm/StructuredClone.cpp:4102:8
#20 0x5bf17f732e2a in ReadStructuredClone(JSContext*, JSStructuredCloneData const&, JS::StructuredCloneScope, JS::MutableHandle<JS::Value>, JS::CloneDataPolicy const&, JSStructuredCloneCallbacks const*, void*) /builds/worker/checkouts/gecko/js/src/vm/StructuredClone.cpp:801:12
#21 0x5bf17f75989c in JS_ReadStructuredClone(JSContext*, JSStructuredCloneData const&, unsigned int, JS::StructuredCloneScope, JS::MutableHandle<JS::Value>, JS::CloneDataPolicy const&, JSStructuredCloneCallbacks const*, void*) /builds/worker/checkouts/gecko/js/src/vm/StructuredClone.cpp:4247:10
#22 0x5bf17d9a8a5d in testStructuredCloneReaderFuzz(unsigned char const*, unsigned long) /builds/worker/workspace/obj-build/js/src/fuzz-tests/./../../../../../checkouts/gecko/js/src/fuzz-tests/testStructuredCloneReader.cpp:56:8
#23 0x5bf17dae89a6 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /builds/worker/checkouts/gecko/tools/fuzzing/libfuzzer/FuzzerLoop.cpp:619:13
#24 0x5bf17dad59f9 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /builds/worker/checkouts/gecko/tools/fuzzing/libfuzzer/FuzzerDriver.cpp:335:6
#25 0x5bf17dada7ff in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /builds/worker/checkouts/gecko/tools/fuzzing/libfuzzer/FuzzerDriver.cpp:871:9
#26 0x5bf17d9ae44c in main /builds/worker/workspace/obj-build/js/src/fuzz-tests/./../../../../../checkouts/gecko/js/src/fuzz-tests/tests.cpp:116:3
#27 0x7a82e30a61c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 8e9fd827446c24067541ac5390e6f527fb5947bb)
#28 0x7a82e30a628a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 8e9fd827446c24067541ac5390e6f527fb5947bb)
#29 0x5bf17d8c15e8 in _start (/home/uncleruc2075/m-c-20260524001456-fuzzing-asan-opt/dist/bin/fuzz-tests+0x2b555e8) (BuildId: 4e4ef33497ddc9e7e13abdfc3da492db89cd3fa9)
SUMMARY: libFuzzer: out-of-memory
Updated•5 months ago
|
Comment 2•5 months ago
|
||
Thanks for the report. This would be nice to improve, but we don't consider an OOM crash like this to be a security problem.
| Reporter | ||
Comment 3•5 months ago
|
||
(In reply to Andrew McCreight [:mccr8] from comment #2)
Thanks for the report. This would be nice to improve, but we don't consider an OOM crash like this to be a security problem.
ok thnaks
Updated•5 months ago
|
Description
•