Closed
Bug 1185144
Opened 9 years ago
Closed 9 years ago
nsContentUtils::LogSimpleConsoleError() releases nsScriptErrorWithStack off the main thread
Categories
(Core :: XPCOM, defect)
Core
XPCOM
Tracking
()
RESOLVED
FIXED
mozilla42
Tracking | Status | |
---|---|---|
firefox41 | --- | unaffected |
firefox42 | --- | fixed |
People
(Reporter: mccr8, Assigned: mccr8)
References
Details
(4 keywords, Whiteboard: [post-critsmash-triage][b2g-adv-main2.5-])
Crash Data
Attachments
(1 file)
(deleted),
patch
|
froydnj
:
review+
|
Details | Diff | Splinter Review |
I came across this while looking at crash stacks. It looks like there is an error in NSS somewhere, then it calls nsContentUtils::LogSimpleConsoleError() to report the error. We then end up in nsConsoleService::LogMessageWithMode(). It looks like we've exceeded the size of the console buffer, so we pull out an error into |retiredMessage|. Then we call NS_RELEASE on this message, but unfortunately it is one of these new nsScriptErrorWithStack things, which is cycle collected, and we're off on some random thread, so we crash when we call release and try to find a cycle collector on the current thread. Maybe some kind of release-to-main-thread thing would work here?
https://crash-stats.mozilla.com/report/index/0191799f-f11f-468f-9771-4544d2150716
https://crash-stats.mozilla.com/report/index/4e742187-73ea-49fc-b38d-725ec2150717
https://crash-stats.mozilla.com/report/index/11fe052f-d318-48c5-9d6d-59a252150716
https://crash-stats.mozilla.com/report/index/e36637b0-93cd-41d2-81ca-aec2f2150716
https://crash-stats.mozilla.com/report/index/779a7203-d870-49cc-9b5e-505e32150717
Comment 1•9 years ago
|
||
Sotaro, I remember you had something that would automatically release something that was off-main-thread on the main thread (I seem to recall it was for gfx), would you mind telling us if we could reuse it here?
Flags: needinfo?(sotaro.ikeda.g)
Comment 2•9 years ago
|
||
NS_ReleaseOnMainThread?
Comment 3•9 years ago
|
||
(In reply to Nathan Froyd [:froydnj][:nfroyd] from comment #2)
> NS_ReleaseOnMainThread?
Yes!
But I don't know how I could distinguish nsScriptErrorWithStack instances here:
http://mxr.mozilla.org/mozilla-central/source/xpcom/base/nsConsoleService.cpp#323
We have nsScriptError(thread-safe) and nsScriptErrorWithStack(main-thread, garbage collected) instances. And possibly other kind of objects that inherits from nsIConsoleMessage.
We could have QI into nsIConsoleMessageWithStack, but as stated in bug 814497 command 55, I wasn't able to implement such custom interface. Also it sounds bad regarding performances to do a QI?
Flags: needinfo?(sotaro.ikeda.g)
Assignee | ||
Comment 4•9 years ago
|
||
(In reply to Alexandre Poirot [:ochameau] from comment #3)
> We have nsScriptError(thread-safe) and nsScriptErrorWithStack(main-thread,
> garbage collected) instances. And possibly other kind of objects that
> inherits from nsIConsoleMessage.
Maybe add a C++-only method ReleaseFromAnyThread() to nsIConsoleMessage?
> We could have QI into nsIConsoleMessageWithStack, but as stated in bug
> 814497 command 55, I wasn't able to implement such custom interface.
The assertion you were seeing means that you didn't clear the JS object in the unlink method. That is bad because it could potentially lead to a dangling pointer to a JS object.
> Also it sounds bad regarding performances to do a QI?
It isn't the fastest thing around, but it is probably not too bad compared to everything else that is going on in that method already, and I'd think it is much cheaper than doing the ReleaseToMainThread.
Assignee | ||
Updated•9 years ago
|
status-firefox41:
--- → unaffected
Assignee | ||
Updated•9 years ago
|
Crash Signature: [@ NS_CycleCollectorSuspect3]
Comment 5•9 years ago
|
||
Can't we just use NS_ReleaseOnMainThread() here? gfx things do not work here, since classes are expected to be derived from AtomicRefCountedWithFinalize.
Assignee | ||
Comment 6•9 years ago
|
||
In terms of security implications, the actual stack here is benign: we will always hit a null deref crash. However, both the main thread and worker threads have a cycle collector. If there are a bunch of errors from the main thread, then you try to dispatch a console error message on a worker using LogSimpleConsoleError, then you'd end up with a main thread object being manipulated by the worker cycle collector, which could be quite bad. I assume we only generate these error messages with stacks when the browser console is open, due to perf concerns, so that mitigates this.
Assignee | ||
Comment 7•9 years ago
|
||
(In reply to Sotaro Ikeda [:sotaro] from comment #5)
> Can't we just use NS_ReleaseOnMainThread() here? gfx things do not work
> here, since classes are expected to be derived from AtomicRefCountedWithFinalize.
Yes, I think that would be okay. It would be doing some more work than is really needed in the common case, but I doubt this code is super perf sensitive.
Comment 8•9 years ago
|
||
(In reply to Andrew McCreight [:mccr8] from comment #6)
> I assume we only generate these error messages with stacks when the browser
> console is open, due to perf concerns, so that mitigates this.
I think we do it no matter what. We always pass the stack objects along, but only start processing/accessing it when a console is opened. Note that it isn't just for the Browser console. it is especially for regular content where we were missing stack for JS exception.
(In reply to Andrew McCreight [:mccr8] from comment #7)
> (In reply to Sotaro Ikeda [:sotaro] from comment #5)
> > Can't we just use NS_ReleaseOnMainThread() here? gfx things do not work
> > here, since classes are expected to be derived from AtomicRefCountedWithFinalize.
>
> Yes, I think that would be okay.
Hum. But if we just replace NS_Release with NS_ReleaseOnMainThread wouldn't it be broken on the opposite direction? Where objects on the other threads are not going to be released correctly?
(In reply to Andrew McCreight [:mccr8] from comment #4)
> (In reply to Alexandre Poirot [:ochameau] from comment #3)
> > We have nsScriptError(thread-safe) and nsScriptErrorWithStack(main-thread,
> > garbage collected) instances. And possibly other kind of objects that
> > inherits from nsIConsoleMessage.
>
> Maybe add a C++-only method ReleaseFromAnyThread() to nsIConsoleMessage?
That would call NS_RELEASE(this) and be overloaded by nsScriptErrorWithStack to call NS_ReleaseOnMainThread?
>
> > We could have QI into nsIConsoleMessageWithStack, but as stated in bug
> > 814497 command 55, I wasn't able to implement such custom interface.
>
> The assertion you were seeing means that you didn't clear the JS object in
> the unlink method. That is bad because it could potentially lead to a
> dangling pointer to a JS object.
Sorry, I meant bug 814497 comment 56, I fixed the assertion of comment 55.
Assignee | ||
Comment 9•9 years ago
|
||
(In reply to Alexandre Poirot [:ochameau] from comment #8)
> Hum. But if we just replace NS_Release with NS_ReleaseOnMainThread wouldn't
> it be broken on the opposite direction? Where objects on the other threads
> are not going to be released correctly?
For threadsafe objects, I think it should be okay. But yeah I guess NS_ReleaseOnMainThread won't really work, because I guess the console message could have been created on the cycle collector thread, and we'd need to release it there. I'm not sure how to deal with that, without each nsScriptErrorWithStack somehow carrying around a thread pointer object.
> That would call NS_RELEASE(this) and be overloaded by nsScriptErrorWithStack
> to call NS_ReleaseOnMainThread?
That was my idea, but as you said this won't actually work if the error with stack isn't on the main thread.
> > > We could have QI into nsIConsoleMessageWithStack, but as stated in bug
> > > 814497 command 55, I wasn't able to implement such custom interface.
> >
> > The assertion you were seeing means that you didn't clear the JS object in
> > the unlink method. That is bad because it could potentially lead to a
> > dangling pointer to a JS object.
>
> Sorry, I meant bug 814497 comment 56, I fixed the assertion of comment 55.
Oh, okay. For that, I think you need to use NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS. If you want to address that in a separate open bug I can help you with that. I think a ReleaseOnOwnThread() kind of method is a better approach, but others may disagree.
Comment 10•9 years ago
|
||
Sorry I missed this in review :-(
Assignee | ||
Comment 11•9 years ago
|
||
billm suggested that we're probably in trouble anyways if one of these things is being created on a worker, so we should probably just assert or even release assert that nsScriptErrorWithStack is only created on the main thread, and then we can do release to main thread.
Assignee | ||
Comment 12•9 years ago
|
||
Alexandre, should it be okay for now if we restrict nsScriptErrorWithStack to being created on the main thread, or is this expected to work for workers right now?
Assignee: nobody → continuation
Flags: needinfo?(poirot.alex)
Comment 13•9 years ago
|
||
Assuming the devtools code runs on the main thread JSRuntime, there's no way it would be able to access worker stuff anyway.
Assignee | ||
Comment 14•9 years ago
|
||
Ok. Yeah, it looks like this object is only created in some XPConnect method xpc::ErrorReport::LogToConsoleWithStack, so hopefully it will be okay.
Flags: needinfo?(poirot.alex)
Assignee | ||
Comment 15•9 years ago
|
||
I think this can be moderate given that these error messages only seem to be made on the main thread. I added an assert in my try push to double-check that assumption.
Keywords: sec-high → sec-moderate
Assignee | ||
Comment 16•9 years ago
|
||
Well, except that the problem is when any kind of console message is generated on a worker thread. I'm not confident enough that that doesn't happen, so I'll just leave it at high. This is trunk-only so it doesn't matter too much either way. The real bug here is in nsConsoleService. I'll try to look through other places that use nsIConsoleMessage.
Component: XPConnect → XPCOM
Keywords: sec-moderate → sec-high
Comment 17•9 years ago
|
||
Yes. Worker isn't targeted by this patch. We would be happy to start by seeing just main thread stacks!
Assignee | ||
Comment 18•9 years ago
|
||
Also, add release asserts that the other methods that addref or release console messages are only run on the main thread.
Finally, add an assert that nsScriptErrorWithStack is only created on the main thread.
try run: https://treeherder.mozilla.org/#/jobs?repo=try&revision=3b7a51e5cc3d
Attachment #8636342 -
Flags: review?(nfroyd)
Comment 19•9 years ago
|
||
Comment on attachment 8636342 [details] [diff] [review]
nsConsoleService::LogMessageWithMode() should release the retired message on the main thread.
Review of attachment 8636342 [details] [diff] [review]:
-----------------------------------------------------------------
::: js/xpconnect/src/nsScriptErrorWithStack.cpp
@@ +42,5 @@
> nsScriptErrorWithStack::nsScriptErrorWithStack(JS::HandleObject aStack)
> : nsScriptError(),
> mStack(aStack)
> {
> + MOZ_ASSERT(NS_IsMainThread(), "You can't use this class on workers.");
Not MOZ_RELEASE_ASSERT?
Attachment #8636342 -
Flags: review?(nfroyd) → review+
Assignee | ||
Comment 20•9 years ago
|
||
(In reply to Nathan Froyd [:froydnj][:nfroyd] from comment #19)
> Not MOZ_RELEASE_ASSERT?
This is a new class that isn't used in many places, so I feel like I have a good understanding of how it is called, and any further changes will probably have tests, so I think that's good enough.
Thanks for the fast review!
https://hg.mozilla.org/integration/mozilla-inbound/rev/49ae0961591e
Assignee | ||
Comment 21•9 years ago
|
||
From my perusal of stacks on crash reports, this is the number 2 crash on Nightly 42 ("about to become #1 on Nightly" according to Tracy).
Status: NEW → RESOLVED
Closed: 9 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla42
Updated•9 years ago
|
Group: core-security → core-security-release
Updated•9 years ago
|
Whiteboard: [post-critsmash-triage]
Updated•9 years ago
|
Group: core-security-release
Updated•9 years ago
|
Whiteboard: [post-critsmash-triage] → [post-critsmash-triage][b2g-adv-main2.5-]
You need to log in
before you can comment on or make changes to this bug.
Description
•