Closed Bug 2015199 (CVE-2026-2775) Opened 9 months ago Closed 9 months ago

Assertion failure: !aKid->GetParentNode() (Inserting node that already has parent), at /dom/base/nsINode.cpp:1737

Categories

(Core :: DOM: HTML Parser, defect)

x86_64
Linux
defect

Tracking

()

VERIFIED FIXED
149 Branch
Tracking Status
firefox-esr115 148+ verified
firefox-esr140 148+ verified
firefox147 --- wontfix
firefox148 + verified
firefox149 + verified

People

(Reporter: tsmith, Assigned: hsivonen)

References

Details

(5 keywords, Whiteboard: [bugmon:bisected,confirmed][adv-main148+] [adv-esr115.33+] [adv-esr140.8+] )

Attachments

(4 files, 5 external files)

Reproduced on mozilla-central rev ed1c0b4f0bbe (built with: --enable-debug --enable-fuzzing).

Testcase can be reproduced using the following commands:

$ pip install fuzzfetch grizzly-framework pipx --upgrade
$ python -m pipx ensurepath
$ fuzzfetch --build ed1c0b4f0bbe --debug --fuzzing  -n firefox
$ grizzly-replay-bugzilla ./firefox/firefox <bugid>
Assertion failure: !aKid->GetParentNode() (Inserting node that already has parent), at /dom/base/nsINode.cpp:1737

    ==21501==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f3ca6c51ecb bp 0x7fff96547390 sp 0x7fff96547270 T21501)
    ==21501==The signal is caused by a WRITE memory access.
    ==21501==Hint: address points to the zero page.
        #0 0x7f3ca6c51ecb in MOZ_CrashSequence /builds/worker/workspace/obj-build/dist/include/mozilla/Assertions.h:237:3
        #1 0x7f3ca6c51ecb in nsINode::InsertChildBefore(nsIContent*, nsIContent*, bool, mozilla::ErrorResult&, nsINode*, MutationEffectOnScript) /dom/base/nsINode.cpp:1737:3
        #2 0x7f3ca596e68f in AppendChildTo /dom/base/nsINode.h:1048:5
        #3 0x7f3ca596e68f in nsHtml5TreeOperation::Append(nsIContent*, nsIContent*, nsHtml5DocumentBuilder*) /parser/html/nsHtml5TreeOperation.cpp:272:12
        #4 0x7f3ca59646bf in nsHtml5TreeOperation::Append(nsIContent*, nsIContent*, mozilla::dom::FromParser, nsHtml5DocumentBuilder*) /parser/html/nsHtml5TreeOperation.cpp:290:17
        #5 0x7f3ca5968faa in nsHtml5TreeOpExecutor::RunFlushLoop() /parser/html/nsHtml5TreeOpExecutor.cpp:664:19
        #6 0x7f3ca596f80c in nsHtml5ExecutorFlusher::Run() /parser/html/nsHtml5StreamParser.cpp:158:18
        #7 0x7f3ca4944497 in mozilla::RunnableTask::Run() /xpcom/threads/TaskController.cpp:705:16
        #8 0x7f3ca493eb64 in mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /xpcom/threads/TaskController.cpp:1325:20
        #9 0x7f3ca493d7e7 in mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /xpcom/threads/TaskController.cpp:1148:15
        #10 0x7f3ca493dc65 in mozilla::TaskController::ProcessPendingMTTask(bool) /xpcom/threads/TaskController.cpp:641:36
        #11 0x7f3ca494d776 in operator() /xpcom/threads/TaskController.cpp:333:37
        #12 0x7f3ca494d776 in mozilla::detail::RunnableFunction<mozilla::TaskController::TaskController()::$_0>::Run() /xpcom/threads/nsThreadUtils.h:549:5
        #13 0x7f3ca495fcf3 in nsThread::ProcessNextEvent(bool, bool*) /xpcom/threads/nsThread.cpp:1168:16
        #14 0x7f3ca496594f in NS_ProcessNextEvent(nsIThread*, bool) /xpcom/threads/nsThreadUtils.cpp:461:10
        #15 0x7f3ca5555287 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /ipc/glue/MessagePump.cpp:85:21
        #16 0x7f3ca54ae691 in RunHandler /ipc/chromium/src/base/message_loop.cc:366:3
        #17 0x7f3ca54ae691 in MessageLoop::Run() /ipc/chromium/src/base/message_loop.cc:348:3
        #18 0x7f3caa665a68 in nsBaseAppShell::Run() /widget/nsBaseAppShell.cpp:152:27
        #19 0x7f3caa731484 in nsAppShell::Run() /widget/gtk/nsAppShell.cpp:555:33
        #20 0x7f3cab7794eb in XRE_RunAppShell() /toolkit/xre/nsEmbedFunctions.cpp:652:20
        #21 0x7f3ca5556134 in mozilla::ipc::MessagePumpForChildProcess::Run(base::MessagePump::Delegate*) /ipc/glue/MessagePump.cpp:235:9
        #22 0x7f3ca54ae691 in RunHandler /ipc/chromium/src/base/message_loop.cc:366:3
        #23 0x7f3ca54ae691 in MessageLoop::Run() /ipc/chromium/src/base/message_loop.cc:348:3
        #24 0x7f3cab778c4f in XRE_InitChildProcess(int, char**, XREChildData const*) /toolkit/xre/nsEmbedFunctions.cpp:590:34
        #25 0x5955e3e7af8c in main /browser/app/nsBrowserApp.cpp:465:22
        #26 0x7f3cb622a1c9 in __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
        #27 0x7f3cb622a28a in __libc_start_main ./csu/../csu/libc-start.c:360:3
        #28 0x5955e3e4ede8 in _start ??:0:0
    
    ==21501==Register values:
    rax = 0x0000000000000000  rbx = 0x000000000810001e  rcx = 0x00000000000006c9  rdx = 0x00007f3cb6404563
    rdi = 0x00007f3cb6405700  rsi = 0x0000000000000000  rbp = 0x00007fff96547390  rsp = 0x00007fff96547270
     r8 = 0x0000000000000000   r9 = 0x0000000000000003  r10 = 0x0000000000000002  r11 = 0x0000000000000293
    r12 = 0x000059561d4e6bf0  r13 = 0x000059561cb85b20  r14 = 0x000059561d810440  r15 = 0x000059561d822b80
    UndefinedBehaviorSanitizer can not provide additional info.
    SUMMARY: UndefinedBehaviorSanitizer: SEGV (/home/user/workspace/browsers/m-c-20260205163736-fuzzing-debug/libxul.so+0x6c51ecb) (BuildId: 0b411186bb9521ab7e302998bc6191dc011c2d12)
    ==21501==ABORTING
Attached file Testcase —
Flags: needinfo?(hsivonen)
Component: DOM: Core & HTML → DOM: HTML Parser

Most likely sec-high, looks scary. Parser uses faster APIs to create DOM tree, and those bypass some checks.

Keywords: sec-high

Verified bug as reproducible on mozilla-central 20260208200320-af326189e3d9.
Unable to bisect testcase (Testcase reproduces on start build!):

Start: dabc3564fa3a922b2336541b737cb27ae04f4d3a (20250210213927)
End: ed1c0b4f0bbef7e458685d5f4743c73ae66cc3fd (20260205163736)
BuildFlags: BuildFlags(asan=False, tsan=False, debug=True, fuzzing=True, coverage=False, valgrind=False, no_opt=False, fuzzilli=False, nyx=False, searchfox=False, afl=False)

Whiteboard: [bugmon:confirm] → [bugmon:bisected,confirmed]
Assignee: nobody → hsivonen
Status: NEW → ASSIGNED
Flags: needinfo?(hsivonen)
Attached file (secure) —

The patch intentionally has no comments and no test case. We should add those as a follow-up.

Attached file Minimized testcase —

New more Chrome-compatible patch coming up.

Comment on attachment 9543822 [details]
(secure)

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: Unclear what it takes to get to an actual exploit, but itäs pretty clear from the patch that it's somehow possible for the new elements to have gained a parent, and it's pretty obvious that the only possibility is Custom Elements.
  • 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 branches (beta, release, and/or ESR) are affected by this flaw, and do the release status flags reflect this affected/unaffected state correctly?: all, yes
  • If not all supported branches, which bug introduced the flaw?: None
  • Do you have backports for the affected branches?: No
  • If not, how different, hard to create, and risky will they be?: This patch should apply as-is or with a trivial merge.
  • How likely is this patch to cause regressions; how much testing does it need?: Unlikely to cause anything worse than what we have now: The new action can already be executed by the parser in a different situation.
  • Is the patch ready to land after security approval is given?: Yes
  • Is Android affected?: Yes
Attachment #9543822 - Flags: sec-approval?

Comment on attachment 9543822 [details]
(secure)

sec-approval+, a=dveditz
Please wait until a couple weeks after 149 ships before landing a testcase (I'll set a reminder)

Attachment #9543822 - Flags: sec-approval? → sec-approval+
Whiteboard: [bugmon:bisected,confirmed] → [bugmon:bisected,confirmed][reminder-test 2026-04-07]
Group: dom-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 9 months ago
Resolution: --- → FIXED
Target Milestone: --- → 149 Branch

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

For more information, please visit BugBot documentation.

Flags: needinfo?(hsivonen)

Tomorrow is the last beta build for Fx148.
:hsivonen, hopefully you can add uplift requests in time to make the beta build.
To add to Comment 13, it will need uplift requests for ESR115 and ESR140, but it grafts cleanly to both.

Verified bug as fixed on rev mozilla-central 20260212095231-0aca2c737e84.
Removing bugmon keyword as no further action possible. Please review the bug and re-add the keyword for further analysis.

Status: RESOLVED → VERIFIED
Keywords: bugmon
Attached file (secure) —
Attachment #9544855 - Flags: approval-mozilla-beta?

firefox-beta Uplift Approval Request

  • User impact if declined: At the very least, the bug makes it possible for a content process to go into an unusable state. It's quite possible that there is a chance for a further exploit, but we haven't looked into proving concrete specifics.
  • Code covered by automated testing: no
  • Fix verified in Nightly: yes
  • Needs manual QE test: yes
  • Steps to reproduce for manual QE testing: Manually load the original test case and the minimized test case from this bug and observe that the browser tab can be used afterwards and doesn't go all weird.

Note: Even with this fix, the original test case creates an excessively deep DOM tree, which will make extensions that traverse the DOM excessively slow. Having to dismiss an infobar about an extension running slowly (if you have such an extension, e.g. 1Password, installed) is an issue distinct from this bug.

  • Risk associated with taking this patch: low
  • Explanation of risk level: The risk is low, because this patch re-uses a behavior that the parser already executes in another situation.
  • String changes made/needed: None.
  • Is Android affected?: yes
Flags: qe-verify+
Attached file (secure) —
Attachment #9544856 - Flags: approval-mozilla-esr115?

firefox-esr115 Uplift Approval Request

  • User impact if declined: At the very least, the bug makes it possible for a content process to go into an unusable state. It's quite possible that there is a chance for a further exploit, but we haven't looked into proving concrete specifics.
  • Code covered by automated testing: no
  • Fix verified in Nightly: yes
  • Needs manual QE test: yes
  • Steps to reproduce for manual QE testing: Manually load the original test case and the minimized test case from this bug and observe that the browser tab can be used afterwards and doesn't go all weird.

Note: Even with this fix, the original test case creates an excessively deep DOM tree, which will make extensions that traverse the DOM excessively slow. Having to dismiss an infobar about an extension running slowly (if you have such an extension, e.g. 1Password, installed) is an issue distinct from this bug.

  • Risk associated with taking this patch: low
  • Explanation of risk level: The risk is low, because this patch re-uses a behavior that the parser already executes in another situation.
  • String changes made/needed: None.
  • Is Android affected?: yes

firefox-esr140 Uplift Approval Request

  • User impact if declined: At the very least, the bug makes it possible for a content process to go into an unusable state. It's quite possible that there is a chance for a further exploit, but we haven't looked into proving concrete specifics.
  • Code covered by automated testing: no
  • Fix verified in Nightly: yes
  • Needs manual QE test: yes
  • Steps to reproduce for manual QE testing: Manually load the original test case and the minimized test case from this bug and observe that the browser tab can be used afterwards and doesn't go all weird.

Note: Even with this fix, the original test case creates an excessively deep DOM tree, which will make extensions that traverse the DOM excessively slow. Having to dismiss an infobar about an extension running slowly (if you have such an extension, e.g. 1Password, installed) is an issue distinct from this bug.

  • Risk associated with taking this patch: low
  • Explanation of risk level: The risk is low, because this patch re-uses a behavior that the parser already executes in another situation.
  • String changes made/needed: None.
  • Is Android affected?: yes
Attachment #9544857 - Flags: approval-mozilla-esr140?
Attached file (secure) —

(In reply to Donal Meehan [:dmeehan] from comment #14)

Tomorrow is the last beta build for Fx148.
:hsivonen, hopefully you can add uplift requests in time to make the beta build.
To add to Comment 13, it will need uplift requests for ESR115 and ESR140, but it grafts cleanly to both.

Requested uplifts. (I didn't do so immediately when the bot needinfoed me, because there was a time gap to the Nightly with the fix becoming available to me and I wanted to check personally before checking the box to say that this has been verified in Nightly.)

Flags: needinfo?(hsivonen)
Attachment #9544855 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
Attachment #9544857 - Flags: approval-mozilla-esr140? → approval-mozilla-esr140+
Attachment #9544856 - Flags: approval-mozilla-esr115? → approval-mozilla-esr115+
QA Whiteboard: [sec] [uplift] [qa-ver-needed-c149/b148]
Whiteboard: [bugmon:bisected,confirmed][reminder-test 2026-04-07] → [bugmon:bisected,confirmed][reminder-test 2026-04-07][adv-main148+]

The issue is no longer reproducible on Firefox 149.0a1 or on Firefox 148.0b15. Tests were performed under Windows 10, macOS 10.15 and Ubuntu 24.

(In reply to Olli Pettay [:smaug][bugs@pettay.fi] from comment #3)

Most likely sec-high, looks scary. Parser uses faster APIs to create DOM tree, and those bypass some checks.

Would this not be a nullptr in other cases or why is it a sec-high? A nullptr wouldn't be exploitable, right?

Flags: needinfo?(smaug)

This isn't nullptr. This is about DOM being in a wrong state.

Flags: needinfo?(smaug)

The issue was also verified on ESR 115.33.0 and on ESR 140.8.0-build2 under Windows 11, macOS 10.15 and under Ubuntu 24.

QA Whiteboard: [sec] [uplift] [qa-ver-needed-c149/b148] → [sec] [uplift] [qa-ver-done-c149/b148]
Whiteboard: [bugmon:bisected,confirmed][reminder-test 2026-04-07][adv-main148+] → [bugmon:bisected,confirmed][reminder-test 2026-04-07][adv-main148+] [adv-esr115.33+]
Whiteboard: [bugmon:bisected,confirmed][reminder-test 2026-04-07][adv-main148+] [adv-esr115.33+] → [bugmon:bisected,confirmed][reminder-test 2026-04-07][adv-main148+] [adv-esr115.33+] [adv-esr140.8+]
Alias: CVE-2026-2775
See Also: → 2028289

2 months ago, dveditz placed a reminder on the bug using the whiteboard tag [reminder-test 2026-04-07] .

hsivonen, please refer to the original comment to better understand the reason for the reminder.

Flags: needinfo?(hsivonen)
Whiteboard: [bugmon:bisected,confirmed][reminder-test 2026-04-07][adv-main148+] [adv-esr115.33+] [adv-esr140.8+] → [bugmon:bisected,confirmed][adv-main148+] [adv-esr115.33+] [adv-esr140.8+]

Let's set another 2-month timer, since it doesn't make sense to disclose a test now that we know that one case was missed and only recently got fixed as bug 2028289.

Flags: needinfo?(hsivonen)
Whiteboard: [bugmon:bisected,confirmed][adv-main148+] [adv-esr115.33+] [adv-esr140.8+] → [bugmon:bisected,confirmed][adv-main148+] [adv-esr115.33+] [adv-esr140.8+] [reminder-test 2026-06-07]
See Also: → CVE-2026-12314

2 months ago, hsivonen placed a reminder on the bug using the whiteboard tag [reminder-test 2026-06-07] .

hsivonen, please refer to the original comment to better understand the reason for the reminder.

Flags: needinfo?(hsivonen)
Whiteboard: [bugmon:bisected,confirmed][adv-main148+] [adv-esr115.33+] [adv-esr140.8+] [reminder-test 2026-06-07] → [bugmon:bisected,confirmed][adv-main148+] [adv-esr115.33+] [adv-esr140.8+]
Attached file (secure) —

A patch has been attached on this bug, which was already closed. Filing a separate bug will ensure better tracking. If this was not by mistake and further action is needed, please alert the appropriate party. (Or: if the patch doesn't change behavior -- e.g. landing a test case, or fixing a typo -- then feel free to disregard this message)

(In reply to BugBot [:suhaib / :marco] from comment #35)

A patch has been attached on this bug, which was already closed. Filing a separate bug will ensure better tracking. If this was not by mistake and further action is needed, please alert the appropriate party. (Or: if the patch doesn't change behavior -- e.g. landing a test case, or fixing a typo -- then feel free to disregard this message)

This was for the test.

Flags: needinfo?(hsivonen)
Group: core-security-release
Keywords: keep-hidden
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: