Closed
Bug 1463494
Opened 7 years ago
Closed 7 years ago
Crash in nsTArray_Impl<T>::Clear | GeckoAppShellSupport::OnSensorChanged
Categories
(Core Graveyard :: Widget: Android, defect)
Tracking
(firefox-esr52 unaffected, firefox-esr6061+ fixed, firefox60 wontfix, firefox61+ fixed, firefox62+ fixed)
RESOLVED
FIXED
mozilla62
People
(Reporter: marcia, Assigned: jesup)
References
Details
(Keywords: crash, regression, sec-high, Whiteboard: [post-critsmash-triage][adv-main61+][adv-esr60.1+][adv-esr52.9+])
Crash Data
Attachments
(2 files, 2 obsolete files)
|
1.54 KB,
patch
|
jesup
:
review+
abillings
:
approval-mozilla-beta+
abillings
:
approval-mozilla-esr60+
abillings
:
sec-approval+
|
Details | Diff | Splinter Review |
|
1.55 KB,
patch
|
jchen
:
review+
|
Details | Diff | Splinter Review |
This bug was filed from the Socorro interface and is
report bp-71f7b3e5-b093-489b-a343-95f4b0180522.
=============================================================
Seen while looking at crash stats. Marking as security sensitive due to addresses: https://bit.ly/2IVsRnN. Crashes started using 20180522100454.
Possible regression window based on Build ID: https://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=226437245483e931aa1413c2db7668435f03bff9&tochange=dc1868d255be744a7d2d462216be205086cc60af
Top 10 frames of crashing thread:
0 libxul.so nsTArray_Impl<BroadcastListener*, nsTArrayInfallibleAllocator>::Clear
1 libxul.so GeckoAppShellSupport::OnSensorChanged widget/android/nsAppShell.cpp:341
2 libxul.so mozilla::jni::detail::ProxyNativeCall<GeckoAppShellSupport, mozilla::java::GeckoAppShell, true, false, int, float, float, float, float, int, long long>::Call<true, false, 0, 1, 2, 3, 4, 5, 6> widget/android/jni/Natives.h:418
3 libxul.so mozilla::jni::detail::ProxyNativeCall<GeckoAppShellSupport, mozilla::java::GeckoAppShell, true, false, int, float, float, float, float, int, long long>::operator widget/android/jni/Natives.h:499
4 libxul.so mozilla::detail::RunnableFunction<mozilla::jni::detail::ProxyNativeCall<GeckoAppShellSupport, mozilla::java::GeckoAppShell, true, false, int, float, float, float, float, int, long long> >::Run xpcom/threads/nsThreadUtils.h:552
5 libxul.so nsThread::ProcessNextEvent xpcom/threads/nsThread.cpp:1090
6 libxul.so NS_ProcessNextEvent xpcom/threads/nsThreadUtils.cpp:519
7 libxul.so mozilla::ipc::MessagePump::Run ipc/glue/MessagePump.cpp:97
8 libxul.so MessageLoop::Run ipc/chromium/src/base/message_loop.cc:326
9 libxul.so nsBaseAppShell::Run widget/nsBaseAppShell.cpp:157
=============================================================
| Assignee | ||
Comment 2•7 years ago
|
||
So a regression from there seems likely - the Clear() call was added in bug 1425930, though it replaced an implicit ~nsTArray<> of a local array. However: the array is one of raw ptrs, not refcounted objects; on Clear() it should be doing little more than setting the Length() to 0 and maybe freeing the vector. So how would this UAF? The only obvious answer would be this is accessing this->mBroadcastCopy, which is the code we're running. This comes from gSensorObservers[] in Hal.cpp.
You'd think that would be fine, and nothing would rip it out from under us... but in UnregisterSensorObserver (which calls UnregisterObserver(), which is what required us to handle inside Broadcast() in bug 1425930) it checks if there are any sensor observers left in any class, and if there are none left, it deletes the gSensorObservers array. If this happened inside of Broadcast, this would reliably UAF now. Before, we were freeing an object that was still in use and running, with dangerous possible side-effects, though depending on the code you may get away with it (and the code only accesses a member once, at the start, so until someone touches the Broadcast() code it would happen to not crash - and I made it touch a member, so Boom).
Safe solution: don't free gSensorObservers[] - 8 objects with two nsTArrays each. I'm tempted to do that. Slightly fancier solution would be to defer the free via a runnable to MainThread (and thus not within the Broadcast()). froyd, snorp: preferences?
Flags: needinfo?(snorp)
Flags: needinfo?(rjesup)
Flags: needinfo?(nfroyd)
| Assignee | ||
Updated•7 years ago
|
Assignee: nobody → rjesup
(In reply to Randell Jesup [:jesup] from comment #2)
>
> Safe solution: don't free gSensorObservers[] - 8 objects with two nsTArrays
> each. I'm tempted to do that. Slightly fancier solution would be to defer
> the free via a runnable to MainThread (and thus not within the Broadcast()).
> froyd, snorp: preferences?
I have not followed that bug very closely, but it seems like it'll be fine to take option 1 here. My guess is that we probably have the observer array allocated most of the time anyway.
Flags: needinfo?(snorp)
Comment 4•7 years ago
|
||
I think it will be complicated to tell the leak checker that it's OK to leak gSensorObservers *and* the arrays contained therein. That means we need to carefully release the list via the event loop.
Flags: needinfo?(nfroyd)
| Assignee | ||
Comment 5•7 years ago
|
||
(In reply to Nathan Froyd [:froydnj] from comment #4)
> I think it will be complicated to tell the leak checker that it's OK to leak
> gSensorObservers *and* the arrays contained therein. That means we need to
> carefully release the list via the event loop.
Well, the arrays within the objects are all going to be empty, one presumes (we were only freeing this if all of them were empty). snorp: And do we run the leak checker on Android?
Flags: needinfo?(snorp)
(In reply to Randell Jesup [:jesup] from comment #5)
> (In reply to Nathan Froyd [:froydnj] from comment #4)
> > I think it will be complicated to tell the leak checker that it's OK to leak
> > gSensorObservers *and* the arrays contained therein. That means we need to
> > carefully release the list via the event loop.
>
> Well, the arrays within the objects are all going to be empty, one presumes
> (we were only freeing this if all of them were empty). snorp: And do we run
> the leak checker on Android?
AFAIK we don't, but I think Hal.cpp gets used on other platforms.
Flags: needinfo?(snorp)
Comment 7•7 years ago
|
||
We certainly had problems with the patch from bug 1425930 on Linux, so Hal.cpp is used there.
nsTArray calls into MOZ_COUNT_CTOR/DTOR, so even if the arrays are empty, we won't call the matching dtor if we leak gSensorObservers, right?
Updated•7 years ago
|
Blocks: 1425930
status-firefox60:
--- → unaffected
status-firefox61:
--- → affected
status-firefox-esr52:
--- → unaffected
status-firefox-esr60:
--- → affected
tracking-firefox61:
--- → +
tracking-firefox62:
--- → +
tracking-firefox-esr60:
--- → 61+
| Assignee | ||
Comment 8•7 years ago
|
||
if there's a better runnable-from-lambda that's not in media::, let me know. Tried it on Linux, but nothing triggers it (likely no sensors get added)
Attachment #8979999 -
Flags: review?(nfroyd)
Comment 9•7 years ago
|
||
Comment on attachment 8979999 [details] [diff] [review]
delete the sensor observerlist array in a deferred manner
Review of attachment 8979999 [details] [diff] [review]:
-----------------------------------------------------------------
r=me with the NS_NewRunnableFunction change.
::: hal/Hal.cpp
@@ +24,5 @@
> #include "mozilla/StaticPtr.h"
> #include "mozilla/dom/ContentChild.h"
> #include "mozilla/dom/ContentParent.h"
> #include "mozilla/dom/ScreenOrientation.h"
> +#include "mozilla/media/MediaUtils.h"
Please make this nsThreadUtils.h.
@@ +447,5 @@
> +
> + // We want to destroy gSensorObservers if all observer lists are
> + // empty, but we have to defer the deallocation via a runnable to
> + // mainthread (since we may be inside NotifySensorChange()/Broadcast()
> + // when it calls UnregisterSensorObserver()).
Unsure if this comment paints a bulls-eye on the issue or not.
@@ +453,3 @@
> gSensorObservers = nullptr;
> +
> + NS_DispatchToMainThread(media::NewRunnableFrom([sensorlists]() {
Please use NS_NewRunnableFunction, like all code outside of media/ does.
Attachment #8979999 -
Flags: review?(nfroyd) → review+
| Assignee | ||
Comment 10•7 years ago
|
||
No bullseye, since until the regressing patch landed this was a latent bug (nothing touched "this" after the Broadcast loop started calling Notify)
| Assignee | ||
Comment 11•7 years ago
|
||
| Assignee | ||
Updated•7 years ago
|
Attachment #8979999 -
Attachment is obsolete: true
| Assignee | ||
Comment 12•7 years ago
|
||
Comment on attachment 8980036 [details] [diff] [review]
delete the sensor observerlist array in a deferred manner
carry forward r+
[Approval Request Comment]
If this is not a sec:{high,crit} bug, please state case for ESR consideration: Latent sec-high UAF which is not needed on ESR unless we touch the Broadcast code (as in the regressing bug here)
User impact if declined: Latent sec bug
Fix Landed on Version: 62
Risk to taking this patch (and alternatives if risky): Low risk
String or UUID changes made by this patch: none
See https://wiki.mozilla.org/Release_Management/ESR_Landing_Process for more info.
Approval Request Comment
[Feature/Bug causing the regression]: N/A long ago
[User impact if declined]: We'd have to fix bug 1425930 in some other manner
[Is this code covered by automated tests?]: Yes
[Has the fix been verified in Nightly?]: No
[Needs manual test from QE? If yes, steps to reproduce]: Unsure how to reproduce
[List of other uplifts needed for the feature/fix]: bug 1425930
[Is the change risky?]: Not very
[Why is the change risky/not risky?]: simply defers freeing the memory
[String changes made/needed]: none
[Security approval request comment]
How easily could an exploit be constructed based on the patch? Very Hard/impossible (bug is latent until bug 1425930)
Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem? Somewhat, but no more so than the regressing bug, and no exploit of this is possible without the regressing bug.
Which older supported branches are affected by this flaw? all
If not all supported branches, which bug introduced the flaw? unknown (long ago)
Do you have backports for the affected branches? If not, how different, hard to create, and risky will they be? Trivial
How likely is this patch to cause regressions; how much testing does it need? Unlikely; minimal testing
Attachment #8980036 -
Flags: sec-approval?
Attachment #8980036 -
Flags: review+
Attachment #8980036 -
Flags: approval-mozilla-esr60?
Attachment #8980036 -
Flags: approval-mozilla-beta?
Comment 13•7 years ago
|
||
Making this a sec-high.
sec-approval+ for trunk and I'll give the other approvals as well.
Keywords: sec-high
Updated•7 years ago
|
Attachment #8980036 -
Flags: sec-approval?
Attachment #8980036 -
Flags: sec-approval+
Attachment #8980036 -
Flags: approval-mozilla-esr60?
Attachment #8980036 -
Flags: approval-mozilla-esr60+
Attachment #8980036 -
Flags: approval-mozilla-beta?
Attachment #8980036 -
Flags: approval-mozilla-beta+
| Assignee | ||
Comment 14•7 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/b837a2a32aebe36307641774f0960c8435082b1d
Before landing I ran an Android Try run, all green:
https://treeherder.mozilla.org/#/jobs?repo=try&revision=e8690f79d4dd693d41cbaaccc8f3a0c7fd40fb6e
| Assignee | ||
Comment 15•7 years ago
|
||
leaks the runnable and array list: mochitest-plain-headless-e10s-8 on linux64 debug.
Backed out: https://hg.mozilla.org/integration/mozilla-inbound/rev/89bd1716b6fa
Probably the infamous "DispatchToMainThread() failure during shutdown" case. :-(
Updated•7 years ago
|
Crash Signature: [@ nsTArray_Impl<T>::Clear | GeckoAppShellSupport::OnSensorChanged] → [@ nsTArray_Impl<T>::Clear | GeckoAppShellSupport::OnSensorChanged]
[@ arena_dalloc | Allocator<T>::free | nsTArray_base<T>::ShrinkCapacity | GeckoAppShellSupport::OnSensorChanged]
| Assignee | ||
Comment 16•7 years ago
|
||
Attachment #8980405 -
Flags: review?(nfroyd)
| Assignee | ||
Comment 17•7 years ago
|
||
Comment on attachment 8980405 [details] [diff] [review]
clean up sensorlist if Dispatch fails
Try issues
Attachment #8980405 -
Flags: review?(nfroyd)
| Assignee | ||
Comment 18•7 years ago
|
||
passes locally (the failing test is dom/system/tests/test_bug1197901.html). Pushing try to verify.
Attachment #8980431 -
Flags: review?(nfroyd)
| Assignee | ||
Updated•7 years ago
|
Attachment #8980405 -
Attachment is obsolete: true
| Assignee | ||
Comment 19•7 years ago
|
||
Updated•7 years ago
|
Attachment #8980431 -
Flags: review+
| Assignee | ||
Comment 20•7 years ago
|
||
Comment 21•7 years ago
|
||
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla62
Comment 22•7 years ago
|
||
| uplift | ||
Updated•7 years ago
|
Group: core-security → core-security-release
Comment 23•7 years ago
|
||
Comment on attachment 8980431 [details] [diff] [review]
clean up sensorlist if DispatchToMainThread fails
Canceling review on this, since jchen got to it before I did.
Attachment #8980431 -
Flags: review?(nfroyd)
Updated•7 years ago
|
Flags: qe-verify-
Whiteboard: [post-critsmash-triage]
Comment 24•7 years ago
|
||
Why is this marked as Firefox 60 is unaffected but ESR60 is affected?
I see we checked into Beta (61), which implies (with the ESR60 status) that Firefox 60 *is* affected. Comment 12 says "all" for what older branches are affected as well. Bug 1425930 is referenced, which affected Firefox 60 as well.
Flags: needinfo?(rjesup)
Comment 26•7 years ago
|
||
I blame the two being right next to each other on the drop-down.
Comment 27•7 years ago
|
||
Actually, it's probably because this first appeared to be a regression from bug 1425930, which was never uplifted to Fx60. But upon further inspection, it was a longstanding issue just exposed by that bug.
| Assignee | ||
Comment 28•7 years ago
|
||
Correct
Comment 29•7 years ago
|
||
Thanks. Putting it in the roll up advisory.
Updated•7 years ago
|
Whiteboard: [post-critsmash-triage] → [post-critsmash-triage][adv-main61+][adv-esr60.1+][adv-esr52.9+]
Updated•6 years ago
|
Group: core-security-release
Updated•3 years ago
|
Product: Core → Core Graveyard
You need to log in
before you can comment on or make changes to this bug.
Description
•