Closed Bug 1997118 Opened 1 year ago Closed 1 year ago

Aborting GC during marking can leave gray marking state invalid

Categories

(Core :: JavaScript: GC, defect, P3)

defect

Tracking

()

RESOLVED FIXED
146 Branch
Tracking Status
firefox-esr115 --- wontfix
firefox-esr140 --- wontfix
firefox144 --- wontfix
firefox145 --- wontfix
firefox146 + fixed

People

(Reporter: jonco, Assigned: jonco)

References

(Blocks 1 open bug)

Details

(Keywords: csectype-uaf, sec-moderate, Whiteboard: [adv-main146+r])

Attachments

(1 external file, 1 obsolete file)

While working on bug 1994871 I realised that there's a problem with gray unmarking where aborting an incremental GC can leave things in a bad state.

Gray unmarking stops when it comes to a zone that is currently being incrementally marked and hands the work over to the GC marking (which is doing something very similar but can do it incrementally and in hopefully in parallel too). When GC marking traverses something gray in a zone that isn't being marked it will perform gray unmarking on it. So gray unmarking can flow through zones that are being collected and out again.

This breaks down if we abort incremental GC while it's marking. This can leave us with black to gray edges, violating our promise to the cycle collector. This can possibly lead to use after free if the CC can be persuaded to free the gray thing that should have been marked black.

Attached file (secure) —

We depend on GC marking to propagate gray umarking through zones that are being
marked incrementally. Aborting this raises the possibility of creating black to
gray edges as previously happened with this testcase.

Marking the gray bits as invalid will cause the CC to perform another GC to
redo the marking. Aborting GC is pretty rare in practice so I don't expect this
to have a performance impact.

I don't know how one would craft an exploit based on this and aborting GC is pretty rare in practice so I'm going to mark this sec-moderate for now.

Keywords: sec-moderate

Yes, that seems reasonable. I'll mark this as a "use-after-free" but really it is more of a "use-after-unlink", which is usually less bad but maybe it could be bad in some weird circumstance depending on the unlink method.

Keywords: csectype-uaf
Blocks: sm-security
Severity: -- → S3
Regressions: 1997268
Pushed by pstanciu@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/12bf2b1c5311 https://hg.mozilla.org/integration/autoland/rev/d53295d3cd83 Revert "Bug 1997118 - Mark gray bits as invalid if we abort GC during marking r=sfink" for causing assertion failure in Bug 1997268

PROCESS-CRASH | 649f64b7-b91c-342e-36d6-5f5fce254c15 | MOZ_CRASH(JS::UnmarkGrayGCThingRecursively(thing)) [@ js::gc::ExposeGCThingToActiveJS] | js/src/tests/non262/extensions/regress-363988.js

Flags: needinfo?(jcoppeard)
Flags: needinfo?(jcoppeard)
Group: javascript-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 146 Branch

The patch landed in nightly and beta is affected.
:jonco, is this bug important enough to require an uplift?

For more information, please visit BugBot documentation.

Flags: needinfo?(jcoppeard)

Doesn't seem like something we need to uplift at the last second for 145 given comment 2, but probably still worth an ESR140 uplift next cycle.

QA Whiteboard: [sec] [qa-triage-done-c147/b146]

Comment on attachment 9523270 [details]
(secure)

ESR Uplift Approval Request

  • If this is not a sec:{high,crit} bug, please state case for ESR consideration: This is a sec-moderate security vulnerability
  • User impact if declined: Potential crash or security vulnerability
  • Fix Landed on Version: 146
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): The change is very simple (mark gray marking state as invalid in one place). The change is covered by tests (the bulk of the patch). This has been on central for a while.
Flags: needinfo?(jcoppeard)

Comment on attachment 9523270 [details]
(secure)

The request flag was missing on the attachment

Attachment #9523270 - Flags: approval-mozilla-esr140?
Flags: needinfo?(jcoppeard)
Attached file (secure) (obsolete) —

We depend on GC marking to propagate gray umarking through zones that are being
marked incrementally. Aborting this raises the possibility of creating black to
gray edges as previously happened with this testcase.

Marking the gray bits as invalid will cause the CC to perform another GC to
redo the marking. Aborting GC is pretty rare in practice so I don't expect this
to have a performance impact.

Attachment #9529787 - Flags: approval-mozilla-esr140?
Flags: needinfo?(jcoppeard)
Attachment #9529787 - Flags: approval-mozilla-esr140? → approval-mozilla-esr140+
Attachment #9523270 - Flags: approval-mozilla-esr140?
Regressions: 2003035

(In reply to Pulsebot from comment #15)
The uplift has caused some assertion failures on esr140. There have been several changes in this area recently and I'm not sure what the dependency is here. Since this is only sec-moderate on balance I'd rather leave this to ride the trains.

Backed out from ESR140 for causing Bug 2003035, see Comment 16.

Whiteboard: [adv-main146+]
Whiteboard: [adv-main146+] → [adv-main146+r]
Attachment #9529787 - Attachment is obsolete: true
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: