UndefinedBehaviorSanitizer: /xpcom/io/Base64.cpp:327:13: runtime error: index 127 out of bounds for type 'const uint8_t[127]' (aka 'const unsigned char[127]')
Categories
(Core :: XPCOM, defect)
Tracking
()
People
(Reporter: jkratzer, Assigned: jstutte)
References
(Blocks 1 open bug)
Details
(Keywords: csectype-bounds, sec-moderate, testcase, Whiteboard: [bugmon:confirm][post-critsmash-triage][adv-main106+r][adv-esr102.4+r])
Attachments
(2 files)
|
4.01 KB,
application/octet-stream
|
Details | |
|
48 bytes,
text/x-phabricator-request
|
pascalc
:
approval-mozilla-beta+
RyanVM
:
approval-mozilla-esr102+
|
Details | Review |
Testcase found while fuzzing mozilla-central rev c9041757a18a (built with: --enable-debug --enable-fuzzing).
Testcase can be reproduced using the following commands:
$ pip install fuzzfetch grizzly-framework
$ python -m fuzzfetch --build c9041757a18a --debug --fuzzing -n firefox
$ python -m grizzly.replay ./firefox/firefox testcase.zip
UndefinedBehaviorSanitizer: /xpcom/io/Base64.cpp:327:13: runtime error: index 127 out of bounds for type 'const uint8_t[127]' (aka 'const unsigned char[127]')
/xpcom/io/Base64.cpp:327:13: runtime error: index 127 out of bounds for type 'const uint8_t[127]' (aka 'const unsigned char[127]')
#0 0x7fe97e67f448 in (anonymous namespace)::Base64URLCharToValue(char, unsigned char*) /xpcom/io/Base64.cpp:327:13
#1 0x7fe97e67ef85 in bool mozilla::Decode4to3<char, unsigned char, bool (*)(char, unsigned char*)>(char const*, unsigned char*, bool (*)(char, unsigned char*)) /xpcom/io/Base64.cpp:450:8
#2 0x7fe97e67eae9 in mozilla::Base64URLDecode(nsTSubstring<char> const&, mozilla::Base64URLDecodePaddingPolicy, FallibleTArray<unsigned char>&) /xpcom/io/Base64.cpp:681:10
#3 0x7fe985be1112 in mozilla::dom::PushManager::NormalizeAppServerKey(mozilla::dom::OwningArrayBufferViewOrArrayBufferOrString const&, nsTArray<unsigned char>&) /dom/push/PushManager.cpp:513:19
#4 0x7fe985be033f in mozilla::dom::PushManager::PerformSubscriptionActionFromWorker(mozilla::dom::PushManager::SubscriptionAction, mozilla::dom::PushSubscriptionOptionsInit const&, mozilla::ErrorResult&) /dom/push/PushManager.cpp:492:19
#5 0x7fe982873be7 in mozilla::dom::PushManager_Binding::subscribe(JSContext*, JS::Handle<JSObject*>, void*, JSJitMethodCallArgs const&) /builds/worker/workspace/obj-build/dom/bindings/PushManagerBinding.cpp:516:60
#6 0x7fe982873919 in mozilla::dom::PushManager_Binding::subscribe_promiseWrapper(JSContext*, JS::Handle<JSObject*>, void*, JSJitMethodCallArgs const&) /builds/worker/workspace/obj-build/dom/bindings/PushManagerBinding.cpp:537:13
#7 0x7fe983a29381 in bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ConvertExceptionsToPromises>(JSContext*, unsigned int, JS::Value*) /dom/bindings/BindingUtils.cpp:3287:13
#8 0x7fe98e1e7cb3 in CallJSNative /js/src/vm/Interpreter.cpp:458:13
#9 0x7fe98e1e7cb3 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /js/src/vm/Interpreter.cpp:546:12
#10 0x7fe98e1d6639 in InternalCall /js/src/vm/Interpreter.cpp:613:10
#11 0x7fe98e1d6639 in CallFromStack /js/src/vm/Interpreter.cpp:618:10
#12 0x7fe98e1d6639 in Interpret(JSContext*, js::RunState&) /js/src/vm/Interpreter.cpp:3374:16
#13 0x7fe98e1bbc3e in js::RunScript(JSContext*, js::RunState&) /js/src/vm/Interpreter.cpp:430:13
#14 0x7fe98e1eb935 in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JS::Handle<JSObject*>, js::AbstractFramePtr, JS::MutableHandle<JS::Value>) /js/src/vm/Interpreter.cpp:824:13
#15 0x7fe98c87209c in bool EvaluateSourceBuffer<mozilla::Utf8Unit>(JSContext*, js::ScopeKind, JS::Handle<JSObject*>, JS::ReadOnlyCompileOptions const&, JS::SourceText<mozilla::Utf8Unit>&, JS::MutableHandle<JS::Value>) /js/src/vm/CompilationAndEvaluation.cpp:526:10
#16 0x7fe98c871c86 in JS::Evaluate(JSContext*, JS::ReadOnlyCompileOptions const&, JS::SourceText<mozilla::Utf8Unit>&, JS::MutableHandle<JS::Value>) /js/src/vm/CompilationAndEvaluation.cpp:534:10
#17 0x7fe98688e2a7 in bool mozilla::dom::workerinternals::loader::EvaluateSourceBuffer<mozilla::Utf8Unit>(JSContext*, JS::CompileOptions const&, JS::SourceText<mozilla::Utf8Unit>&) /dom/workers/ScriptLoader.cpp:383:10
#18 0x7fe98688a4ff in mozilla::dom::workerinternals::loader::WorkerScriptLoader::EvaluateScript(JSContext*, JS::loader::ScriptLoadRequest*) /dom/workers/ScriptLoader.cpp:1003:13
#19 0x7fe986889d54 in mozilla::dom::workerinternals::loader::WorkerScriptLoader::ProcessPendingRequests(JSContext*) /dom/workers/ScriptLoader.cpp:643:10
#20 0x7fe98688f344 in mozilla::dom::workerinternals::loader::ScriptExecutorRunnable::WorkerRun(JSContext*, mozilla::dom::WorkerPrivate*) /dom/workers/ScriptLoader.cpp:1137:24
#21 0x7fe9868e704e in mozilla::dom::WorkerRunnable::Run() /dom/workers/WorkerRunnable.cpp:377:12
#22 0x7fe97e79a1ee in nsThread::ProcessNextEvent(bool, bool*) /xpcom/threads/nsThread.cpp:1199:16
#23 0x7fe97e7a3e44 in NS_ProcessNextEvent(nsIThread*, bool) /xpcom/threads/nsThreadUtils.cpp:465:10
#24 0x7fe9868d7145 in mozilla::dom::WorkerPrivate::RunCurrentSyncLoop() /dom/workers/WorkerPrivate.cpp:4200:7
#25 0x7fe9845d010c in mozilla::dom::AutoSyncLoopHolder::Run() /builds/worker/workspace/obj-build/dist/include/mozilla/dom/WorkerPrivate.h:1504:27
#26 0x7fe98688ffee in mozilla::dom::workerinternals::(anonymous namespace)::LoadAllScripts(mozilla::dom::WorkerPrivate*, mozilla::UniquePtr<mozilla::dom::SerializedStackHolder, mozilla::DefaultDelete<mozilla::dom::SerializedStackHolder> >, nsTArray<nsTString<char16_t> > const&, bool, mozilla::dom::WorkerScriptType, mozilla::ErrorResult&, mozilla::Encoding const*) /dom/workers/ScriptLoader.cpp:264:14
#27 0x7fe98688fc52 in mozilla::dom::workerinternals::LoadMainScript(mozilla::dom::WorkerPrivate*, mozilla::UniquePtr<mozilla::dom::SerializedStackHolder, mozilla::DefaultDelete<mozilla::dom::SerializedStackHolder> >, nsTSubstring<char16_t> const&, mozilla::dom::WorkerScriptType, mozilla::ErrorResult&, mozilla::Encoding const*) /dom/workers/ScriptLoader.cpp:1250:3
#28 0x7fe9868f9726 in mozilla::dom::(anonymous namespace)::CompileScriptRunnable::WorkerRun(JSContext*, mozilla::dom::WorkerPrivate*) /dom/workers/WorkerPrivate.cpp:380:5
#29 0x7fe9868e704e in mozilla::dom::WorkerRunnable::Run() /dom/workers/WorkerRunnable.cpp:377:12
#30 0x7fe97e79a1ee in nsThread::ProcessNextEvent(bool, bool*) /xpcom/threads/nsThread.cpp:1199:16
#31 0x7fe97e7a3e44 in NS_ProcessNextEvent(nsIThread*, bool) /xpcom/threads/nsThreadUtils.cpp:465:10
#32 0x7fe9868cf1ec in mozilla::dom::WorkerPrivate::DoRunLoop(JSContext*) /dom/workers/WorkerPrivate.cpp:3204:7
#33 0x7fe9868a5e1e in mozilla::dom::workerinternals::(anonymous namespace)::WorkerThreadPrimaryRunnable::Run() /dom/workers/RuntimeService.cpp:2042:42
#34 0x7fe97e79a1ee in nsThread::ProcessNextEvent(bool, bool*) /xpcom/threads/nsThread.cpp:1199:16
#35 0x7fe97e7a3e44 in NS_ProcessNextEvent(nsIThread*, bool) /xpcom/threads/nsThreadUtils.cpp:465:10
#36 0x7fe97ff3e135 in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /ipc/glue/MessagePump.cpp:300:20
#37 0x7fe97fdbb5f1 in RunInternal /ipc/chromium/src/base/message_loop.cc:381:10
#38 0x7fe97fdbb5f1 in RunHandler /ipc/chromium/src/base/message_loop.cc:374:3
#39 0x7fe97fdbb5f1 in MessageLoop::Run() /ipc/chromium/src/base/message_loop.cc:356:3
#40 0x7fe97e791338 in nsThread::ThreadFunc(void*) /xpcom/threads/nsThread.cpp:384:10
#41 0x7fe9a61d8b7e in _pt_root /nsprpub/pr/src/pthreads/ptthread.c:201:5
#42 0x7fe9a6959b42 in start_thread nptl/./nptl/pthread_create.c:442:8
#43 0x7fe9a69eb9ff misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
SUMMARY: UndefinedBehaviorSanitizer: out-of-bounds-index /xpcom/io/Base64.cpp:327:13 in
| Reporter | ||
Comment 1•3 years ago
|
||
Comment 2•3 years ago
|
||
Bugmon Analysis
Unable to reproduce bug 1792041 using build mozilla-central 20220922095647-c9041757a18a. Without a baseline, bugmon is unable to analyze this bug.
Removing bugmon keyword as no further action possible. Please review the bug and re-add the keyword for further analysis.
Comment 3•3 years ago
|
||
Seems like this has something to do with workers.
| Reporter | ||
Comment 4•3 years ago
|
||
Marking as s-s until we can determine if this represents a security issue or not.
Updated•3 years ago
|
| Assignee | ||
Comment 6•3 years ago
|
||
(In reply to Jason Kratzer [:jkratzer] from comment #5)
You can find a pernosco session for this bug here.
Thanks! That looks a bit weird. We have the static kBase64URLDecodeTable and it seems ubsan does not like kBase64URLDecodeTable[127]. sizeof(kBase64URLDecodeTable) results to 127 in gdb, so this would tell us that kBase64URLDecodeTable lacks an element. Indeed if I look at *aValue = kBase64URLDecodeTable[index & 0x7f]; I assume that the array is supposed to be 128 bytes long instead, not 127.
It is unclear to me though what the missing element should be numerically.
In any case it seems to me that we are in XPCOM land here.
| Assignee | ||
Comment 7•3 years ago
|
||
And yes, it is a buffer overrun, but I am not sure how exploitable that might be given the probable alignment to 4 or even 8 byte boundaries. We might just read random data, which is bad enough.
Comment 8•3 years ago
|
||
I'll mark it as sec-moderate, as it looks like we're reading just past the end of a fixed location in memory.
| Assignee | ||
Comment 9•3 years ago
|
||
Talking with :mt we found that 127 (DEL) can be just mapped to 255.
| Assignee | ||
Comment 10•3 years ago
|
||
And we might want to ensure that https://searchfox.org/mozilla-central/source/xpcom/tests/gtest/TestBase64.cpp has complete coverage for all characters.
| Assignee | ||
Comment 11•3 years ago
|
||
Updated•3 years ago
|
Updated•3 years ago
|
Updated•3 years ago
|
Comment 12•3 years ago
|
||
Add a value for DEL to kBase64URLDecodeTable and have static asserts for lookup tables' length. r=xpcom-reviewers,nika
https://hg.mozilla.org/integration/autoland/rev/fba6ffac04a6
https://hg.mozilla.org/mozilla-central/rev/fba6ffac04a6
Updated•3 years ago
|
Comment 13•3 years ago
|
||
The patch landed in nightly and beta is affected.
:jstutte, is this bug important enough to require an uplift?
- If yes, please nominate the patch for beta approval.
- If no, please set
status-firefox106towontfix.
For more information, please visit auto_nag documentation.
| Assignee | ||
Comment 14•3 years ago
|
||
Comment on attachment 9296420 [details]
Bug 1792041 - Add a value for DEL to kBase64URLDecodeTable and have static asserts for lookup tables' length. r?#xpcom-reviewers
Beta/Release Uplift Approval Request
- User impact if declined: Unknown, we just have a fuzzer test case. We can read just 1 byte beyond a static buffer.
- Is this code covered by automated tests?: Yes
- Has the fix been verified in Nightly?: Yes
- Needs manual test from QE?: No
- If yes, steps to reproduce:
- List of other uplifts needed: None
- Risk to taking this patch: Low
- Why is the change risky/not risky? (and alternatives if risky): We just added a value to the buffer and added some static asserts for testing. There is only one small logic change in
Base64URLCharToValuewhere we used to wrap around for values >128 by bit-masking, now we will return a failure/invalid value for those. For correct requests this should have no impact. - String changes made/needed:
- Is Android affected?: Yes
Comment 15•3 years ago
|
||
Comment on attachment 9296420 [details]
Bug 1792041 - Add a value for DEL to kBase64URLDecodeTable and have static asserts for lookup tables' length. r?#xpcom-reviewers
Approved for 106.0b8, thanks.
Comment 16•3 years ago
|
||
| uplift | ||
Comment 17•3 years ago
|
||
Comment on attachment 9296420 [details]
Bug 1792041 - Add a value for DEL to kBase64URLDecodeTable and have static asserts for lookup tables' length. r?#xpcom-reviewers
Approved for 102.4esr.
Comment 18•3 years ago
|
||
| uplift | ||
Updated•3 years ago
|
Updated•3 years ago
|
Updated•3 years ago
|
Updated•3 years ago
|
Description
•