Closed Bug 1858509 Opened 1 year ago Closed 1 year ago

Use-after-free crash in [@ mozilla::MediaSourceTrackDemuxer::HasManager]

Categories

(Core :: Audio/Video: Playback, defect)

Unspecified
All
defect

Tracking

()

RESOLVED FIXED
122 Branch
Tracking Status
firefox-esr115 121+ fixed
firefox120 --- wontfix
firefox121 + fixed
firefox122 + fixed

People

(Reporter: karlt, Assigned: karlt)

References

Details

(4 keywords, Whiteboard: [adv-main121+r][adv-esr115.6+r])

Crash Data

Attachments

(6 files)

+++ This bug was initially created as a clone of Bug #1853201 +++

Crash report: https://crash-stats.mozilla.org/report/index/10831076-cca8-441e-a4db-b59e10230912

Reason: SIGSEGV / SEGV_MAPERR

Top 10 frames of crashing thread:

0  libxul.so  RefPtr<mozilla::TrackBuffersManager>::get const  mfbt/RefPtr.h:325
0  libxul.so  operator==<mozilla::TrackBuffersManager, mozilla::TrackBuffersManager>  mfbt/RefPtr.h:544
0  libxul.so  mozilla::MediaSourceTrackDemuxer::HasManager const  dom/media/mediasource/MediaSourceDemuxer.cpp:513
0  libxul.so  mozilla::MediaSourceDemuxer::DoDetachSourceBuffer  dom/media/mediasource/MediaSourceDemuxer.cpp:200
1  libxul.so  mozilla::detail::RunnableMethodArguments<RefPtr<mozilla::TrackBuffersManager>&&>::apply<mozilla::MediaSourceDemuxer, void  const  xpcom/threads/nsThreadUtils.h:1164
1  libxul.so  std::__ndk1::__invoke_constexpr<mozilla::detail::RunnableMethodArguments<RefPtr<mozilla::TrackBuffersManager>&&>::apply<mozilla::MediaSourceDemuxer, void   /builds/worker/fetches/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/type_traits:3880
1  libxul.so  std::__ndk1::__apply_tuple_impl<mozilla::detail::RunnableMethodArguments<RefPtr<mozilla::TrackBuffersManager>&&>::apply<mozilla::MediaSourceDemuxer, void   /builds/worker/fetches/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/tuple:1415
1  libxul.so  std::__ndk1::apply<mozilla::detail::RunnableMethodArguments<RefPtr<mozilla::TrackBuffersManager>&&>::apply<mozilla::MediaSourceDemuxer, void   /builds/worker/fetches/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/tuple:1424
1  libxul.so  mozilla::detail::RunnableMethodArguments<RefPtr<mozilla::TrackBuffersManager>&&>::apply<mozilla::MediaSourceDemuxer, void   xpcom/threads/nsThreadUtils.h:1162
1  libxul.so  mozilla::detail::RunnableMethodImpl<mozilla::MediaSourceDemuxer*, void   xpcom/threads/nsThreadUtils.h:1213

Mostly but not entirely on Android. Window crash: bp-796852dc-f800-444c-9d6e-ef29c0230908

We're in this loop:

  for (auto& demuxer : mDemuxers) {
    if (demuxer->HasManager(aSourceBuffer)) {
      demuxer->DetachManager();
    }
  }

Could one of the DetachManager calls cause mDemuxers to have something added or removed? I tried looking over the code but I couldn't figure out how that might happen. mDemuxers has strong references so it isn't clear why a demuxer in the list would have gone away, even though we're running this code off a runnable.

19 crashes with this signature in the last 6 months, and all but 1 are on poison values.

From bug 1853201 comment 7:

GetTrackDemuxer modifies mDemuxers without asserting OnTaskQueue().

MediaFormatReader::DemuxerProxy uses its own TaskQueue.
Can that call MediaSourceDemuxer::GetTrackDemuxer()?

Severity: -- → S2

We will follow back up on this after the parent has had some time to bake.

Parent fix was uplifted to 119.

No longer blocks: 1853201
Depends on: 1853201

Hmm, seem to have picked up a similar crash report in 119 -
https://crash-stats.mozilla.org/report/index/5f31400d-dd13-488a-b68f-9f3750231031

Could this be because aSourceBuffer is captured by reference? It seems it is SourceBuffer::mTrackBuffersManager which will go out of scope after the call to MediaSourceDemuxer::DetachSourceBuffer:
https://searchfox.org/mozilla-central/rev/02841791400cf7cf5760c0cfaf31f5d772624253/dom/media/mediasource/MediaSourceDemuxer.cpp#182
https://searchfox.org/mozilla-central/rev/02841791400cf7cf5760c0cfaf31f5d772624253/dom/media/mediasource/SourceBuffer.cpp#453

If so, the fix is just something like sourceBuffer = RefPtr{aSourceBuffer}.

Attached file reference-capture.cpp

(In reply to Andrew Osmond [:aosmond] (he/him) from comment #5)

Could this be because aSourceBuffer is captured by reference?
I also wasn't certain about by-copy capture of a reference so I wrote this to check. Output is

construct A
Direct
const copy A
From reference
const copy A
From const reference
const copy A
From rvalue reference
const copy A
From inline rvalue reference
move A
From move
move A
destruct A
destruct A
destruct A
destruct A
destruct A
destruct A
destruct A

so aSourceBuffer is a non-reference RefPtr in the lambda expression.

I suspect mDemuxers is being modified from the MediaFormatReader TaskQueue.

Assignee: nobody → karlt
No longer blocks: media-triage

Adding an OnTaskQueue() assertion to MediaSourceDemuxer::GetTrackDemuxer() confirms that it is modifying mDemuxers off the task queue, when running test_BufferedSeek.html, for example.

This issue has existed since https://hg.mozilla.org/mozilla-central/rev/7fd2d15b8fae36cb51122e44db546fdcbb1c1845#l1.13
Prior to that, there was no obvious reason for the existence of mDemuxers because it was otherwise unused.

When mDemuxers was added, there was a racy read OnTaskQueue(). That was removed when CI identified the race.

The mDemuxers array element entry is also removed when no longer required.

Attachment #9363619 - Attachment description: Bug 1858509 clarify that some TrackBuffersManager reference parameters are not muted as side-effects r?alwu → Bug 1858509 clarify that some TrackBuffersManager reference parameters are not mutated as side-effects r?alwu
Attachment #9363619 - Attachment description: Bug 1858509 clarify that some TrackBuffersManager reference parameters are not mutated as side-effects r?alwu → Bug 1858509 clarify that some TrackBuffersManager reference parameters are not mutable through side-effects r?alwu

Comment on attachment 9363617 [details]
Bug 1858509 add thread-safety annotations around MediaSourceDemuxer::mMonitor r?alwu

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: This would be difficult to exploit due to the need to have one thread iterate the array while another is adding to it, neither of which threads run content JS.

D193616 identifies the two sections of code that would need to race. The other patches do not highlight the security flaw.

  • Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?: No
  • Which older supported branches are affected by this flaw?: All.
  • If not all supported branches, which bug introduced the flaw?: None
  • Do you have backports for the affected branches?: Yes
  • If not, how different, hard to create, and risky will they be?: D193616 applies to ESR115.

D193617 and D193618 merely clarify and simplify, and so do not need to be uplifted.

  • How likely is this patch to cause regressions; how much testing does it need?: Unlikely because the changes in behavior are small and there are many automated tests exercising this code.
  • Is Android affected?: Yes
Attachment #9363617 - Flags: sec-approval?
Attachment #9363619 - Flags: sec-approval?
Attachment #9363620 - Flags: sec-approval?

Comment on attachment 9363617 [details]
Bug 1858509 add thread-safety annotations around MediaSourceDemuxer::mMonitor r?alwu

Approved to land and uplift

Attachment #9363617 - Flags: sec-approval? → sec-approval+
Attachment #9363619 - Flags: sec-approval? → sec-approval+
Attachment #9363620 - Flags: sec-approval? → sec-approval+
Pushed by ktomlinson@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/4f09bc1d010b add thread-safety annotations around MediaSourceDemuxer::mMonitor r=alwu
Pushed by ktomlinson@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/1ec171cb7fb1 clarify that some TrackBuffersManager reference parameters are not mutable through side-effects r=alwu
Backout by nfay@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/b8f6bb99beb4 Backed out changeset 4f09bc1d010b for causing process-crashes on MediaSourceDemuxer.cpp

4f09bc1d010b got backed out for causing process-crashes in MediaSourceDemuxer.cpp:

https://hg.mozilla.org/integration/autoland/rev/b8f6bb99beb4206d1b0fb7e2f5a053f02dddf1a3

Push with failures
Failure log

PROCESS-CRASH | MOZ_ASSERT(!mDemuxers.Contains(aSourceBuffer.get(), MatchTrackDemuxerManager())) [@ mozilla::MediaSourceDemuxer::DoDetachSourceBuffer] | /media-source/mediasource-detach.html

Flags: needinfo?(karlt)
Keywords: leave-open
Flags: needinfo?(karlt)
Pushed by ktomlinson@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/f7e938ac6494 add thread-safety annotations around MediaSourceDemuxer::mMonitor r=alwu
Pushed by ktomlinson@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/9259a4ff84a4 replace Monitor with Mutex where a condition variable is not used r=alwu

mDemuxers array elements are also removed when no longer required.

Original Revision: https://phabricator.services.mozilla.com/D193616

Attachment #9367406 - Flags: approval-mozilla-beta?

Uplift Approval Request

  • Is Android affected?: yes
  • String changes made/needed: None
  • Fix verified in Nightly: no
  • Steps to reproduce for manual QE testing: n/a
  • Risk associated with taking this patch: Low, but some risk of deadlock if there's something i've missed.
  • Needs manual QE test: no
  • User impact if declined: sec-high
  • Explanation of risk level: Low because there are many automated tests, which caught an incorrect assumption in a previous version of this patch.
  • Code covered by automated testing: yes

mDemuxers array elements are also removed when no longer required.

Original Revision: https://phabricator.services.mozilla.com/D193616

Attachment #9367408 - Flags: approval-mozilla-esr115?

Uplift Approval Request

  • Is Android affected?: yes
  • String changes made/needed: none
  • Fix verified in Nightly: no
  • Steps to reproduce for manual QE testing: n/a
  • Risk associated with taking this patch: Low, but some risk of deadlock if there's something i've missed.
  • Needs manual QE test: no
  • User impact if declined: sec-high
  • Explanation of risk level: Low because there are many automated tests, which caught an incorrect assumption in a previous version of this patch.
  • Code covered by automated testing: yes

:karlt this bug has a leave-open keyword, should that be removed and the bug resolved?

Flags: needinfo?(karlt)

Yes, thanks.

Status: NEW → RESOLVED
Closed: 1 year ago
Flags: needinfo?(karlt)
Keywords: leave-open
Resolution: --- → FIXED
Target Milestone: --- → 122 Branch

Comment on attachment 9367406 [details]
Bug 1858509 add thread-safety annotations around MediaSourceDemuxer::mMonitor r?alwu

Approved for 121.0b9.

Attachment #9367406 - Flags: approval-mozilla-beta? → approval-mozilla-beta+

Comment on attachment 9367408 [details]
Bug 1858509 add thread-safety annotations around MediaSourceDemuxer::mMonitor r?alwu

Approved for 115.6esr.

Attachment #9367408 - Flags: approval-mozilla-esr115? → approval-mozilla-esr115+
Group: media-core-security → core-security-release
QA Whiteboard: [post-critsmash-triage]
Flags: qe-verify-
Whiteboard: [adv-main121+r]
Whiteboard: [adv-main121+r] → [adv-main121+r][adv-esr115.6+r]

Bulk-unhiding security bugs fixed in Firefox 119-121 (Fall 2023). Use "moo-doctrine-subsidy" to filter

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: