Closed Bug 1954018 Opened 1 year ago Closed 7 months ago

expat CVE-2024-8176 payloads (nested entities) can crash firefox tab

Categories

(Core :: XML, defect)

Firefox 136
defect

Tracking

()

RESOLVED FIXED
149 Branch
Tracking Status
firefox-esr115 --- wontfix
firefox-esr140 --- fixed
firefox147 --- wontfix
firefox148 --- wontfix
firefox149 --- fixed

People

(Reporter: hanno, Assigned: mccr8)

References

Details

(Keywords: crash, csectype-dos, reporter-external)

Attachments

(7 files)

Attached file payload1.xml

The expat library has just published a security update which fixes several crashes caused due to deep nesting of entities (recursion / stack overflow):
https://blog.hartwork.org/posts/expat-2-7-0-released/

There are scripts to generate example payloads (payload{1,2,3}.py.txt) attached to the relevant expat github issue:
https://github.com/libexpat/libexpat/issues/893

These example payloads can crash a firefox tab.

Attached file payload2.xml
Attached file payload3.xml

Error output from an ASAN build.

The stack traces imply that this is wrapped into wasm, probably due to this: https://blog.mozilla.org/attack-and-defense/2021/12/06/webassembly-and-back-again-fine-grained-sandboxing-in-firefox-95/

Group: mozilla-employee-confidential
Group: mozilla-employee-confidential → dom-core-security
Component: General → XML
Product: Firefox → Core
Attachment #9471987 - Attachment mime type: application/octet-stream → application/xml
Attachment #9471988 - Attachment mime type: application/octet-stream → application/xml
Attachment #9471989 - Attachment mime type: application/octet-stream → application/xml

At quick glance it seems it could just as well stack overflow in the wasm/rlbox sandbox, but somehow heap overflows before that happens? Shravan, what do you think?

Flags: needinfo?(shravanrn)

For convenience, here is the top of the 3 ASan reports in the zip file:

==31006==ERROR: AddressSanitizer: SEGV on unknown address 0x7f2f00000018 (pc 0x7f3079e981aa bp 0x7fffc9188570 sp 0x7fffc9188540 T0)
==31006==The signal is caused by a WRITE memory access.
    #0 0x7f3079e981aa in i64_store /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:215:1
    #1 0x7f3079e981aa in w2c_rlbox_hash /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:110026:3
    #2 0x7f3079e6dc21 in w2c_rlbox_lookup /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:97026:12
    #3 0x7f3079e784bd in w2c_rlbox_doContent /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:105977:14
    #4 0x7f3079e96c79 in w2c_rlbox_processInternalEntity /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:109919:12

==31255==ERROR: AddressSanitizer: SEGV on unknown address 0x7ff800000028 (pc 0x7ff928d191aa bp 0x7fff3168a880 sp 0x7fff3168a850 T0)
==31255==The signal is caused by a WRITE memory access.
    #0 0x7ff928d191aa in i64_store /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:215:1
    #1 0x7ff928d191aa in w2c_rlbox_hash /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:110026:3
    #2 0x7ff928ceec21 in w2c_rlbox_lookup /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:97026:12
    #3 0x7ff928d2fa29 in w2c_rlbox_appendAttributeValue /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:110525:14

==31299==ERROR: AddressSanitizer: SEGV on unknown address 0x7f0200000028 (pc 0x7f03988191aa bp 0x7fff0458b130 sp 0x7fff0458b100 T0)
==31299==The signal is caused by a WRITE memory access.
    #0 0x7f03988191aa in i64_store /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:215:1
    #1 0x7f03988191aa in w2c_rlbox_hash /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:110026:3
    #2 0x7f03987eec21 in w2c_rlbox_lookup /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:97026:12
    #3 0x7f039880e878 in w2c_rlbox_storeEntityValue /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:108728:14

Looking now.

As noted expat is sandboxed with RLBox+Wasm. Based on the prior message showing the ASAN stack trace, all three of the top ASAN reports here are a heap crash which Wasm will protect. So there is NO exploit/security-concern here --- the only reason to update is to avoid the crash.

The reason we see this as heap OOB's that are crashing is the following.

  • All heap memory accesses in RLBox+Wasm are bounds checked. OOB accesses are guaranteed to either abort() or SIGSEGV.
  • All buffers on the stack are moved to the heap as well and also bounds checked. (Wasm safety requires implementing the same semantics as -fsanitize=safe-stack)

My assessment: the only issues these bugs can cause are non-exploitable crashes:

  • Expat code OOB from a heap access, (or a stack buffer which is moved on to the heap by Wasm) can crash the browser.
  • Expat can run code with an infinite function recursion causing too many stack frames running out of stack space. But again, this is not likely to be a security issue --- just a crash. In particular given that there are no buffers on the stack, it is very hard (read: likely impossible) to convert stack exhaustion to a stack-heap clash (you have to work very hard to find a gadget that skips all of the unmapped space in between the memories without performing a single access to the stack --- this is typically only possible if you have buffers on the stack).

@glandium:

  • Let me know what you think about above
  • One follow up question for you also . Wasm also has an explicit recursion limit for functions, which I have intentionally disabled for performance reasons. My reasoning: since you can't introduce buffers onto the stack, it is very difficult to use things like recursion to do anything except stack exhaustion. If we want to add an on extra layer of safety going forward, I'm happy to flip the switch to limit recursive calls also. (Just need to change this line https://searchfox.org/mozilla-central/source/security/rlbox/rlbox.mozbuild#39)
Flags: needinfo?(shravanrn)
Flags: needinfo?(mh+mozilla)

Stack access in rlbox indeed actually happens on the heap, with the same protections as other heap access. From that perspective, whatever might be possible from the original stack overflow is practically not exploitable in rlbox.

That being said, I think the only thing that really happens from the original stack overflow is a DoS. I don't think it's possible to craft something that would go over the guard page and possibly start hitting the heap (and even in practice, the likelihood that there's actual mapped heap after the stack guard page would be rather low).

So from that perspective, rlbox is not doing much here, as we get the same result: a DoS.

If the new expat release removes the lengthy recursion (I think it does), then it would be good to apply.

I also agree that enabling the recursion limit wouldn't buy much.

Flags: needinfo?(mh+mozilla)
Group: dom-core-security
Keywords: crash, csectype-dos
See Also: → CVE-2026-4726
Severity: -- → S3
See Also: → 1988534
Depends on: 1988534
See Also: 1988534

It is unfortunate that this issue has stayed unfixed for so long. Sure, this is "only" a crash, but it could still be used for some quite annoying attacks.

I would like to add some information that emphasizes the severity. This can be triggered through an SVG image, which gives multiple possibilities:

  • It is not just possible to crash a tab, but also the whole browser process by using a favicon (which gets rendered outside the page sandbox). I will attach a proof of concept.

  • One could make a Github issue unreadable for firefox users by adding a comment including a markdown image tag referencing the PoC as an SVG.

  • It is possible to create a page with an OpenGraph preview using the PoC as the preview image. Some OpenGraph implementations directly use the unmodified preview image. This makes it, e.g., possible to crash the browser for all participants in a Rocketchat or Mattermost chat by posting a link with the payload as an SVG preview image.

Attached file crashffsvgxml.html

One more scenario: it's also possible to cause a crash crash in thunderbird (and it appears there's no sandboxing of HTML rendering in thunderbird, it directly crashes the whole application).

Bug 1988534 (along with bug 2010288) fixes the test cases in this bug.

Status: NEW → RESOLVED
Closed: 7 months ago
Depends on: 2010288
Resolution: --- → FIXED

I basically landed Peter's patches in this bug, with a few minor additional tweaks given that I updated to a slightly newer version.

Assignee: nobody → continuation
Target Milestone: --- → 149 Branch

If somebody is looking at verifying this, basically you just open the four test cases in a new tab, one at a time. You might get a weird error page, but the browser shouldn't crash. The test cases are: payload1.xml, payload2.xml, payload3.xml, payload4.xml and crashffsvgxml.html.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: