Summary of the free stack:
```
[mozilla::Graphs() gets resized]
[unlinking a MediaStreamTrack triggers MediaTrackGraphImpl::RemoveTrack]
[finishing an existing cycle collection in nsCycleCollector::FinishAnyCurrentCollection]
[triggering a garbage collection in GCRuntime::collect]
[allocating a new JS object in XPCWrappedNative::Init]
[calling into an XPCOM object implemented in JS using XPConnect]
#39 0x7f0d12c856b1 in mozilla::MediaTrackGraphImpl::AddShutdownBlocker() /builds/worker/checkouts/gecko/dom/media/MediaTrackGraph.cpp:1842:26
#40 0x7f0d12c95cec in mozilla::MediaTrackGraphImpl::Init(mozilla::MediaTrackGraph::GraphDriverType, mozilla::MediaTrackGraph::GraphRunType, unsigned int) /builds/worker/checkouts/gecko/dom/media/MediaTrackGraph.cpp:3474:35
#41 0x7f0d12c8c52f in mozilla::MediaTrackGraphImpl::GetInstance(mozilla::MediaTrackGraph::GraphDriverType, unsigned long, int, void const*, nsISerialEventTarget*) /builds/worker/checkouts/gecko/dom/media/MediaTrackGraph.cpp:3590:10
#42 0x7f0d1297832c in mozilla::dom::CanvasCaptureMediaStream::Init(mozilla::dom::Optional<double> const&, nsIPrincipal*) /builds/worker/checkouts/gecko/dom/media/CanvasCaptureMediaStream.cpp:173:28
```
Then looking at the use stack:
```
#2 0x7f0d12c8ca07 in add<mozilla::MediaTrackGraphImpl *&> /builds/worker/workspace/obj-build/dist/include/mozilla/HashTable.h:629:18
#3 0x7f0d12c8ca07 in mozilla::MediaTrackGraphImpl::GetInstance(mozilla::MediaTrackGraph::GraphDriverType, unsigned long, int, void const*, nsISerialEventTarget*) /builds/worker/checkouts/gecko/dom/media/MediaTrackGraph.cpp:3591:3
#4 0x7f0d1297832c in mozilla::dom::CanvasCaptureMediaStream::Init(mozilla::dom::Optional<double> const&, nsIPrincipal*) /builds/worker/checkouts/gecko/dom/media/CanvasCaptureMediaStream.cpp:173:28
#5 0x7f0d1276e866 in mozilla::dom::HTMLCanvasElement::CaptureStream(mozilla::dom::Optional<double> const&, nsIPrincipal&, mozilla::ErrorResult&) /builds/worker/checkouts/gecko/dom/html/HTMLCanvasElement.cpp:892:25
```
The use is happening [here](https://searchfox.org/firefox-main/rev/ff87356d65bc2e9e7349ac3a24276696434f27fc/dom/media/MediaTrackGraph.cpp#3588-3591). The issue is that we're using `addPtr` which came from `Graphs()::lookupForAdd`, but in the meanwhile we've mutated `Graphs`. It looks like you could use `relookupOrAdd` here to save rehashing but honestly it doesn't feel like this code can be so performance sensitive that this doesn't really matter.
It also doesn't make me feel good that we have a raw pointer to a `MediaTrackGraphImpl` on the stack [here](https://searchfox.org/firefox-main/rev/ff87356d65bc2e9e7349ac3a24276696434f27fc/dom/media/MediaTrackGraph.cpp#3588-3591) while we're doing a GC/CC, but I think in this specific situation it is safe because we don't addref or release it until after the GC/CC is done, so the CC is never aware of it.
There is a second callsite for `MediaTrackGraphImpl::Init` in `MediaTrackGraphImpl::CreateNonRealtimeInstance`. This has the raw pointer on the stack issue that I do not like, but it does not keep a `Lookup` object alive so it shouldn't have the same UAF problem as the test case.
Bug 1988931 Comment 3 Edit History
Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.
Summary of the free stack:
```
[mozilla::Graphs() gets resized]
[unlinking a MediaStreamTrack triggers MediaTrackGraphImpl::RemoveTrack]
[finishing an existing cycle collection in nsCycleCollector::FinishAnyCurrentCollection]
[triggering a garbage collection in GCRuntime::collect]
[allocating a new JS object in XPCWrappedNative::Init]
[calling into an XPCOM object implemented in JS using XPConnect]
#39 0x7f0d12c856b1 in mozilla::MediaTrackGraphImpl::AddShutdownBlocker() /builds/worker/checkouts/gecko/dom/media/MediaTrackGraph.cpp:1842:26
#40 0x7f0d12c95cec in mozilla::MediaTrackGraphImpl::Init(mozilla::MediaTrackGraph::GraphDriverType, mozilla::MediaTrackGraph::GraphRunType, unsigned int) /builds/worker/checkouts/gecko/dom/media/MediaTrackGraph.cpp:3474:35
#41 0x7f0d12c8c52f in mozilla::MediaTrackGraphImpl::GetInstance(mozilla::MediaTrackGraph::GraphDriverType, unsigned long, int, void const*, nsISerialEventTarget*) /builds/worker/checkouts/gecko/dom/media/MediaTrackGraph.cpp:3590:10
#42 0x7f0d1297832c in mozilla::dom::CanvasCaptureMediaStream::Init(mozilla::dom::Optional<double> const&, nsIPrincipal*) /builds/worker/checkouts/gecko/dom/media/CanvasCaptureMediaStream.cpp:173:28
```
Then looking at the use stack:
```
#2 0x7f0d12c8ca07 in add<mozilla::MediaTrackGraphImpl *&> /builds/worker/workspace/obj-build/dist/include/mozilla/HashTable.h:629:18
#3 0x7f0d12c8ca07 in mozilla::MediaTrackGraphImpl::GetInstance(mozilla::MediaTrackGraph::GraphDriverType, unsigned long, int, void const*, nsISerialEventTarget*) /builds/worker/checkouts/gecko/dom/media/MediaTrackGraph.cpp:3591:3
#4 0x7f0d1297832c in mozilla::dom::CanvasCaptureMediaStream::Init(mozilla::dom::Optional<double> const&, nsIPrincipal*) /builds/worker/checkouts/gecko/dom/media/CanvasCaptureMediaStream.cpp:173:28
#5 0x7f0d1276e866 in mozilla::dom::HTMLCanvasElement::CaptureStream(mozilla::dom::Optional<double> const&, nsIPrincipal&, mozilla::ErrorResult&) /builds/worker/checkouts/gecko/dom/html/HTMLCanvasElement.cpp:892:25
```
The use is happening [here](https://searchfox.org/firefox-main/rev/ff87356d65bc2e9e7349ac3a24276696434f27fc/dom/media/MediaTrackGraph.cpp#3588-3591). The issue is that we're using `addPtr` which came from `Graphs()::lookupForAdd`, but in the meanwhile we've mutated `Graphs`. It looks like you could use `relookupOrAdd` here to save rehashing but honestly it doesn't feel like this code can be so performance sensitive that this would matter, given that we're calling into JS.
It also doesn't make me feel good that we have a raw pointer to a `MediaTrackGraphImpl` on the stack [here](https://searchfox.org/firefox-main/rev/ff87356d65bc2e9e7349ac3a24276696434f27fc/dom/media/MediaTrackGraph.cpp#3588-3591) while we're doing a GC/CC, but I think in this specific situation it is safe because we don't addref or release it until after the GC/CC is done, so the CC is never aware of it.
There is a second callsite for `MediaTrackGraphImpl::Init` in `MediaTrackGraphImpl::CreateNonRealtimeInstance`. This has the raw pointer on the stack issue that I do not like, but it does not keep a `Lookup` object alive so it shouldn't have the same UAF problem as the test case.