Closed Bug 1784588 (CVE-2022-40961) Opened 2 years ago Closed 2 years ago

stack-buffer-overflow in [@ mozilla::widget::GfxInfo::EnsureInitialized] on startup

Categories

(Core :: Graphics, defect)

Unspecified
Android
defect

Tracking

()

RESOLVED FIXED
105 Branch
Tracking Status
firefox-esr91 --- wontfix
firefox-esr102 --- wontfix
firefox103 --- wontfix
firefox104 --- wontfix
firefox105 + fixed

People

(Reporter: tsmith, Assigned: jnicol)

References

(Blocks 2 open bugs)

Details

(Keywords: csectype-bounds, sec-moderate, Whiteboard: [adv-main105+r])

Attachments

(2 files)

This is detected at launch with an ASan build. It seems to be blocking startup.

ASAN_OPTIONS=strict_string_checks=1 is used to get a good stack.

==30983==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7b979fd406f5 at pc 0x7b987f1c169c bp 0x7b979fd40190 sp 0x7b979fd3f950
READ of size 7 at 0x7b979fd406f5 thread T21 (Gecko)
    #0 0x7b987f1c169b in atoi /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp:506:3
    #1 0x7b9790c3c14a in mozilla::widget::GfxInfo::EnsureInitialized() /builds/worker/checkouts/gecko/widget/android/GfxInfo.cpp:218:16
    #2 0x7b9790c3df29 in mozilla::widget::GfxInfo::GetFeatureStatusImpl(int, int*, nsTSubstring<char16_t>&, nsTArray<mozilla::widget::GfxDriverInfo> const&, nsTSubstring<char>&, mozilla::widget::OperatingSystem*) /builds/worker/checkouts/gecko/widget/android/GfxInfo.cpp:403:3
    #3 0x7b9790a9a4fb in mozilla::widget::GfxInfoBase::GetFeatureStatus(int, nsTSubstring<char>&, int*) /builds/worker/checkouts/gecko/widget/GfxInfoBase.cpp:829:7
    #4 0x7b9789fc0229 in IsFeatureSupported /builds/worker/checkouts/gecko/gfx/thebes/gfxPlatform.cpp:1122:8
    #5 0x7b9789fc0229 in IsDXInterop2Blocked /builds/worker/checkouts/gecko/gfx/thebes/gfxPlatform.cpp:1130:11
    #6 0x7b9789fc0229 in gfxPlatform::Init() /builds/worker/checkouts/gecko/gfx/thebes/gfxPlatform.cpp:899:35
    #7 0x7b9789fbeb4b in gfxPlatform::GetPlatform() /builds/worker/checkouts/gecko/gfx/thebes/gfxPlatform.cpp:460:5
    #8 0x7b9790c79681 in mozilla::widget::GeckoViewSupport::Open(mozilla::jni::LocalRef<mozilla::jni::TypedObject<_jclass*> > const&, mozilla::jni::Ref<mozilla::java::GeckoSession::Window, _jobject*> const&, mozilla::jni::Ref<mozilla::jni::Object, _jobject*> const&, mozilla::jni::Ref<mozilla::jni::Object, _jobject*> const&, mozilla::jni::Ref<mozilla::jni::Object, _jobject*> const&, mozilla::jni::Ref<mozilla::jni::Object, _jobject*> const&, mozilla::jni::Ref<mozilla::jni::Object, _jobject*> const&, mozilla::jni::StringParam const&, mozilla::jni::StringParam const&, bool) /builds/worker/checkouts/gecko/widget/android/nsWindow.cpp:1618:3
    #9 0x7b9790cb45af in Call<true, true, 0UL, 1UL, 2UL, 3UL, 4UL, 5UL, 6UL, 7UL, 8UL> /builds/worker/workspace/obj-build/dist/include/mozilla/jni/Natives.h:1194:5
    #10 0x7b9790cb45af in mozilla::jni::detail::ProxyNativeCall<mozilla::widget::GeckoViewSupport, mozilla::java::GeckoSession::Window, true, true, mozilla::jni::Ref<mozilla::java::GeckoSession::Window, _jobject*> const&, mozilla::jni::Ref<mozilla::jni::Object, _jobject*> const&, mozilla::jni::Ref<mozilla::jni::Object, _jobject*> const&, mozilla::jni::Ref<mozilla::jni::Object, _jobject*> const&, mozilla::jni::Ref<mozilla::jni::Object, _jobject*> const&, mozilla::jni::Ref<mozilla::jni::Object, _jobject*> const&, mozilla::jni::StringParam const&, mozilla::jni::StringParam const&, bool>::operator()() /builds/worker/workspace/obj-build/dist/include/mozilla/jni/Natives.h:1281:5
    #11 0x7b9790cb40fc in mozilla::widget::WindowEvent<mozilla::jni::detail::ProxyNativeCall<mozilla::widget::GeckoViewSupport, mozilla::java::GeckoSession::Window, true, true, mozilla::jni::Ref<mozilla::java::GeckoSession::Window, _jobject*> const&, mozilla::jni::Ref<mozilla::jni::Object, _jobject*> const&, mozilla::jni::Ref<mozilla::jni::Object, _jobject*> const&, mozilla::jni::Ref<mozilla::jni::Object, _jobject*> const&, mozilla::jni::Ref<mozilla::jni::Object, _jobject*> const&, mozilla::jni::Ref<mozilla::jni::Object, _jobject*> const&, mozilla::jni::StringParam const&, mozilla::jni::StringParam const&, bool>, true, mozilla::jni::Ref<mozilla::jni::TypedObject<_jclass*>, _jclass*> const&, mozilla::widget::GeckoViewSupport>::Run() /builds/worker/workspace/obj-build/dist/include/mozilla/widget/WindowEvent.h:48:7
    #12 0x7b9787998e30 in mozilla::RunnableTask::Run() /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:538:16
    #13 0x7b978794d89d in mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:851:26
    #14 0x7b978794a698 in mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:683:15
    #15 0x7b978794aecb in mozilla::TaskController::ProcessPendingMTTask(bool) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:461:36
    #16 0x7b97879a3961 in operator() /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:187:37
    #17 0x7b97879a3961 in mozilla::detail::RunnableFunction<mozilla::TaskController::InitializeInternal()::$_0>::Run() /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:531:5
    #18 0x7b978797362d in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:1205:16
    #19 0x7b9787980361 in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.cpp:465:10
    #20 0x7b9788f21b13 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/worker/checkouts/gecko/ipc/glue/MessagePump.cpp:85:21
    #21 0x7b9788e0c3d2 in RunInternal /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:381:10
    #22 0x7b9788e0c3d2 in RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:374:3
    #23 0x7b9788e0c3d2 in MessageLoop::Run() /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:356:3
    #24 0x7b9790b4569a in nsBaseAppShell::Run() /builds/worker/checkouts/gecko/widget/nsBaseAppShell.cpp:150:27
    #25 0x7b9795289952 in nsAppStartup::Run() /builds/worker/checkouts/gecko/toolkit/components/startup/nsAppStartup.cpp:295:30
    #26 0x7b97954ce94c in XREMain::XRE_mainRun() /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:5718:22
    #27 0x7b97954d0056 in XREMain::XRE_main(int, char**, mozilla::BootstrapConfig const&) /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:5912:8
    #28 0x7b97954d14a6 in XRE_main(int, char**, mozilla::BootstrapConfig const&) /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:5968:21
    #29 0x7b97954d83c8 in GeckoStart /builds/worker/checkouts/gecko/toolkit/xre/nsAndroidStartup.cpp:54:18
    #30 0x7b979ef7948a in Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun /builds/worker/checkouts/gecko/mozglue/android/APKOpen.cpp:386:17
    #31 0x7b97f86b60c7 in art_quick_generic_jni_trampoline adler32.c
    #32 0x7b97f86a7aa8 in NterpCheckCast crtbegin_so.c

Address 0x7b979fd406f5 is located in stack of thread T21 (Gecko) at offset 1365 in frame
    #0 0x7b9790c3a95f in mozilla::widget::GfxInfo::EnsureInitialized() /builds/worker/checkouts/gecko/widget/android/GfxInfo.cpp:178

  This frame has 21 object(s):
    [32, 64) 'dest.i'
    [96, 392) 'ref.tmp' (line 182)
    [464, 480) 'model' (line 186)
    [496, 512) 'ref.tmp6' (line 187)
    [528, 616) 'ref.tmp12' (line 188)
    [656, 672) 'product' (line 191)
    [688, 704) 'ref.tmp15' (line 192)
    [720, 808) 'ref.tmp23' (line 193)
    [848, 864) 'manufacturer' (line 196)
    [880, 896) 'ref.tmp26' (line 198)
    [912, 1000) 'ref.tmp34' (line 199)
    [1040, 1056) 'hardware' (line 206)
    [1072, 1088) 'ref.tmp38' (line 207)
    [1104, 1192) 'ref.tmp46' (line 208)
    [1232, 1248) 'release' (line 211)
    [1264, 1280) 'ref.tmp49' (line 212)
    [1296, 1304) 'ref.tmp50' (line 212)
    [1328, 1333) 'a' (line 215)
    [1360, 1365) 'b' (line 215) <== Memory access at offset 1365 overflows this variable
    [1392, 1397) 'c' (line 215)
    [1424, 1429) 'd' (line 215)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
Thread T21 (Gecko) created by T0 (AndroidUI) here:
    #0 0x7b987f1bfb6c in pthread_create /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp:208:3
    #1 0x7b97f8bc0c42 in art::Thread::CreateNativeThread(_JNIEnv*, _jobject*, unsigned long, bool) (/apex/com.android.art/lib64/libart.so+0x68ec42) (BuildId: 1dfb27162fe62a7ac7a10ea361233369)
    #2 0x921e0a2c9f35647f  (<unknown module>)

SUMMARY: AddressSanitizer: stack-buffer-overflow /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp:506:3 in atoi
Shadow bytes around the buggy address:
  0x0f7373fa0080: f8 f2 f2 f2 f2 f2 00 00 f2 f2 f8 f8 f2 f2 f8 f8
  0x0f7373fa0090: f8 f8 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 00 00
  0x0f7373fa00a0: f2 f2 f8 f8 f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
  0x0f7373fa00b0: f8 f2 f2 f2 f2 f2 00 00 f2 f2 f8 f8 f2 f2 f8 f8
  0x0f7373fa00c0: f8 f8 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 00 00
=>0x0f7373fa00d0: f2 f2 f8 f8 f2 f2 f8 f2 f2 f2 05 f2 f2 f2[05]f2
  0x0f7373fa00e0: f2 f2 05 f2 f2 f2 05 f3 f3 f3 f3 f3 00 00 00 00
  0x0f7373fa00f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0f7373fa0100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0f7373fa0110: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 01 f2 f8 f8
  0x0f7373fa0120: f2 f2 f8 f8 f2 f2 f8 f8 f2 f2 f8 f8 f2 f2 f8 f8
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==30983==ABORTING

Jamie, could you please have a quick look? Appears to involve GeckoView/Android.

Severity: -- → S2
Flags: needinfo?(jnicol)

Tyson, do we have any documentation anywhere for how to reproduce this, either locally or on try? Does this occur reliably or intermittently?

Flags: needinfo?(jnicol) → needinfo?(twsmith)

Okay, this is trivial to reproduce. If mOsVersion is for example "7.0", then SplitDriverVersion sets a and b to "7" and "0". But c and d are left uninitialized, then atoi overflows because there is no null-terminator. Whoops.

SplitDriverVersion is supposed to be given an input string with 4 "."-separated numbers, which isn't always (usually? ever?) the case here. On a couple devices I can see we get either 1 or 2 numbers. The docs say we should make no assumptions about the structure of this value.

We really shouldn't be using this value in this way. It was added in bug 802827 to use for blocklisting. This is so old we might be able to simply remove it. We'd need to check whether anything else uses the OS version to blocklist on, and perhaps switch to SDK level instead. This could introduce regressions though.

For now probably best if we just make SplitDriverVersion null terminate the unused output strings.

Flags: needinfo?(twsmith)
Assignee: nobody → jnicol
Status: NEW → ASSIGNED

I'll conservatively mark this sec-moderate because it sounds like this happens on startup without any real ability for an attacker to control the data.

Keywords: sec-moderate

Andrew, does this being sec-moderate mean I can just go ahead and land without sec-approval? That's how I'm reading the docs, but just want to be extra certain.

Flags: needinfo?(continuation)

(In reply to Jamie Nicol [:jnicol] from comment #6)

Andrew, does this being sec-moderate mean I can just go ahead and land without sec-approval? That's how I'm reading the docs, but just want to be extra certain.

That is correct.

Flags: needinfo?(continuation)
Group: gfx-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 105 Branch

Please nominate this for ESR102 approval when you get a chance.

Flags: needinfo?(jnicol)

This only affects android, as the other callers of SplitDriverVersion pass a string with 4 parts as it expected. Do we do ESR releases for Android?

Flags: needinfo?(jnicol) → needinfo?(ryanvm)

We do not. Thanks for clarifying.

Flags: needinfo?(ryanvm)
QA Whiteboard: [post-critsmash-triage]
Whiteboard: [adv-main105+r]
Attached file advisory.txt
Alias: CVE-2022-40961
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: