Closed Bug 1756793 Opened 3 years ago Closed 3 years ago

ZDI-CAN-16716: Mozilla Firefox textPath Element Use-After-Free Remote Code Execution Vulnerability

Categories

(Core :: SVG, defect)

defect

Tracking

()

RESOLVED DUPLICATE of bug 1736243

People

(Reporter: freddy, Assigned: emilio)

Details

(Keywords: csectype-uaf, sec-high)

Attachments

(2 files, 1 obsolete file)

Attached file poc-zdi-can-16716.html

Below is the original email from the ZDI, with some details hidden away for brevity.

VULNERABILITY DETAILS

Analysis

UAF during handling of textPath element (it should crash upon loading the poc. If not, reload the page):

ASAN output:

==82318==ERROR: AddressSanitizer: heap-use-after-free on address 0x60c000085488 at pc 0x7fc2876b981a bp 0x7fff206a03d0 sp 0x7fff206a03c8
WRITE of size 1 at 0x60c000085488 thread T0 (file:// Content)
console.warn: TopSitesFeed: Failed to fetch data from Contile server: NetworkError when attempting to fetch resource.
    #0 0x7fc2876b9819 in OnNonDOMMutationRenderingChange /builds/worker/checkouts/gecko/layout/svg/SVGObserverUtils.cpp:246:18
    #1 0x7fc2876b9819 in mozilla::SVGRenderingObserverSet::InvalidateAll() /builds/worker/checkouts/gecko/layout/svg/SVGObserverUtils.cpp:1066:15
    #2 0x7fc2876b5ef5 in mozilla::SVGTextFrame::ReflowSVGNonDisplayText() /builds/worker/checkouts/gecko/layout/svg/SVGTextFrame.cpp:2848:3
    #3 0x7fc287680023 in mozilla::SVGContainerFrame::ReflowSVGNonDisplayText(nsIFrame*) /builds/worker/checkouts/gecko/layout/svg/SVGContainerFrame.cpp:114:40
    #4 0x7fc2876814d3 in mozilla::SVGDisplayContainerFrame::ReflowSVG() /builds/worker/checkouts/gecko/layout/svg/SVGContainerFrame.cpp:337:11
    #5 0x7fc2876c13f8 in mozilla::SVGOuterSVGFrame::Reflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsReflowStatus&) /builds/worker/checkouts/gecko/layout/svg/SVGOuterSVGFrame.cpp:451:14
    #6 0x7fc2874fb8df in nsLineLayout::ReflowFrame(nsIFrame*, nsReflowStatus&, mozilla::ReflowOutput*, bool&) /builds/worker/checkouts/gecko/layout/generic/nsLineLayout.cpp:875:13
    #7 0x7fc2872ec961 in nsBlockFrame::ReflowInlineFrame(mozilla::BlockReflowInput&, nsLineLayout&, nsLineList_iterator, nsIFrame*, LineReflowStatus*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:4553:15
    #8 0x7fc2872eb96d in nsBlockFrame::DoReflowInlineFrames(mozilla::BlockReflowInput&, nsLineLayout&, nsLineList_iterator, nsFlowAreaRect&, int&, nsFloatManager::SavedState*, bool*, LineReflowStatus*, bool) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:4355:5
    #9 0x7fc2872e4bee in nsBlockFrame::ReflowInlineFrames(mozilla::BlockReflowInput&, nsLineList_iterator, bool*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:4240:9
    #10 0x7fc2872de3e9 in nsBlockFrame::ReflowLine(mozilla::BlockReflowInput&, nsLineList_iterator, bool*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:3227:5
    #11 0x7fc2872d5d9e in nsBlockFrame::ReflowDirtyLines(mozilla::BlockReflowInput&) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:2761:7
    #12 0x7fc2872cf040 in nsBlockFrame::Reflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsReflowStatus&) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:1394:3
    #13 0x7fc2872e94d2 in nsBlockReflowContext::ReflowBlock(mozilla::LogicalRect const&, bool, nsCollapsingMargin&, int, bool, nsLineBox*, mozilla::ReflowInput&, nsReflowStatus&, mozilla::BlockReflowInput&) /builds/worker/checkouts/gecko/layout/generic/nsBlockReflowContext.cpp:288:11
    #14 0x7fc2872e15e2 in nsBlockFrame::ReflowBlockFrame(mozilla::BlockReflowInput&, nsLineList_iterator, bool*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:3874:11
    #15 0x7fc2872de536 in nsBlockFrame::ReflowLine(mozilla::BlockReflowInput&, nsLineList_iterator, bool*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:3224:5
    #16 0x7fc2872d5d9e in nsBlockFrame::ReflowDirtyLines(mozilla::BlockReflowInput&) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:2761:7
    #17 0x7fc2872cf040 in nsBlockFrame::Reflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsReflowStatus&) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:1394:3
    #18 0x7fc2872e94d2 in nsBlockReflowContext::ReflowBlock(mozilla::LogicalRect const&, bool, nsCollapsingMargin&, int, bool, nsLineBox*, mozilla::ReflowInput&, nsReflowStatus&, mozilla::BlockReflowInput&) /builds/worker/checkouts/gecko/layout/generic/nsBlockReflowContext.cpp:288:11
    #19 0x7fc2872e15e2 in nsBlockFrame::ReflowBlockFrame(mozilla::BlockReflowInput&, nsLineList_iterator, bool*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:3874:11
    #20 0x7fc2872de536 in nsBlockFrame::ReflowLine(mozilla::BlockReflowInput&, nsLineList_iterator, bool*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:3224:5
    #21 0x7fc2872d5d9e in nsBlockFrame::ReflowDirtyLines(mozilla::BlockReflowInput&) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:2761:7
    #22 0x7fc2872cf040 in nsBlockFrame::Reflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsReflowStatus&) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:1394:3
    #23 0x7fc287307c3d in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, mozilla::WritingMode const&, mozilla::LogicalPoint const&, nsSize const&, nsIFrame::ReflowChildFlags, nsReflowStatus&, nsOverflowContinuationTracker*) /builds/worker/checkouts/gecko/layout/generic/nsContainerFrame.cpp:1005:14
    #24 0x7fc287306417 in nsCanvasFrame::Reflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsReflowStatus&) /builds/worker/checkouts/gecko/layout/generic/nsCanvasFrame.cpp:787:7
    #25 0x7fc287307c3d in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, mozilla::WritingMode const&, mozilla::LogicalPoint const&, nsSize const&, nsIFrame::ReflowChildFlags, nsReflowStatus&, nsOverflowContinuationTracker*) /builds/worker/checkouts/gecko/layout/generic/nsContainerFrame.cpp:1005:14
    #26 0x7fc287392e86 in nsHTMLScrollFrame::ReflowScrolledFrame(mozilla::ScrollReflowInput&, bool, bool, mozilla::ReflowOutput*) /builds/worker/checkouts/gecko/layout/generic/nsGfxScrollFrame.cpp:838:3
    #27 0x7fc287394489 in nsHTMLScrollFrame::ReflowContents(mozilla::ScrollReflowInput&, mozilla::ReflowOutput const&) /builds/worker/checkouts/gecko/layout/generic/nsGfxScrollFrame.cpp:973:3
    #28 0x7fc28739aad4 in nsHTMLScrollFrame::Reflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsReflowStatus&) /builds/worker/checkouts/gecko/layout/generic/nsGfxScrollFrame.cpp:1395:3
    #29 0x7fc2872bebfb in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, int, int, nsIFrame::ReflowChildFlags, nsReflowStatus&, nsOverflowContinuationTracker*) /builds/worker/checkouts/gecko/layout/generic/nsContainerFrame.cpp:1045:14
    #30 0x7fc2872be229 in mozilla::ViewportFrame::Reflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsReflowStatus&) /builds/worker/checkouts/gecko/layout/generic/ViewportFrame.cpp:374:7
    #31 0x7fc287102a29 in mozilla::PresShell::DoReflow(nsIFrame*, bool, mozilla::OverflowChangedTracker*) /builds/worker/checkouts/gecko/layout/base/PresShell.cpp:9542:11
(...)
SUMMARY: AddressSanitizer: heap-use-after-free /builds/worker/checkouts/gecko/layout/svg/SVGObserverUtils.cpp:246:18 in OnNonDOMMutationRenderingChange

CREDIT

This vulnerability was discovered by:
Hossein Lotfi of Trend Micro Zero Day Initiative

Attached file full-email.txt
Flags: needinfo?(emilio)
Assignee: nobody → emilio
Flags: needinfo?(emilio)

InvalidateAll() would call into our observers and potentially reflow
here:

https://searchfox.org/mozilla-central/rev/9b0bdcc37419e6765223358a31a4a54d62e1cd97/layout/svg/SVGObserverUtils.cpp#499-505

Which could delete our continuations while we have a reference to the
observer on the stack.

Blocks: 1415551
Group: core-security → layout-core-security

Comment on attachment 9265163 [details]
Bug 1756793 - Make SVGObserverUtils::GetAndObserveTextPathsPath not observe on continuations. r=jwatt,jfkthame

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: Not super-easily, but easily enough for someone with deep layout knowledge.
  • 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?: Should apply cleanly.
  • How likely is this patch to cause regressions; how much testing does it need?: not very likely.
Attachment #9265163 - Flags: sec-approval?

For reference, extended commit message which will be deleted is in comment 2.

This seems to be the same root issue as bug 1736243 - per discussions with emilio/dveditz, let's move the patch over there and mark this as a duplicate.

No longer blocks: 1415551, CVE-2022-26381
Status: NEW → RESOLVED
Closed: 3 years ago
Resolution: --- → DUPLICATE

Comment on attachment 9265163 [details]
Bug 1756793 - Make SVGObserverUtils::GetAndObserveTextPathsPath not observe on continuations. r=jwatt,jfkthame

Revision D139485 was moved to bug 1736243. Setting attachment 9265163 [details] to obsolete.

Attachment #9265163 - Attachment is obsolete: true
Attachment #9265163 - Flags: sec-approval?
Group: layout-core-security → core-security-release
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: