Closed Bug 1811327 (CVE-2023-28162) Opened 1 year ago Closed 1 year ago

cfi-derived-cast: Invalid downcast in ExecutionRunnable::RunOnWorkletThread

Categories

(Core :: Audio/Video, defect)

defect

Tracking

()

RESOLVED FIXED
111 Branch
Tracking Status
firefox-esr102 111+ fixed
firefox109 --- wontfix
firefox110 --- wontfix
firefox111 + fixed

People

(Reporter: lukas.bernhard, Assigned: mccr8)

References

(Blocks 1 open bug, Regression)

Details

(Keywords: csectype-undefined, regression, sec-moderate, Whiteboard: [adv-main111+][adv-esr102.9+])

Attachments

(2 files)

Steps to reproduce:

When compiling Firefox with cfi-derived-cast, crashtest dom/media/test/crashtests/audioworkletnode-after-unload-1.html fails due to the downcasting here:
https://searchfox.org/mozilla-central/rev/daf613efc5c358f3a94961d73b90472c00703838/dom/worklet/Worklet.cpp#410
The dynamic type of the casted object is nsThread, a parent class of WorkletThread.

This might not be s-s, just flagging as a precaution.

Blocks: cfi
Group: firefox-core-security → core-security
Component: Untriaged → DOM: Core & HTML
Product: Firefox → Core
Group: core-security → dom-core-security

The relevant code has been implemented for web audio, so moving this bug there.

I'm not familiar with the setup, see https://searchfox.org/mozilla-central/rev/7426a35738cd542b9488c7b67f4f6d21edfeda0a/dom/worklet/Worklet.cpp#370-375

Component: DOM: Core & HTML → Audio/Video
Group: dom-core-security → media-core-security

Andrew looked and it appears to only be touched by static methods rather than virtual and is probably OK until a compiler decides to go optimize some undefined behavior. Should fix.

Specifically, we first call EnsureCycleCollectedJSContext on it, which is a non-static non-virtual method that does not touch any fields. It passes this into the closure argument of JS::InitDispatchToEventLoop, which eventually ends up getting passed back in to the static method DispatchToEventLoop, which casts it back to WorkletThread and calls DispatchRunnable on it, which is a non-static, non-virtual method, that also does not touch any fields.

Assignee: nobody → continuation

I started throwing together a patch to fix this, and it looks like I was wrong. In WorkletThread::DispatchRunnable(), nsThread::Dispatch() is actually a virtual method on the parent class nsThread. I guess it works out anyways because NS_GetCurrentThread() returns an nsThread and I suppose there's no weird multiple inheritance so the vtables are compatible at least for that one method?

I'm guessing it must be okay because otherwise it would just crash every time.

Attachment #9314151 - Attachment description: Bug 1811327 - Be more precise in the types passed around in EnsureCycleCollectedJSContext. → Bug 1811327 - Be more precise in the types passed around in EnsureCycleCollectedJSContext. WIP

I think my patch here reflects why we don't go awry on this test case, but maybe I'm missing the forest for the trees. If we're running ExecutionRunnable::RunOnWorkletThread() on a thread that apparently isn't a worklet thread, that doesn't sound good. Maybe some error condition should have been detected earlier and bailed out?

It looks like the thread name for the thread we're calling ExecutionRunnable::RunOnWorkletThread() on is "GraphRunner".

Across all of the plain mochitests in dom/worklet/tests/, dom/worklet/tests/test_paintWorklet.html seems to be the only one where the name of the thread is "DOM Worklet" and not "GraphRunner", so I suppose that is normal.

Attachment #9314151 - Attachment description: Bug 1811327 - Be more precise in the types passed around in EnsureCycleCollectedJSContext. WIP → Bug 1811327 - Be more precise in the types passed around to WorkletThread methods.

Set release status flags based on info from the regressing bug 1612570

Group: media-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 111 Branch

Comment on attachment 9314151 [details]
Bug 1811327 - Be more precise in the types passed around to WorkletThread methods.

ESR Uplift Approval Request

  • If this is not a sec:{high,crit} bug, please state case for ESR consideration: This fixes up a minor bit of undefined behavior.
  • User impact if declined: Undefined behavior could in theory lead to security problems if the compiler changes.
  • Fix Landed on Version: 111
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): This really just shuffles around some static casts to make them more accurate.
Attachment #9314151 - Flags: approval-mozilla-esr102?

Comment on attachment 9314151 [details]
Bug 1811327 - Be more precise in the types passed around to WorkletThread methods.

Approved for 102.9esr.

Attachment #9314151 - Flags: approval-mozilla-esr102? → approval-mozilla-esr102+
QA Whiteboard: [post-critsmash-triage]
Whiteboard: [adv-main111+]
Whiteboard: [adv-main111+] → [adv-main111+][adv-esr102.9+]
Alias: CVE-2023-28162
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: