Closed
Bug 875402
Opened 12 years ago
Closed 11 years ago
WebAudio use-after-free crash [@mozilla::MediaInputPort::Release]
Categories
(Core :: Web Audio, defect)
Tracking
()
RESOLVED
FIXED
mozilla24
Tracking | Status | |
---|---|---|
firefox21 | --- | unaffected |
firefox22 | --- | disabled |
firefox23 | - | disabled |
firefox24 | + | fixed |
firefox-esr17 | --- | unaffected |
b2g18 | --- | unaffected |
People
(Reporter: posidron, Assigned: ehsan.akhgari)
References
Details
(4 keywords, Whiteboard: [adv-main24-])
Attachments
(6 files, 1 obsolete file)
If the testcase doesn't trigger at the first try, refresh the page one or two times.
alloc: ./content/media/webaudio/AudioNode.cpp:174
void
AudioNode::Connect(AudioNode& aDestination, uint32_t aOutput,
uint32_t aInput, ErrorResult& aRv)
{
[...]
* ps->AllocateInputPort(mStream, MediaInputPort::FLAG_BLOCK_INPUT,
static_cast<uint16_t>(aInput),
static_cast<uint16_t>(aOutput));
[...]
free: ./content/media/MediaStreamGraph.cpp:1882
void
MediaInputPort::Destroy()
{
class Message : public ControlMessage {
public:
Message(MediaInputPort* aPort)
: ControlMessage(nullptr), mPort(aPort) {}
virtual void Run()
{
mPort->Disconnect();
--mPort->GraphImpl()->mPortCount;
* NS_RELEASE(mPort);
}
[...]
}
re-use: ./content/media/MediaStreamGraph.h:737
* NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaInputPort)
Tested with m-i changeset: 132784:57f555f96ac9 and the patch in bug 874952
Reporter | ||
Updated•12 years ago
|
Summary: WebAudio use-after-free crash [@] → WebAudio use-after-free crash [@mozilla::MediaInputPort::Release]
Reporter | ||
Comment 1•12 years ago
|
||
Assignee | ||
Updated•12 years ago
|
Assignee: nobody → ehsan
Comment 2•12 years ago
|
||
Triaged branch flags with Ehsan.
status-firefox21:
--- → unaffected
status-firefox22:
--- → disabled
status-firefox23:
--- → affected
status-firefox24:
--- → affected
tracking-firefox23:
--- → ?
tracking-firefox24:
--- → ?
Assignee | ||
Comment 3•12 years ago
|
||
OK, so MediaInputPort::Destroy::Command holds a plain pointer to MediaInputPort, and NS_RELEASES it directly, claiming that the graph is the last thing holding on to the MediaInputPort. That is completely incorrect. You can allocate an input port and hold on to it as much as you want.
Assignee | ||
Comment 4•12 years ago
|
||
And FWIW, this bug should have been discovered before by fuzzing WebRTC etc, I would have expected.
Comment 5•12 years ago
|
||
I doubt the sequence that causes this is possible in webrtc, which only uses MediaInputPorts as part of nsDOMUserMediaStream in MediaManager.cpp (aka getUserMedia). The failure paths there are minimal, and it's closely tied to the associated MediaStream/TrackUnion.
Assignee | ||
Comment 6•12 years ago
|
||
After fixing that part of the bug, I hit bug 875221 on this test case.
Assignee | ||
Comment 7•12 years ago
|
||
(In reply to Randell Jesup [:jesup] from comment #5)
> I doubt the sequence that causes this is possible in webrtc, which only uses
> MediaInputPorts as part of nsDOMUserMediaStream in MediaManager.cpp (aka
> getUserMedia). The failure paths there are minimal, and it's closely tied
> to the associated MediaStream/TrackUnion.
Hmm, actually, maybe this is only an issue for the non-realtime MSGs...
Assignee | ||
Comment 8•12 years ago
|
||
Attachment #753493 -
Flags: review?(roc)
Updated•12 years ago
|
Comment on attachment 753493 [details] [diff] [review]
Patch (v1)
Review of attachment 753493 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/MediaStreamGraph.cpp
@@ +1906,5 @@
> virtual void RunDuringShutdown()
> {
> Run();
> }
> + nsRefPtr<MediaInputPort> mPort;
This is going to leak since you're adding a reference we weren't adding before.
The comment is definitely wrong, but I'm not sure why the NS_RELEASE is wrong. We need to release the MediaStreamGraph's reference to the port.
Assignee | ||
Comment 10•12 years ago
|
||
Hmm, I think you're right. For some reason the leak detector doesn't detect that. :(
So perhaps the real problem here is that mConsumers holds weak pointers to MediaInputPorts, and everything else holds a strong reference to it. If we made those nsRefPtrs, we should be able to remove this NS_RELEASE and just make the ControlCommand hold a normal nsRefPtr. Does that make sense?
Flags: needinfo?(roc)
Read the comment on MediaInputPort in MediaStreamGraph.h :-)
Note that in ProcessedMediaStream::AllocateInputPort, in the Run method that runs in the MediaStreamGraph thread, we have
// The graph holds its reference implicitly
mPort.forget();
So the already_AddRefed we throw away there is supposed to be released by the NS_RELEASE we're doing in Destroy's Run method. There shouldn't be a need to use nsRefPtrs actually inside the MediaStreamGraph.
So, I don't know why this code isn't working.
Flags: needinfo?(roc)
Reporter | ||
Comment 12•12 years ago
|
||
Assignee | ||
Comment 13•12 years ago
|
||
OK, so the problem here is that if ProcessedMediaStream::AllocateInputPort::Command is run during shutdown, it Release()'s mPort without registering it with the graph, and then later on we NS_RELEASE the pointer because we think that the graph is holding a reference to it, while it's not.
Assignee | ||
Comment 14•12 years ago
|
||
Attachment #753493 -
Attachment is obsolete: true
Attachment #753493 -
Flags: review?(roc)
Attachment #753822 -
Flags: review?(roc)
Assignee | ||
Comment 15•12 years ago
|
||
With the patch v2, we seem to hit another bug with this callstack...
Assignee | ||
Comment 16•12 years ago
|
||
Christoph, can you please see if you can minimize the test case once more with this patch applied?
Flags: needinfo?(cdiehl)
Reporter | ||
Comment 17•12 years ago
|
||
:Ehsan, I have noticed something similar, see: https://bugzilla.mozilla.org/show_bug.cgi?id=875221#c6
Yes, give me a few minutes.
Flags: needinfo?(cdiehl)
Attachment #753822 -
Flags: review?(roc) → review+
Updated•12 years ago
|
status-b2g18:
--- → unaffected
status-firefox-esr17:
--- → unaffected
Reporter | ||
Comment 18•12 years ago
|
||
Assignee | ||
Comment 19•12 years ago
|
||
(In reply to Christoph Diehl [:cdiehl] from comment #18)
> Created attachment 753840 [details]
> testcase-reduced-after-patch-2
Attached this to bug 875221.
Assignee | ||
Comment 20•12 years ago
|
||
Assignee | ||
Comment 21•12 years ago
|
||
Backed out, because the crashtest leaks:
https://hg.mozilla.org/integration/mozilla-inbound/rev/c4a85f341ffd
https://tbpl.mozilla.org/php/getParsedLog.php?id=23371046&tree=Cypress
Assignee | ||
Comment 22•12 years ago
|
||
The leak is bug 875911.
Assignee | ||
Comment 23•12 years ago
|
||
Landed with the fix to bug 875911 and converted the test to a mochitest to use SpecialPowers instead of fuzzPriv to force GC and CC.
Comment 24•11 years ago
|
||
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla24
Assignee | ||
Comment 25•11 years ago
|
||
Mass moving Web Audio bugs to the Web Audio component. Filter on duckityduck.
Component: Video/Audio → Web Audio
Updated•11 years ago
|
Updated•11 years ago
|
Whiteboard: [adv-main24-]
Updated•11 years ago
|
Group: core-security
You need to log in
before you can comment on or make changes to this bug.
Description
•