Closed
Bug 1018299
Opened 10 years ago
Closed 8 years ago
MediaRecorder needs to handle dynamic stream principals
Categories
(Core :: Audio/Video: Recording, defect, P1)
Core
Audio/Video: Recording
Tracking
()
RESOLVED
FIXED
mozilla48
Tracking | Status | |
---|---|---|
firefox48 | --- | fixed |
People
(Reporter: mt, Assigned: jib)
References
()
Details
Attachments
(3 files, 2 obsolete files)
Bug 966066 adds the ability to have media on the MediaStreamGraph that have both content and changing principals. This was previously possible for HTMLMediaElement, but that does not emit media into the graph if the media principal is not subsumed by the document principal. So up until now, the static checks that MediaRecorder is performing were sufficient. Those checks occur on .start() and when new blobs are about to be passed to the application. This is not sufficient in general, since media could have a subsumed principal at both those points, but briefly change to another principal during the recording process. This could be exploited by an application to gain access to cross origin content. MediaRecorder probably needs to stop once it is no longer able to subsume a stream. Since it's possible that the entire recording is tainted when principals change.
Reporter | ||
Comment 1•10 years ago
|
||
Work in progress. Need to work out how to actually test this.
Assignee: nobody → martin.thomson
Status: NEW → ASSIGNED
Reporter | ||
Comment 2•10 years ago
|
||
This test doesn't work, because MediaRecorder doesn't seem to be able to produce a recording from a microphone. Until that is possible, this bug isn't worth my time fixing.
Updated•10 years ago
|
Component: WebRTC: Audio/Video → Video/Audio: Recording
Comment 3•10 years ago
|
||
Could we try to use the fake audio in gUM?
(In reply to Martin Thomson [:mt] from comment #2) > Created attachment 8431889 [details] [diff] [review] > 0001-Bug-1018299-Test-for-changing-principals-in-recorder.patch > > This test doesn't work, because MediaRecorder doesn't seem to be able to > produce a recording from a microphone. Until that is possible, this bug > isn't worth my time fixing. Hi Martin, I think you means MediaRecorder doesn't seem to be able to produce a recording from a microphone on *emulator*. If that's the case, please check comment #3
Reporter | ||
Comment 5•10 years ago
|
||
(In reply to C.J. Ku[:cjku] from comment #4) > Hi Martin, > I think you means MediaRecorder doesn't seem to be able to produce a > recording from a microphone on *emulator*. If that's the case, please check > comment #3 Oh. I was using a desktop build. I infer from this that MediaRecorder, despite being present and accessible, doesn't work on desktop builds.
Comment 6•10 years ago
|
||
Hi Martin, I found if you use mozCaptureStream to get the stream from audio tag, The original audio tag would stop playing and no data feed into recorder. You can replace the mozCaptureStream with using audio.mozSrcObject or stream from gUM directly.
Reporter | ||
Comment 7•10 years ago
|
||
Is there a bug for that?
Updated•8 years ago
|
Rank: 17
Priority: -- → P1
Comment 9•8 years ago
|
||
How important is it to fix this bug in the next release or two? (I'm re-examining all the P1s for Recording and need to know if this is really a "should fix soon" bug.) Also, how close is your patch to landing? Thanks.
Flags: needinfo?(martin.thomson)
Reporter | ||
Comment 10•8 years ago
|
||
This is an open cross site information leakage bug. It probably should have been fixed before shipping.
Flags: needinfo?(martin.thomson)
Comment 11•8 years ago
|
||
MediaRecorder fully works on Desktop, and it is testable; so this bug is actionable. You're currently the bug owner. Do you have the time to fix it now, or should I put someone else on it?
Flags: needinfo?(martin.thomson)
Updated•8 years ago
|
Rank: 17 → 10
Reporter | ||
Comment 12•8 years ago
|
||
Might be better to try to find someone. I just tried to build gecko and that's going to take me quite some time to fix.
Flags: needinfo?(martin.thomson)
Updated•8 years ago
|
Assignee: martin.thomson → jib
Assignee | ||
Comment 13•8 years ago
|
||
(In reply to Randy Lin [:rlin] - Be Mozillian on 2015/01/26 from comment #6) > I found if you use mozCaptureStream to get the stream from audio tag, > The original audio tag would stop playing and no data feed into recorder. I see this still unfortunately. > You can replace the mozCaptureStream with using audio.mozSrcObject or stream > from gUM directly. Yeah that would work, except the whole point of this test was to have a source whose peer identity changed after it was created, and there's no way to change the identity of an existing gUM track. In any case, peerIdentity has since moved to RTCPeerConnection in the spec, so this all seems moot. I'll see if I can redo this test to record over a peer connection.
Assignee | ||
Comment 14•8 years ago
|
||
To recap, since gUM streams can't change peerIdentity, and HTMLMediaElements apparently can't be used as switchers between gum streams, there seems to be no security hole here, and no need for this patch, until bug 1257569 is fixed. Marking as blocked on that bug so we can have a working test. Please unblock if there's another case I don't know about.
Depends on: 1257569
Flags: needinfo?(martin.thomson)
Assignee | ||
Comment 15•8 years ago
|
||
Review commit: https://reviewboard.mozilla.org/r/40809/diff/#index_header See other reviews: https://reviewboard.mozilla.org/r/40809/
Assignee | ||
Comment 16•8 years ago
|
||
Review commit: https://reviewboard.mozilla.org/r/40811/diff/#index_header See other reviews: https://reviewboard.mozilla.org/r/40811/
Assignee | ||
Comment 17•8 years ago
|
||
Comment on attachment 8431680 [details] [diff] [review] 0001-Bug-1018299-MediaRecorder-reacts-to-stream-principal.patch Uploaded rebased patches since they were nearly two years old.
Attachment #8431680 -
Attachment is obsolete: true
Assignee | ||
Updated•8 years ago
|
Attachment #8431889 -
Attachment is obsolete: true
Assignee | ||
Updated•8 years ago
|
Rank: 10 → 19
Reporter | ||
Comment 18•8 years ago
|
||
It should be possible to use HTMLMediaElement.captureStream with a redirect mid-load. I seem to recall seeing a test that does that.
Flags: needinfo?(martin.thomson)
Assignee | ||
Comment 19•8 years ago
|
||
Like this? https://jsfiddle.net/40cogc45/ Thing is, it already fails with SecurityError even without this patch. If you have something else in mind, please let me know.
Flags: needinfo?(martin.thomson)
Assignee | ||
Comment 20•8 years ago
|
||
If it helps, the fiddle in comment 19 fails (with or without a patch) with NS_ERROR_DOM_SECURITY_ERR here: http://mxr.mozilla.org/mozilla-central/source/dom/media/MediaRecorder.cpp?rev=dce8cc239a84&mark=185-185#160
Reporter | ||
Comment 21•8 years ago
|
||
The example I saw, but am unable to find in the current tree is something like this: <video> is sourced from example.com. That video is loaded in pieces, with HTTP ranges. A chunk in the middle of the file is requested, but is redirected to other.example. This causes the principal of the media to change to other.example. I'm certain that there used to be a test for this, but there has been a lot of churn in the media code in the time since I last looked. It could be that we lost it. All examples that rely on simply changing the source of the <video> element seem less likely to trigger this sort of thing, your example seems to just change src/srcObject. Also, I'm on Nightly and your test doesn't throw any exceptions.
Flags: needinfo?(martin.thomson)
Assignee | ||
Comment 22•8 years ago
|
||
(In reply to Martin Thomson [:mt:] from comment #21) > your example seems to just change src/srcObject. Yes, I just couldn't find a simpler way to compensate for lack of same-origin content on jsfiddle.net. > Also, I'm on Nightly and your test doesn't throw any exceptions. Odd, the first time I tried it in Nightly after reading this, I got the same thing, just: recording for 5 seconds... recording for 5 seconds... and then nothing. But every time after that, I get this again: recording for 5 seconds... recording for 5 seconds... Partial recording due to SecurityError Playing video/webm recording. (In the fiddle output window, not web console) Maybe there was a hardware delay long enough to let recording finish the first time? Anyway, let me know if you still don't see it. Will look into http ranges.
Assignee | ||
Comment 23•8 years ago
|
||
This one? http://mxr.mozilla.org/mozilla-central/source/dom/media/test/test_mixed_principals.html?force=1#27 I'll try adding mozCaptureStreamUntilEnded() to it, but I suspect it's already handled.
Assignee | ||
Comment 24•8 years ago
|
||
Comment on attachment 8731742 [details] MozReview Request: Bug 1018299 - MediaRecorder reacts to stream principal change Review request updated; see interdiff: https://reviewboard.mozilla.org/r/40809/diff/1-2/
Assignee | ||
Comment 25•8 years ago
|
||
Comment on attachment 8731744 [details] MozReview Request: Bug 1018299 - Test for changing principals in recorder Review request updated; see interdiff: https://reviewboard.mozilla.org/r/40811/diff/1-2/
Assignee | ||
Comment 26•8 years ago
|
||
OK I've updated the test as mentioned in comment 23, but the test is failing with the patches here. failed | Failed to reject in MediaRecorder for v1 that is, not seeing any SecurityError. Need to investigate tomorrow. If anything obvious sticks out, let me know.
Reporter | ||
Comment 27•8 years ago
|
||
https://reviewboard.mozilla.org/r/40811/#review38047 I'm not sure that these comments are helpful, but maybe... ::: dom/media/test/test_mediarecorder_principals.html:35 (Diff revision 2) > + record(v.mozCaptureStreamUntilEnded(), 20000) > + .then(recording => { > + v2.src = URL.createObjectURL(new Blob(recording)); > + return new Promise(resolve => v2.onplaying = resolve); > + }) I would expect the first capture to produce a stream with the null principal (after the seek based on the comment, and I'm not sure when that happens exactly). That should cause the first call to record to fail when it encounters the changed principal. I'm not sure that the Blob part is necessary. ::: dom/media/test/test_mediarecorder_principals.html:45 (Diff revision 2) > + .then(() => ok(false, "Failed to reject in MediaRecorder for " + id)) > + .catch(e => ok(true, "Threw exception in MediaRecorder for " + id)) > + .then(() => { > + SimpleTest.finish(); > + }) > + .catch(e => setTimeout(() => { throw e; })); Maybe we need an unrollStackAndThrow method here. Note that setTimeout(f, 0) actually takes 4ms. ::: dom/media/test/test_mediarecorder_principals.html:55 (Diff revision 2) > + // to a different origin ('localhost:8888' will be redirected to 'example.org', > + // and 'example.org' will be redirected to 'localhost:8888'). We rely on the > + // fact that Ogg will do a seek to the end of the resource, triggering a new > + // load with the same key which will return a same-origin resource. > + // Loading data from two different origins should be detected by the media > + // cache and result in a null principal so that the canvas usage above fails. fix "canvas usage" ::: dom/media/test/test_mediarecorder_principals.html:68 (Diff revision 2) > + todo(false, "No types supported"); > +} > + > +var record = (stream, ms) => { > + var config = { mimeType: 'video/webm;codecs="vp8,opus"' }; > + var rec = new MediaRecorder(stream, config), data = []; If the video tag is tainted immediately, then this should throw. Is there an existing test that covers that? ::: dom/media/test/test_mediarecorder_principals.html:72 (Diff revision 2) > + var config = { mimeType: 'video/webm;codecs="vp8,opus"' }; > + var rec = new MediaRecorder(stream, config), data = []; > + rec.ondataavailable = e => data.push(e.data); > + rec.start(); > + let interval = setInterval(() => > + rec.state == "recording" && rec.requestData(), 200); This is a little too aggressive a compression for me. Braces aren't that bad: ``` setInterval(_ => { if (rec.state == "recording") { rec.requestData(); } }, 200); ``` ::: dom/media/test/test_mediarecorder_principals.html:76 (Diff revision 2) > + return Promise.all([ > + stopped, > + wait(ms).then(() => rec.state == "recording" && rec.stop()) > + ]) Isn't it enough to wait for `stopped`, since you are calling .stop after waiting? ::: dom/media/test/test_mediarecorder_principals.html:80 (Diff revision 2) > + .then(() => (clearInterval(interval), data)) > + .catch(e => { > + clearInterval(interval); > + if (!data.length) throw e; > + info("Partial recording due to "+ e); > + return data; > + }); .catch({ and check for partial recording }) .then({ clearInterval(); return data; })
Assignee | ||
Comment 28•8 years ago
|
||
https://reviewboard.mozilla.org/r/40811/#review38047 > I would expect the first capture to produce a stream with the null principal (after the seek based on the comment, and I'm not sure when that happens exactly). > > That should cause the first call to record to fail when it encounters the changed principal. I'm not sure that the Blob part is necessary. This is the first and only capture btw, and yes I expected it to throw also, or at least onerror out sometime before the blob is playing, but it appears to play without incident unfortunately. > If the video tag is tainted immediately, then this should throw. Is there an existing test that covers that? There was here before I removed it (as I massaged a similar test), and it did throw SecurityError. I've put it back in. > Isn't it enough to wait for `stopped`, since you are calling .stop after waiting? Sure, but this way all errors get handled in one place.
Reporter | ||
Comment 29•8 years ago
|
||
https://reviewboard.mozilla.org/r/40811/#review38047 > This is the first and only capture btw, and yes I expected it to throw also, or at least onerror out sometime before the blob is playing, but it appears to play without incident unfortunately. I think that you misunderstand. If the recording succeeds, then I would expect that the content will be same-origin. It's the recording that I expect to have failed. I know that you can have cross-origin blobs, but MediaRecorder shouldn't produce them.
Assignee | ||
Comment 30•8 years ago
|
||
I should have noticed sooner, but the test I based this test on, test_mixed_principals.html, does not work for me at all locally either, and has apparently been disabled in the tree since 2010 (!) (bug 567954). This is turning into a rat hole.
Reporter | ||
Comment 31•8 years ago
|
||
Hmm, unused or commented-out code is a bad pattern. Is it possible to verify this in a gtest instead? One where you can just *change* the principal on a stream and observe the effect that has. That's probably a lot of work though. The original code is clearly not able to deal with changing principals, so there is a problem to solve, but it's not worth landing a change if we can't be sure that the change actually does something.
Assignee | ||
Comment 32•8 years ago
|
||
Comment on attachment 8731742 [details] MozReview Request: Bug 1018299 - MediaRecorder reacts to stream principal change Review request updated; see interdiff: https://reviewboard.mozilla.org/r/40809/diff/2-3/
Attachment #8731742 -
Flags: review?(martin.thomson)
Attachment #8731744 -
Flags: review?(martin.thomson)
Assignee | ||
Comment 33•8 years ago
|
||
Comment on attachment 8731744 [details] MozReview Request: Bug 1018299 - Test for changing principals in recorder Review request updated; see interdiff: https://reviewboard.mozilla.org/r/40811/diff/2-3/
Assignee | ||
Comment 34•8 years ago
|
||
Finally a green try - https://treeherder.mozilla.org/#/jobs?repo=try&revision=2750dc0cbad0 I've tamed the test. Note: I changed MediaRecorder to fire .onerror with SecurityError in addition to stopping, as that seems consistent with existing behavior and the spec ("An error has occurred, e.g. out of memory or a modification to the stream has occurred that makes it impossible to continue recording").
Assignee | ||
Comment 35•8 years ago
|
||
Note that the interdiffs show chaff due to rebase.
Reporter | ||
Comment 36•8 years ago
|
||
Comment on attachment 8731742 [details] MozReview Request: Bug 1018299 - MediaRecorder reacts to stream principal change https://reviewboard.mozilla.org/r/40809/#review41387 Looks fine. ::: dom/media/MediaRecorder.cpp:1317 (Diff revision 3) > + if ((!mDOMStream && !mAudioNode) || !GetOwner() || !doc || !srcPrincipal) { > + LOG(LogLevel::Debug, ("MediaRecorder principal not subsuming")); > return false; > } > - bool subsumes; > if (NS_FAILED(doc->NodePrincipal()->Subsumes(srcPrincipal, &subsumes))) { NS_WARN_IF instead?
Attachment #8731742 -
Flags: review?(martin.thomson) → review+
Reporter | ||
Comment 37•8 years ago
|
||
Comment on attachment 8731744 [details] MozReview Request: Bug 1018299 - Test for changing principals in recorder https://reviewboard.mozilla.org/r/40811/#review41391 Nice work. ::: dom/media/test/test_mediarecorder_principals.html:64 (Diff revision 3) > + > + let msg = "mediaRecorder.start() must throw SecurityError"; > + return new Promise(resolve => video.onplaying = resolve) > + .then(() => waitUntil(() => video.currentTime > resource.duration / 2)) > + .then(() => new MediaRecorder(video.mozCaptureStreamUntilEnded()).start()) > + .then(() => ok(false, msg), e => is(e.name, "SecurityError", msg)) Just to be safe, can you add a .catch to the line above this one so that you can catch and filter out early exceptions? ::: dom/media/test/test_mediarecorder_principals.html:80 (Diff revision 3) > + let msg1 = "mediaRecorder.start() should not throw here"; > + let msg2 = "mediaRecorder.onerror must fire SecurityError"; > + let msg3 = "mediaRecorder.onstop must also have fired"; msg1 -> msgNoThrow msg2 -> msgSecErr msg3 -> msgOnStop ::: dom/media/test/test_mediarecorder_principals.html:90 (Diff revision 3) > + rec.ondataavailable = e => data.push(e.data); > + rec.start(); > + hasStopped = new Promise(resolve => rec.onstop = resolve); > + video.play(); > + }) > + .then(() => ok(true, msg1), e => is(e.name, null, msg1)) The .catch side of this clause is strange. Can't you just do ok(false, msg1) ? ::: dom/media/test/test_mediarecorder_principals.html:104 (Diff revision 3) > + }) > + .catch(e => throwOutside(e)) > + .then(() => SimpleTest.finish()) > + .catch(e => throwOutside(e)); > +} else { > + todo(false, "No types supported"); This is definitely worth an early return. And yes, that suggests a function or two.
Attachment #8731744 -
Flags: review?(martin.thomson) → review+
Assignee | ||
Comment 38•8 years ago
|
||
https://reviewboard.mozilla.org/r/40811/#review41391 > Just to be safe, can you add a .catch to the line above this one so that you can catch and filter out early exceptions? A catch above would make the chain continue in the face of error, but I can do a "catch-bypass" (I'm coining it). Preemptive example: https://jsfiddle.net/834o22c3/ > The .catch side of this clause is strange. Can't you just do ok(false, msg1) ? The benefit is it logs the error. e.g. "UNEXPECTED: mediaRecorder.start() should not throw here - got "InvalidStateError", expected null".
Assignee | ||
Comment 39•8 years ago
|
||
Comment on attachment 8731742 [details] MozReview Request: Bug 1018299 - MediaRecorder reacts to stream principal change Review request updated; see interdiff: https://reviewboard.mozilla.org/r/40809/diff/3-4/
Assignee | ||
Comment 40•8 years ago
|
||
Comment on attachment 8731744 [details] MozReview Request: Bug 1018299 - Test for changing principals in recorder Review request updated; see interdiff: https://reviewboard.mozilla.org/r/40811/diff/3-4/
Assignee | ||
Comment 41•8 years ago
|
||
Andreas, the first patch here got trounced by your clone landing, could you help me rebase it? I'm having trouble keeping track of where everything went (no pun intended). Looks like you improved principal handling in the process... so I wonder is this patch even needed anymore? The tests are still valuable regardless: You changed .start() so it can no longer throw SecurityError (which I guess wasn't to spec anyway?) which trips up my first of two tests, but the second test succeeds!
Flags: needinfo?(pehrsons)
Comment 42•8 years ago
|
||
Right, so in your code you introduce one of the old PrincipalChangeObservers for DOMMediaStream, while I changed it to use listeners and PrincipalChangeObservers for MediaStreamTrack instead. The rest is basically the same. When a track we're recording changes its principal, we check the principals for all tracks here: https://dxr.mozilla.org/mozilla-central/rev/21bf1af375c1fa8565ae3bb2e89bd1a0809363d4/dom/media/MediaRecorder.cpp#429 I.e., we don't need that patch. -- The spec doesn't mention throwing a security error in the start() algorithm, instead it says the following: > If at any point the stream's isolation properties change so that MediaRecorder is no longer allowed access to it, the UA must stop recording, discard any data that it has gathered and throw a SecurityError DOMException followed by the stop event. Now, can you throw something when not in a method called to by the user? I imagine it should use the error event instead. We should raise that to the spec.
Flags: needinfo?(pehrsons)
Assignee | ||
Comment 43•8 years ago
|
||
Right, we can only throw something when in a method called by the user. Curious, was there a technical reason for the move? I think I'm fine with the new behavior (not throwing SecurityError in .start(), but fire the error callback instead), as it cuts down on codepaths with almost the same outcome. We should double-check there's no way to exploit this delay to have dataavailable fire before the principal check. The spec text is quite terrible (not queuing the firing of dataavailble, a major concurrency issue), so I'm filing several issues on it.
Flags: needinfo?(pehrsons)
Comment 44•8 years ago
|
||
Technical reason - don't think so. Can't remember exactly :-) This can't leak any blobs. Main thread is always notified of the principal change before any data goes through the MSG, and we use the same error event path as before (`DoSessionEndTask(NS_ERROR_DOM_SECURITY_ERR)`), which doesn't surface the current blob: https://dxr.mozilla.org/mozilla-central/rev/21bf1af375c1fa8565ae3bb2e89bd1a0809363d4/dom/media/MediaRecorder.cpp#830
Flags: needinfo?(pehrsons)
Assignee | ||
Comment 45•8 years ago
|
||
In light of https://github.com/w3c/mediacapture-record/issues/55#issuecomment-211152977 I think we should make .start() throw SecurityError again. Andreas, if you have tips on the best way to do this with the new way things work, I'd appreciate them.
Flags: needinfo?(pehrsons)
Comment 47•8 years ago
|
||
We ignore the check in case there are no tracks yet available in the MediaStream. There are legacy tests depending on track-less-stream-to-MediaRecorder working and the spec doesn't mention it. Review commit: https://reviewboard.mozilla.org/r/47467/diff/#index_header See other reviews: https://reviewboard.mozilla.org/r/47467/
Attachment #8742869 -
Flags: review?(martin.thomson)
Attachment #8742869 -
Flags: review?(jib)
Comment 48•8 years ago
|
||
Try push: https://treeherder.mozilla.org/#/jobs?repo=try&revision=1d8ee7631a9d
Assignee | ||
Updated•8 years ago
|
Attachment #8742869 -
Flags: review?(jib) → review+
Assignee | ||
Comment 49•8 years ago
|
||
Comment on attachment 8742869 [details] MozReview Request: Bug 1018299 - Throw security error if principal check fails in MediaRecorder::Start(). r?jib,mt https://reviewboard.mozilla.org/r/47467/#review44173 wfm. Thanks. ::: dom/media/MediaRecorder.cpp:1068 (Diff revision 1) > + nsIDocument* doc; > + if (!(window = GetOwner())) { > + subsumes = false; > + } else if (!(doc = window->GetExtantDoc())) { > + subsumes = false; > + } else if (NS_FAILED(doc->NodePrincipal()->Subsumes( Maybe NS_WARN as well?
Reporter | ||
Comment 50•8 years ago
|
||
Comment on attachment 8742869 [details] MozReview Request: Bug 1018299 - Throw security error if principal check fails in MediaRecorder::Start(). r?jib,mt https://reviewboard.mozilla.org/r/47467/#review44351 ::: dom/media/MediaRecorder.cpp:1061 (Diff revision 1) > + mDOMStream->GetTracks(tracks); > + } > + if (!tracks.IsEmpty()) { > + // If there are tracks already available that we're not allowed > + // to record, we should throw a security error. > + bool subsumes; Why not just initialize to false? Then you have: if (!(window = GetOwner()) || !(doc = window->GetExtantDoc()) || NS_FAILED(...Subsumes() || !subsumes) { aResult.Throw(...); } It's about as readable. (Yeah, you don't need to initialize at all here, but I think compilers aren't always smart enough to work that out.)
Attachment #8742869 -
Flags: review?(martin.thomson) → review+
Comment 51•8 years ago
|
||
https://reviewboard.mozilla.org/r/47467/#review44351 > Why not just initialize to false? > > Then you have: > > if (!(window = GetOwner()) || > !(doc = window->GetExtantDoc()) || > NS_FAILED(...Subsumes() || > !subsumes) { > aResult.Throw(...); > } > > It's about as readable. (Yeah, you don't need to initialize at all here, but I think compilers aren't always smart enough to work that out.) Wfm.
Comment 52•8 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/3e00ab630419 https://hg.mozilla.org/integration/mozilla-inbound/rev/fa4d407df253
Comment 53•8 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/3e00ab630419 https://hg.mozilla.org/mozilla-central/rev/fa4d407df253
Status: ASSIGNED → RESOLVED
Closed: 8 years ago
status-firefox48:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla48
You need to log in
before you can comment on or make changes to this bug.
Description
•