Closed Bug 1878211 Opened 1 year ago Closed 1 year ago

heap-buffer-overflow in [@ PolyArea::GetRect]

Categories

(Core :: Layout: Images, Video, and HTML Frames, defect)

defect

Tracking

()

VERIFIED FIXED
124 Branch
Tracking Status
firefox-esr115 123+ verified
firefox122 --- wontfix
firefox123 + verified
firefox124 + verified

People

(Reporter: tsmith, Assigned: eeejay)

References

(Blocks 1 open bug, )

Details

(5 keywords, Whiteboard: [adv-main123+r][adv-esr115.8+r])

Attachments

(2 files)

Found with m-c 20240201-366005a91eda (--enable-address-sanitizer)

This was found by visiting a live website with an ASan build.

STR:

  • Launch browser and visit site

This issue was triggered by visiting http://forecast.weather.gov/.

==41785==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50600031019c at pc 0x7fa72a377bdd bp 0x7fff67b764c0 sp 0x7fff67b764b8
READ of size 4 at 0x50600031019c thread T0 (Isolated Web Co)
    #0 0x7fa72a377bdc in PolyArea::GetRect(nsIFrame*, nsRect&) /builds/worker/checkouts/gecko/layout/generic/nsImageMap.cpp:498:49
    #1 0x7fa72a379482 in nsImageMap::GetBoundsForAreaContent(nsIContent*, nsRect&) /builds/worker/checkouts/gecko/layout/generic/nsImageMap.cpp:619:13
    #2 0x7fa72d5fe2ec in mozilla::a11y::HTMLAreaAccessible::RelativeBounds(nsIFrame**) const /builds/worker/checkouts/gecko/accessible/html/HTMLImageMapAccessible.cpp:173:22
    #3 0x7fa72d5fe505 in mozilla::a11y::HTMLAreaAccessible::ParentRelativeBounds() /builds/worker/checkouts/gecko/accessible/html/HTMLImageMapAccessible.cpp:186:31
    #4 0x7fa72d59ea50 in mozilla::a11y::LocalAccessible::BundleFieldsForCache(unsigned long, mozilla::a11y::CacheUpdateType) /builds/worker/checkouts/gecko/accessible/generic/LocalAccessible.cpp:3391:28
    #5 0x7fa72d60b090 in mozilla::a11y::DocAccessibleChild::SerializeAcc(mozilla::a11y::LocalAccessible*) /builds/worker/checkouts/gecko/accessible/ipc/DocAccessibleChild.cpp:64:15
    #6 0x7fa72d60bd83 in mozilla::a11y::DocAccessibleChild::InsertIntoIpcTree(mozilla::a11y::LocalAccessible*, bool) /builds/worker/checkouts/gecko/accessible/ipc/DocAccessibleChild.cpp:97:24
    #7 0x7fa72d5cff47 in mozilla::a11y::LocalAccessible::HandleAccEvent(mozilla::a11y::AccEvent*) /builds/worker/checkouts/gecko/accessible/generic/LocalAccessible.cpp:876:19
    #8 0x7fa72d51414b in nsEventShell::FireEvent(mozilla::a11y::AccEvent*) /builds/worker/checkouts/gecko/accessible/base/nsEventShell.cpp:54:15
    #9 0x7fa72d4f300e in mozilla::a11y::NotificationController::ProcessMutationEvents() /builds/worker/checkouts/gecko/accessible/base/NotificationController.cpp:616:7
    #10 0x7fa72d4f5e56 in mozilla::a11y::NotificationController::WillRefresh(mozilla::TimeStamp) /builds/worker/checkouts/gecko/accessible/base/NotificationController.cpp:984:3
    #11 0x7fa729e1c377 in nsRefreshDriver::TickObserverArray(unsigned int, mozilla::TimeStamp) /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:2447:10
    #12 0x7fa729e1319e in nsRefreshDriver::Tick(mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp, nsRefreshDriver::IsExtraTick) /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:2738:28
    #13 0x7fa729e2a086 in TickDriver /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:367:13
    #14 0x7fa729e2a086 in mozilla::RefreshDriverTimer::TickRefreshDrivers(mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp, nsTArray<RefPtr<nsRefreshDriver>>&) /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:345:7
    #15 0x7fa729e29d5e in mozilla::RefreshDriverTimer::Tick(mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp) /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:361:5
    #16 0x7fa729e299b1 in mozilla::VsyncRefreshDriverTimer::RunRefreshDrivers(mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp) /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:951:5
    #17 0x7fa729e28864 in mozilla::VsyncRefreshDriverTimer::TickRefreshDriver(mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp) /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:861:5
    #18 0x7fa729e273a4 in mozilla::VsyncRefreshDriverTimer::NotifyVsyncOnMainThread(mozilla::VsyncEvent const&) /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:758:5
    #19 0x7fa729e269a2 in mozilla::VsyncRefreshDriverTimer::RefreshDriverVsyncObserver::NotifyVsyncTimerOnMainThread() /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:592:14
    #20 0x7fa729e26555 in mozilla::VsyncRefreshDriverTimer::RefreshDriverVsyncObserver::NotifyVsync(mozilla::VsyncEvent const&) /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:549:9
    #21 0x7fa728169d1b in mozilla::dom::VsyncMainChild::RecvNotify(mozilla::VsyncEvent const&, float const&) /builds/worker/checkouts/gecko/dom/ipc/VsyncMainChild.cpp:66:15
    #22 0x7fa728782c9d in mozilla::dom::PVsyncChild::OnMessageReceived(IPC::Message const&) /builds/worker/workspace/obj-build/ipc/ipdl/PVsyncChild.cpp:237:78
    #23 0x7fa7285309fa in mozilla::dom::PContentChild::OnMessageReceived(IPC::Message const&) /builds/worker/workspace/obj-build/ipc/ipdl/PContentChild.cpp:8260:32
    #24 0x7fa71fd997a5 in mozilla::ipc::MessageChannel::DispatchAsyncMessage(mozilla::ipc::ActorLifecycleProxy*, IPC::Message const&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1813:25
    #25 0x7fa71fd951ab in mozilla::ipc::MessageChannel::DispatchMessage(mozilla::ipc::ActorLifecycleProxy*, mozilla::UniquePtr<IPC::Message, mozilla::DefaultDelete<IPC::Message>>) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1732:9
    #26 0x7fa71fd96559 in mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::ActorLifecycleProxy*, mozilla::ipc::MessageChannel::MessageTask&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1525:3
    #27 0x7fa71fd97ad3 in mozilla::ipc::MessageChannel::MessageTask::Run() /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1623:14
    #28 0x7fa71e0d049a in mozilla::RunnableTask::Run() /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:578:16
    #29 0x7fa71e0b631b in mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:905:26
    #30 0x7fa71e0b2ef8 in mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:728:15
    #31 0x7fa71e0b35f9 in mozilla::TaskController::ProcessPendingMTTask(bool) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:514:36
    #32 0x7fa71e0d8591 in operator() /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:232:37
    #33 0x7fa71e0d8591 in mozilla::detail::RunnableFunction<mozilla::TaskController::TaskController()::$_0>::Run() /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.h:548:5
    #34 0x7fa71e10050f in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:1199:16
    #35 0x7fa71e10e24a in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.cpp:480:10
    #36 0x7fa71fda2dae in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/worker/checkouts/gecko/ipc/glue/MessagePump.cpp:85:21
    #37 0x7fa71fbcb52a in RunInternal /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:370:10
    #38 0x7fa71fbcb52a in RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:363:3
    #39 0x7fa71fbcb52a in MessageLoop::Run() /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:345:3
    #40 0x7fa729526db9 in nsBaseAppShell::Run() /builds/worker/checkouts/gecko/widget/nsBaseAppShell.cpp:148:27
    #41 0x7fa72972dcc2 in nsAppShell::Run() /builds/worker/checkouts/gecko/widget/gtk/nsAppShell.cpp:470:33
    #42 0x7fa72e4e8dce in XRE_RunAppShell() /builds/worker/checkouts/gecko/toolkit/xre/nsEmbedFunctions.cpp:721:20
    #43 0x7fa71fbcb52a in RunInternal /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:370:10
    #44 0x7fa71fbcb52a in RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:363:3
    #45 0x7fa71fbcb52a in MessageLoop::Run() /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:345:3
    #46 0x7fa72e4e8373 in XRE_InitChildProcess(int, char**, XREChildData const*) /builds/worker/checkouts/gecko/toolkit/xre/nsEmbedFunctions.cpp:656:34
    #47 0x55c93f30853c in content_process_main /builds/worker/checkouts/gecko/browser/app/../../ipc/contentproc/plugin-container.cpp:57:28
    #48 0x55c93f30853c in main /builds/worker/checkouts/gecko/browser/app/nsBrowserApp.cpp:375:18
    #49 0x7fa746429d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #50 0x7fa746429e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #51 0x55c93f22c848 in _start (/home/user/workspace/browsers/m-c-20240201173838-fuzzing-asan-opt/firefox+0xdc848) (BuildId: 62afdc50f9f296278e12e04b2f7345d38694de0d)

0x50600031019c is located 0 bytes after 60-byte region [0x506000310160,0x50600031019c)
allocated by thread T0 (Isolated Web Co) here:
    #0 0x55c93f2c86ae in malloc /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:69:3
    #1 0x55c93f30d7c5 in moz_xmalloc /builds/worker/checkouts/gecko/memory/mozalloc/mozalloc.cpp:52:15
    #2 0x7fa72a374320 in operator new[] /builds/worker/workspace/obj-build/dist/include/mozilla/cxxalloc.h:42:10
    #3 0x7fa72a374320 in MakeUnique<int[]> /builds/worker/workspace/obj-build/dist/include/mozilla/UniquePtr.h:613:23
    #4 0x7fa72a374320 in Area::ParseCoords(nsTSubstring<char16_t> const&) /builds/worker/checkouts/gecko/layout/generic/nsImageMap.cpp:181:39
    #5 0x7fa72a376281 in PolyArea::ParseCoords(nsTSubstring<char16_t> const&) /builds/worker/checkouts/gecko/layout/generic/nsImageMap.cpp:377:9
    #6 0x7fa72a37a7f5 in nsImageMap::AddArea(mozilla::dom::HTMLAreaElement*) /builds/worker/checkouts/gecko/layout/generic/nsImageMap.cpp:736:9
    #7 0x7fa72a379e11 in nsImageMap::SearchForAreas(nsIContent*) /builds/worker/checkouts/gecko/layout/generic/nsImageMap.cpp:660:7
    #8 0x7fa72a37100d in UpdateAreas /builds/worker/checkouts/gecko/layout/generic/nsImageMap.cpp:681:3
    #9 0x7fa72a37100d in nsImageMap::Init(nsImageFrame*, nsIContent*) /builds/worker/checkouts/gecko/layout/generic/nsImageMap.cpp:652:3
    #10 0x7fa72a35d189 in nsImageFrame::GetImageMap() /builds/worker/checkouts/gecko/layout/generic/nsImageFrame.cpp:2627:18
    #11 0x7fa72a35c449 in nsImageFrame::Init(nsIContent*, nsContainerFrame*, nsIFrame*) /builds/worker/checkouts/gecko/layout/generic/nsImageFrame.cpp:705:3
    #12 0x7fa729f6aa8d in InitAndRestoreFrame /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:4613:14
    #13 0x7fa729f6aa8d in nsCSSFrameConstructor::ConstructFrameFromItemInternal(nsCSSFrameConstructor::FrameConstructionItem&, nsFrameConstructorState&, nsContainerFrame*, nsFrameList&) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:3791:7
    #14 0x7fa729f74557 in nsCSSFrameConstructor::ConstructFramesFromItem(nsFrameConstructorState&, nsCSSFrameConstructor::FrameConstructionItemList::Iterator&, nsContainerFrame*, nsFrameList&) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:5548:3
    #15 0x7fa729f50a06 in nsCSSFrameConstructor::ConstructFramesFromItemList(nsFrameConstructorState&, nsCSSFrameConstructor::FrameConstructionItemList&, nsContainerFrame*, bool, nsFrameList&) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:9476:5
    #16 0x7fa729f52564 in nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState&, nsIContent*, mozilla::ComputedStyle*, nsContainerFrame*, bool, nsFrameList&, bool, nsIFrame*) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:9763:3
    #17 0x7fa729f5dce0 in nsCSSFrameConstructor::ConstructBlock(nsFrameConstructorState&, nsIContent*, nsContainerFrame*, nsContainerFrame*, mozilla::ComputedStyle*, nsContainerFrame**, nsFrameList&, nsIFrame*) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:10626:3
    #18 0x7fa729f68158 in nsCSSFrameConstructor::ConstructNonScrollableBlock(nsFrameConstructorState&, nsCSSFrameConstructor::FrameConstructionItem&, nsContainerFrame*, nsStyleDisplay const*, nsFrameList&) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:4600:3
    #19 0x7fa729f6a6a5 in nsCSSFrameConstructor::ConstructFrameFromItemInternal(nsCSSFrameConstructor::FrameConstructionItem&, nsFrameConstructorState&, nsContainerFrame*, nsFrameList&) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:3766:16
    #20 0x7fa729f74557 in nsCSSFrameConstructor::ConstructFramesFromItem(nsFrameConstructorState&, nsCSSFrameConstructor::FrameConstructionItemList::Iterator&, nsContainerFrame*, nsFrameList&) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:5548:3
    #21 0x7fa729f50a06 in nsCSSFrameConstructor::ConstructFramesFromItemList(nsFrameConstructorState&, nsCSSFrameConstructor::FrameConstructionItemList&, nsContainerFrame*, bool, nsFrameList&) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:9476:5
    #22 0x7fa729f52564 in nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState&, nsIContent*, mozilla::ComputedStyle*, nsContainerFrame*, bool, nsFrameList&, bool, nsIFrame*) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:9763:3
    #23 0x7fa729f5dce0 in nsCSSFrameConstructor::ConstructBlock(nsFrameConstructorState&, nsIContent*, nsContainerFrame*, nsContainerFrame*, mozilla::ComputedStyle*, nsContainerFrame**, nsFrameList&, nsIFrame*) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:10626:3
    #24 0x7fa729f68158 in nsCSSFrameConstructor::ConstructNonScrollableBlock(nsFrameConstructorState&, nsCSSFrameConstructor::FrameConstructionItem&, nsContainerFrame*, nsStyleDisplay const*, nsFrameList&) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:4600:3
    #25 0x7fa729f6a6a5 in nsCSSFrameConstructor::ConstructFrameFromItemInternal(nsCSSFrameConstructor::FrameConstructionItem&, nsFrameConstructorState&, nsContainerFrame*, nsFrameList&) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:3766:16
    #26 0x7fa729f74557 in nsCSSFrameConstructor::ConstructFramesFromItem(nsFrameConstructorState&, nsCSSFrameConstructor::FrameConstructionItemList::Iterator&, nsContainerFrame*, nsFrameList&) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:5548:3
    #27 0x7fa729f50a06 in nsCSSFrameConstructor::ConstructFramesFromItemList(nsFrameConstructorState&, nsCSSFrameConstructor::FrameConstructionItemList&, nsContainerFrame*, bool, nsFrameList&) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:9476:5
    #28 0x7fa729f52564 in nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState&, nsIContent*, mozilla::ComputedStyle*, nsContainerFrame*, bool, nsFrameList&, bool, nsIFrame*) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:9763:3
    #29 0x7fa729f5dce0 in nsCSSFrameConstructor::ConstructBlock(nsFrameConstructorState&, nsIContent*, nsContainerFrame*, nsContainerFrame*, mozilla::ComputedStyle*, nsContainerFrame**, nsFrameList&, nsIFrame*) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:10626:3
    #30 0x7fa729f68158 in nsCSSFrameConstructor::ConstructNonScrollableBlock(nsFrameConstructorState&, nsCSSFrameConstructor::FrameConstructionItem&, nsContainerFrame*, nsStyleDisplay const*, nsFrameList&) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:4600:3
    #31 0x7fa729f6a6a5 in nsCSSFrameConstructor::ConstructFrameFromItemInternal(nsCSSFrameConstructor::FrameConstructionItem&, nsFrameConstructorState&, nsContainerFrame*, nsFrameList&) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:3766:16
    #32 0x7fa729f74557 in nsCSSFrameConstructor::ConstructFramesFromItem(nsFrameConstructorState&, nsCSSFrameConstructor::FrameConstructionItemList::Iterator&, nsContainerFrame*, nsFrameList&) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:5548:3
    #33 0x7fa729f50a06 in nsCSSFrameConstructor::ConstructFramesFromItemList(nsFrameConstructorState&, nsCSSFrameConstructor::FrameConstructionItemList&, nsContainerFrame*, bool, nsFrameList&) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:9476:5

A Pernosco session is available here: https://pernos.co/debug/7F0Uz0m3_aXWej5U_k_Rog/index.html

Keywords: pernosco
Group: dom-core-security → layout-core-security
Keywords: sec-high

I don't think a11y is accessing layout when it shouldn't, since this happens in our refresh tick, so I'm not sure why this would happen.

Severity: -- → S2

Eitan, can you glean anything from Pernosco?

Flags: needinfo?(eitan)

Yup, looking into this.

Flags: needinfo?(eitan)

area[shape=poly] provides a flattened list of x/y coordinates in the coords attribute. We are hitting this because the number of coordinates provided is uneven and we have no fail-safe for that. Although this is a layout bug, a11y seems to be the sole consumer of nsImageMap::GetBoundsForAreaContent which triggers this.

Assignee: nobody → eitan
Component: Disability Access APIs → Layout: Images, Video, and HTML Frames

Looking in pernosco and the patch, it looks like the issue here is a mismatch between the counts here where we allocate precisely mNumCoords entries in mCoords:
https://searchfox.org/mozilla-central/rev/896042a1a71066254ceb5291f016ca3dbca21cb7/layout/generic/nsImageMap.cpp#181,216-217

UniquePtr<nscoord[]> value_list = MakeUnique<nscoord[]>(cnt);
...
mNumCoords = cnt;
mCoords = std::move(value_list);

...vs. here where the i+1 indexing operation potentially is an access of mCoords[mNumCoords], just off the end of the array, if mNumCoords is odd:
https://searchfox.org/mozilla-central/rev/896042a1a71066254ceb5291f016ca3dbca21cb7/layout/generic/nsImageMap.cpp#491,496-498

void PolyArea::GetRect(nsIFrame* aFrame, nsRect& aRect) {
...
    for (int32_t i = 2; i < mNumCoords; i += 2) {
      xtmp = nsPresContext::CSSPixelsToAppUnits(mCoords[i]);
      ytmp = nsPresContext::CSSPixelsToAppUnits(mCoords[i + 1]);

Any chance we could change mCoords to be an nsTArray which is bounds checked, here or in a followup? It doesn't look like there are TOO many uses of nsCoord[] so maybe all of that could be cleaned up. I don't know if this is performance sensitive enough for those bounds checks to matter.

This code here is definitely not performance-sensitive where a nsTArray bounds-check would matter.

That conversion makes sense; let's do that in a followup, so that the patch here can be trivial and hence uplifted confidently (I suspect we'll want to land this on all branches -- including ESR -- at once, when we're at a good time for sec-bug-landing).

Attachment #9378352 - Attachment description: Bug 1878211 - Round down uneven coord attribute for PolyArea areas. r?dholbert → Bug 1878211 - Round down uneven coord list when processing PolyArea. r?dholbert
Attachment #9378352 - Attachment description: Bug 1878211 - Round down uneven coord list when processing PolyArea. r?dholbert → Bug 1878211 - Process pairs in coord list in PolyArea. r?dholbert

Comment on attachment 9378352 [details]
Bug 1878211 - Process pairs in coord list in PolyArea. r?dholbert

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: Not hard. A web author just needs to pass an uneven coord list and wait for someone with a11y enabled.
  • 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?: No
  • If not, how different, hard to create, and risky will they be?: easy
  • How likely is this patch to cause regressions; how much testing does it need?: this is a very simple patch
  • Is Android affected?: Yes
Attachment #9378352 - Flags: sec-approval?

(In reply to Eitan Isaacson [:eeejay] from comment #10)

  • Do you have backports for the affected branches?: No
  • If not, how different, hard to create, and risky will they be?: easy

slightly more detail on this^: the existing patch applies perfectly to ESR115 (I just checked), so the patch should uplift trivially with no manual rebasing needed.

(This code hasn't changed much in ages.)

This testcase crashes in ASAN builds, if you:
(1) run the build with environmental variable GNOME_ACCESSIBILITY=1
...or:
(2) Prompt the testcase to draw a focus ring by pressing "Tab" after you load it

These two different approaches are crashing via the two different codepaths that are fixed in eeejay's patch here.

(In reply to Daniel Holbert [:dholbert] from comment #12)

(2) Prompt the testcase to draw a focus ring by pressing "Tab" after you load it

Note, I tried to automate the focus-ring action in this testcase, but that apparently doesn't work due to another bug with our image map handling. I filed bug 1878753 on that.

(With that fixed, we could create a better automated test for this sec issue here. In the meantime, an automated testcase here would probably need to use SpecialPowers or EventUtils or somesuch to synthesize a Tab keyboard-event.)

[EDIT Feb 8th: Looks like bug 1878753 is being fixed rather quickly, so we can morph this into a relatively-simple automated test, when we're ready to land tests here. Hooray!]

I verified that eeejay's attached patch fixes the crash, testing a local ASAN debug+opt build on my attached testcase 1 with steps in comment 12.

In a stock ASAN debug+opt build, both approaches (1) and (2) from comment 12 instantly crash for me, with this fatal asan error:

==384424==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x504000113e34 at pc 0x7f39116ae4e8 bp 0x7ffdec65ac50 sp 0x7ffdec65ac48
READ of size 4 at 0x504000113e34 thread T0 (file:// Content)

When I apply eeejay's patch and rebuild and repeat the test, I don't crash.

Comment on attachment 9378352 [details]
Bug 1878211 - Process pairs in coord list in PolyArea. r?dholbert

Approved to request uplift and land

Attachment #9378352 - Flags: sec-approval? → sec-approval+
Pushed by rvandermeulen@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/52b668d19d28 Process pairs in coord list in PolyArea. r=dholbert

[ni=eeejay as a reminder to request uplift soonish]

Flags: needinfo?(eitan)

Keeping the NI to remember. I'm going to wait 24 hours after this lands in Central and we didn't break precious image maps for everyone.

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

There was no uplift request for beta/release/esr and we are in RC week, can it wait for 124 / esr 115.9 or should I already plan a RC2 for an uplift? The patch grafts cleanly to mozilla-release and esr.

Comment on attachment 9378352 [details]
Bug 1878211 - Process pairs in coord list in PolyArea. r?dholbert

Beta/Release Uplift Approval Request

  • User impact if declined: Potential UAF in badly authored HTML.
  • Is this code covered by automated tests?: No
  • Has the fix been verified in Nightly?: Yes
  • Needs manual test from QE?: Yes
  • If yes, steps to reproduce: Execute attached test case in comment #12.
  • List of other uplifts needed: None
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): It is a very small change that just assures an array is even.
  • String changes made/needed:
  • Is Android affected?: Yes

ESR Uplift Approval Request

  • If this is not a sec:{high,crit} bug, please state case for ESR consideration:
  • User impact if declined: Potential UAF in badly authored HTML.
  • Fix Landed on Version: 124
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): It is a very small change that just assures an array is even.
Flags: needinfo?(eitan)
Attachment #9378352 - Flags: approval-mozilla-esr115?
Attachment #9378352 - Flags: approval-mozilla-beta?
Flags: qe-verify+

Comment on attachment 9378352 [details]
Bug 1878211 - Process pairs in coord list in PolyArea. r?dholbert

Approved for 123.0RC + ESR, thanks

Attachment #9378352 - Flags: approval-mozilla-release+
Attachment #9378352 - Flags: approval-mozilla-esr115?
Attachment #9378352 - Flags: approval-mozilla-esr115+
Attachment #9378352 - Flags: approval-mozilla-beta?
QA Whiteboard: [post-critsmash-triage]

Reproduced the issue with Firefox 124.0a1 Bof Asan build (366005a91eda) on Ubuntu 22 by visiting the website from comment 0 and by opening the test case from comment 12 with the export GNOME_ACCESSIBILITY=1 env variable set. A tab crash can be seen. Running the test case will crash the tab with and without the environment variable as stated in comment 12.

Verified fixed with Firefox Asan Bof 124.0a1 (2024-02-13), Firefox 123.0 (20240212203859) AsanBof and Firefox 115.8.0esr (20240213011312) AsanBof on Ubuntu 22. This was tested by accessing the webpage mentioned in comment 0 along with the test case, and then using the Tab key to focus on the red box, with the export GNOME_ACCESSIBILITY=1 environment variable enabled and without it.

I have also tested Firefox Asan Bof 124.0a1 (2024-02-13), and Firefox Asan Bof 123.0 (20240212203859) on Windows 10x64 by using the test case and the link from comment 0, and no tab crashes can be seen. Note that Firefox 115.8.0esr Asan Bof build does not work on Windows 10 for some reason and neither does 115.7.0esr Asan bof build.

Status: RESOLVED → VERIFIED
Has STR: --- → yes
Flags: qe-verify+

(In reply to Andrew McCreight [:mccr8] from comment #8)

Any chance we could change mCoords to be an nsTArray which is bounds checked, here or in a followup? It doesn't look like there are TOO many uses of nsCoord[] so maybe all of that could be cleaned up. I don't know if this is performance sensitive enough for those bounds checks to matter.

I filed bug 1880093 about this. Thanks to Freddy for the reminder.

Whiteboard: [adv-main123+r]
Whiteboard: [adv-main123+r] → [adv-main123+r][adv-esr115.8+r]
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: