Bug 1222809 (CVE-2015-7212)

Memset crash in mozilla::layers::BufferTextureClient::AllocateForSurface

VERIFIED FIXED

Status

()

defect
VERIFIED FIXED
4 years ago
2 years ago

People

(Reporter: inferno, Assigned: nical)

Tracking

({sec-high})

Trunk
Points:
---
Bug Flags:
sec-bounty +

Firefox Tracking Flags

(firefox43 verified, firefox44 verified, firefox45 verified, firefox-esr3843+ verified)

Details

(Whiteboard: [fixed by bug 1224254][adv-main43+][adv-esr38.5+])

Attachments

(2 attachments)

(Reporter)

Description

4 years ago
Posted file Testcase
Crash Annotation GraphicsCriticalError: |[0][GFX1-]: Attempt to create DrawTarget for invalid surface. Size(17895697,25) Cairo Status: 32[GFX1-]: Attempt to create DrawTarget for invalid surface. Size(17895697,25) Cairo Status: 32
Crash Annotation GraphicsCriticalError: |[0][GFX1-]: Attempt to create DrawTarget for invalid surface. Size(17895697,25) Cairo Status: 32|[1][GFX1-]: Failed to create DrawTarget, Type: 4 Size: Size(17895697,25), Data: 0x, Stride: 71582788[GFX1-]: Failed to create DrawTarget, Type: 4 Size: Size(17895697,25), Data: 0x, Stride: 71582788
Crash Annotation GraphicsCriticalError: |[0][GFX1-]: Attempt to create DrawTarget for invalid surface. Size(17895697,25) Cairo Status: 32|[1][GFX1-]: Failed to create DrawTarget, Type: 4 Size: Size(17895697,25), Data: 0x, Stride: 71582788|[2][GFX1-]: Failed GetAsDrawTarget true, 0x7fd87a0f2000 + 16, Size(17895697,25), 71582788, 0[GFX1-]: Failed GetAsDrawTarget true, 0x7fd87a0f2000 + 16, Size(17895697,25), 71582788, 0
Crash Annotation GraphicsCriticalError: |[0][GFX1-]: Attempt to create DrawTarget for invalid surface. Size(17895697,25) Cairo Status: 32|[1][GFX1-]: Failed to create DrawTarget, Type: 4 Size: Size(17895697,25), Data: 0x, Stride: 71582788|[2][GFX1-]: Failed GetAsDrawTarget true, 0x7fd87a0f2000 + 16, Size(17895697,25), 71582788, 0|[3][GFX1-]: Attempt to create DrawTarget for invalid surface. Size(17895697,25) Cairo Status: 32[GFX1-]: Attempt to create DrawTarget for invalid surface. Size(17895697,25) Cairo Status: 32
Crash Annotation GraphicsCriticalError: |[0][GFX1-]: Attempt to create DrawTarget for invalid surface. Size(17895697,25) Cairo Status: 32|[1][GFX1-]: Failed to create DrawTarget, Type: 4 Size: Size(17895697,25), Data: 0x, Stride: 71582788|[2][GFX1-]: Failed GetAsDrawTarget true, 0x7fd87a0f2000 + 16, Size(17895697,25), 71582788, 0|[3][GFX1-]: Attempt to create DrawTarget for invalid surface. Size(17895697,25) Cairo Status: 32|[4][GFX1-]: Failed to create DrawTarget, Type: 4 Size: Size(17895697,25), Data: 0x, Stride: 71582788[GFX1-]: Failed to create DrawTarget, Type: 4 Size: Size(17895697,25), Data: 0x, Stride: 71582788
Crash Annotation GraphicsCriticalError: |[0][GFX1-]: Attempt to create DrawTarget for invalid surface. Size(17895697,25) Cairo Status: 32|[1][GFX1-]: Failed to create DrawTarget, Type: 4 Size: Size(17895697,25), Data: 0x, Stride: 71582788|[2][GFX1-]: Failed GetAsDrawTarget true, 0x7fd87a0f2000 + 16, Size(17895697,25), 71582788, 0|[3][GFX1-]: Attempt to create DrawTarget for invalid surface. Size(17895697,25) Cairo Status: 32|[4][GFX1-]: Failed to create DrawTarget, Type: 4 Size: Size(17895697,25), Data: 0x, Stride: 71582788|[5][GFX1-]: Failed GetAsDrawTarget true, 0x7fd87a0f2000 + 16, Size(17895697,25), 71582788, 0[GFX1-]: Failed GetAsDrawTarget true, 0x7fd87a0f2000 + 16, Size(17895697,25), 71582788, 0
Crash Annotation GraphicsCriticalError: |[0][GFX1-]: Attempt to create DrawTarget for invalid surface. Size(17895697,25) Cairo Status: 32|[6][GFX1-]: BorrowDrawTarget failure, original backend 4|[2][GFX1-]: Failed GetAsDrawTarget true, 0x7fd87a0f2000 + 16, Size(17895697,25), 71582788, 0|[3][GFX1-]: Attempt to create DrawTarget for invalid surface. Size(17895697,25) Cairo Status: 32|[4][GFX1-]: Failed to create DrawTarget, Type: 4 Size: Size(17895697,25), Data: 0x, Stride: 71582788|[5][GFX1-]: Failed GetAsDrawTarget true, 0x7fd87a0f2000 + 16, Size(17895697,25), 71582788, 0[GFX1-]: BorrowDrawTarget failure, original backend 4
Crash Annotation GraphicsCriticalError: |[0][GFX1-]: Attempt to create DrawTarget for invalid surface. Size(17895697,25) Cairo Status: 32|[6][GFX1-]: BorrowDrawTarget failure, original backend 4|[7][GFX1-]: Failed 2 buffer db=0x0 dw=0x0 for -3, -3, 17895697, 25|[3][GFX1-]: Attempt to create DrawTarget for invalid surface. Size(17895697,25) Cairo Status: 32|[4][GFX1-]: Failed to create DrawTarget, Type: 4 Size: Size(17895697,25), Data: 0x, Stride: 71582788|[5][GFX1-]: Failed GetAsDrawTarget true, 0x7fd87a0f2000 + 16, Size(17895697,25), 71582788, 0[GFX1-]: Failed 2 buffer db=0x0 dw=0x0 for -3, -3, 17895697, 25
ASAN:SIGSEGV
=================================================================
==11876==ERROR: AddressSanitizer: SEGV on unknown address 0x7fd8179ee000 (pc 0x7fd8fb4ad660 bp 0x7ffd8943c030 sp 0x7ffd8943b7b8 T0)
    #0 0x7fd8fb4ad65f in memset /build/buildd/eglibc-2.19/sysdeps/x86_64/memset.S:90
    #1 0x7fd9000cc855 in mozilla::layers::BufferTextureClient::AllocateForSurface(mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits>, mozilla::layers::TextureAllocationFlags) gfx/layers/client/TextureClient.cpp:868:5
    #2 0x7fd9000b59af in mozilla::layers::TextureClient::CreateForDrawing(mozilla::layers::CompositableForwarder*, mozilla::gfx::SurfaceFormat, mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits>, mozilla::layers::BackendSelector, mozilla::layers::TextureFlags, mozilla::layers::TextureAllocationFlags) gfx/layers/client/TextureClient.cpp:479:8
    #3 0x7fd9000b8f07 in CreateTextureClientForDrawing gfx/layers/client/CompositableClient.cpp:214:10
    #4 0x7fd9000b8f07 in mozilla::layers::ContentClientRemoteBuffer::CreateBackBuffer(mozilla::gfx::IntRectTyped<mozilla::gfx::UnknownUnits> const&) gfx/layers/client/ContentClient.cpp:294
    #5 0x7fd9000b94c3 in BuildTextureClients gfx/layers/client/ContentClient.cpp:287:3
    #6 0x7fd9000b94c3 in mozilla::layers::ContentClientRemoteBuffer::CreateBuffer(gfxContentType, mozilla::gfx::IntRectTyped<mozilla::gfx::UnknownUnits> const&, unsigned int, RefPtr<mozilla::gfx::DrawTarget>*, RefPtr<mozilla::gfx::DrawTarget>*) gfx/layers/client/ContentClient.cpp:323
    #7 0x7fd8fffd7a18 in mozilla::layers::RotatedContentBuffer::BeginPaint(mozilla::layers::PaintedLayer*, unsigned int) gfx/layers/RotatedBuffer.cpp:670:5
    #8 0x7fd9000e5c81 in mozilla::layers::ContentClientRemoteBuffer::BeginPaintBuffer(mozilla::layers::PaintedLayer*, unsigned int) objdir-ff-asan/dist/include/mozilla/layers/ContentClient.h:218:12
    #9 0x7fd9000aa454 in mozilla::layers::ClientPaintedLayer::PaintThebes() gfx/layers/client/ClientPaintedLayer.cpp:65:5
    #10 0x7fd9000ab3bf in mozilla::layers::ClientPaintedLayer::RenderLayerWithReadback(mozilla::layers::ReadbackProcessor*) gfx/layers/client/ClientPaintedLayer.cpp:141:3
    #11 0x7fd9000ed9e4 in mozilla::layers::ClientContainerLayer::RenderLayer() gfx/layers/client/ClientContainerLayer.h:65:7
    #12 0x7fd9000ed9e4 in mozilla::layers::ClientContainerLayer::RenderLayer() gfx/layers/client/ClientContainerLayer.h:65:7
    #13 0x7fd9000a509d in mozilla::layers::ClientLayerManager::EndTransactionInternal(void (*)(mozilla::layers::PaintedLayer*, gfxContext*, mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const&, mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const&, mozilla::layers::DrawRegionClip, mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const&, void*), void*, mozilla::layers::LayerManager::EndTransactionFlags) gfx/layers/client/ClientLayerManager.cpp:281:3
    #14 0x7fd9000a567b in mozilla::layers::ClientLayerManager::EndTransaction(void (*)(mozilla::layers::PaintedLayer*, gfxContext*, mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const&, mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const&, mozilla::layers::DrawRegionClip, mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const&, void*), void*, mozilla::layers::LayerManager::EndTransactionFlags) gfx/layers/client/ClientLayerManager.cpp:324:3
    #15 0x7fd904945246 in nsDisplayList::PaintRoot(nsDisplayListBuilder*, nsRenderingContext*, unsigned int) layout/base/nsDisplayList.cpp:1701:3
    #16 0x7fd9049f784c in nsLayoutUtils::PaintFrame(nsRenderingContext*, nsIFrame*, nsRegion const&, unsigned int, unsigned int) layout/base/nsLayoutUtils.cpp:3441:5
    #17 0x7fd904a7b77b in PresShell::Paint(nsView*, nsRegion const&, unsigned int) layout/base/nsPresShell.cpp:6132:5
    #18 0x7fd9040763c5 in nsViewManager::ProcessPendingUpdatesPaint(nsIWidget*) view/nsViewManager.cpp:466:7
    #19 0x7fd90407539e in nsViewManager::ProcessPendingUpdatesForView(nsView*, bool) view/nsViewManager.cpp:397:9
    #20 0x7fd904782211 in nsRefreshDriver::Tick(long, mozilla::TimeStamp) layout/base/nsRefreshDriver.cpp:1733:5
    #21 0x7fd90478b62a in TickDriver layout/base/nsRefreshDriver.cpp:196:5
    #22 0x7fd90478b62a in mozilla::RefreshDriverTimer::Tick(long, mozilla::TimeStamp) layout/base/nsRefreshDriver.cpp:187
    #23 0x7fd90478d174 in mozilla::VsyncRefreshDriverTimer::RefreshDriverVsyncObserver::NotifyVsync(mozilla::TimeStamp) layout/base/nsRefreshDriver.cpp:343:9
    #24 0x7fd9050cf0e4 in mozilla::layout::VsyncChild::RecvNotify(mozilla::TimeStamp const&) layout/ipc/VsyncChild.cpp:63:5
    #25 0x7fd8ff11c260 in mozilla::layout::PVsyncChild::OnMessageReceived(IPC::Message const&) objdir-ff-asan/ipc/ipdl/PVsyncChild.cpp:220:20
    #26 0x7fd8fec73ebf in mozilla::ipc::PBackgroundChild::OnMessageReceived(IPC::Message const&) objdir-ff-asan/ipc/ipdl/PBackgroundChild.cpp:1555:16
    #27 0x7fd8febe2e9b in mozilla::ipc::MessageChannel::DispatchAsyncMessage(IPC::Message const&) ipc/glue/MessageChannel.cpp:1385:14
    #28 0x7fd8febe038c in mozilla::ipc::MessageChannel::DispatchMessage(IPC::Message const&) ipc/glue/MessageChannel.cpp:1305:17
    #29 0x7fd8febd2907 in mozilla::ipc::MessageChannel::OnMaybeDequeueOne() ipc/glue/MessageChannel.cpp:1276:5
    #30 0x7fd8feb55a6d in RunTask ipc/chromium/src/base/message_loop.cc:364:3
    #31 0x7fd8feb55a6d in MessageLoop::DeferOrRunPendingTask(MessageLoop::PendingTask const&) ipc/chromium/src/base/message_loop.cc:372
    #32 0x7fd8feb5673a in MessageLoop::DoWork() ipc/chromium/src/base/message_loop.cc:459:13
    #33 0x7fd8febea852 in mozilla::ipc::DoWorkRunnable::Run() ipc/glue/MessagePump.cpp:220:3
    #34 0x7fd8fe1f2145 in nsThread::ProcessNextEvent(bool, bool*) xpcom/threads/nsThread.cpp:964:7
    #35 0x7fd8fe27593c in NS_ProcessNextEvent(nsIThread*, bool) xpcom/glue/nsThreadUtils.cpp:297:10
    #36 0x7fd8febe9e6f in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) ipc/glue/MessagePump.cpp:127:5
    #37 0x7fd8feb546d1 in RunInternal ipc/chromium/src/base/message_loop.cc:234:3
    #38 0x7fd8feb546d1 in RunHandler ipc/chromium/src/base/message_loop.cc:227
    #39 0x7fd8feb546d1 in MessageLoop::Run() ipc/chromium/src/base/message_loop.cc:201
    #40 0x7fd9040d8acf in nsBaseAppShell::Run() widget/nsBaseAppShell.cpp:156:3
    #41 0x7fd906090383 in XRE_RunAppShell toolkit/xre/nsEmbedFunctions.cpp:787:12
    #42 0x7fd8feb546d1 in RunInternal ipc/chromium/src/base/message_loop.cc:234:3
    #43 0x7fd8feb546d1 in RunHandler ipc/chromium/src/base/message_loop.cc:227
    #44 0x7fd8feb546d1 in MessageLoop::Run() ipc/chromium/src/base/message_loop.cc:201
    #45 0x7fd90608f8a7 in XRE_InitChildProcess toolkit/xre/nsEmbedFunctions.cpp:623:7
    #46 0x4dbd14 in content_process_main(int, char**) ipc/contentproc/plugin-container.cpp:237:19
    #47 0x7fd8fb442ec4 in __libc_start_main /build/buildd/eglibc-2.19/csu/libc-start.c:287
Group: core-security → gfx-core-security
Keywords: sec-high
(Assignee)

Comment 1

4 years ago
I think that this causes an allocation that overflows the uint32 parameter aSize in BufferTextureClient::Allocate. That's pretty bad!

The obvious thing to do here is to go through all of the texture code related to allocation and make sure we use size_t everywhere, and also have a notion of "reasonable" texture size. I don't think even trying to allocate something that doesn't fit in 32 bits of address space will ever yield anything good.
Assignee: nobody → nical.bugzilla
(Assignee)

Comment 2

4 years ago
Actually, I spoke too fast. ImageDataSerializer::ComputeMinBufferSize prevents what I had in mind from happenig.
(Assignee)

Comment 3

3 years ago
This should be fixed by bug 1224254 which was uplifted all the way to beta (but not esr). The patch in that bug sets a limit on texture sizes which may remove some silly OOM situations, and the limit also prevents some integer overflows situations that weren't handled before.
Depends on: 1224254
Somebody should verify this, but I'll mark it fixed for now.
Status: NEW → RESOLVED
Last Resolved: 3 years ago
Resolution: --- → FIXED
Whiteboard: [fixed by bug 1224254]
(In reply to Nicolas Silva [:nical] from comment #3)
> fixed by bug 1224254 which was uplifted all the way to beta (but not esr).

Is there a reason to keep this fix out of ESR?
Flags: needinfo?(nical.bugzilla)
(Assignee)

Comment 6

3 years ago
(In reply to Daniel Veditz [:dveditz] from comment #5)
> (In reply to Nicolas Silva [:nical] from comment #3)
> > fixed by bug 1224254 which was uplifted all the way to beta (but not esr).
> 
> Is there a reason to keep this fix out of ESR?

Not really. I am not used to uplifting patches to ESR. I don't know if the security implication is critical enough to warrant it, I'll rebase the patch, post it here and we'll see if it gets approved (I assume it needs a security review as well).
Flags: needinfo?(nical.bugzilla)
(In reply to Nicolas Silva [:nical] from comment #6)
> Not really. I am not used to uplifting patches to ESR. I don't know if the
> security implication is critical enough to warrant it, I'll rebase the
> patch, post it here and we'll see if it gets approved

We try to backport everything that is sec-high or sec-critical to ESR, so that would be appropriate for this bug.

> (I assume it needs a security review as well).

The patch will not need sec-approval, because it has already landed on a branch (so the cat is out of the bag, so to speak).
(Assignee)

Comment 8

3 years ago
[Approval Request Comment]
User impact if declined: possible integer overflow and crashes when allocating textures of unreasonable sizes.
Fix Landed on Version: 43, 44, 45
Risk to taking this patch (and alternatives if risky): low, it has baked on central, aurora, beta for a while.
String or UUID changes made by this patch:
Attachment #8695229 - Flags: approval-mozilla-esr38?
Group: gfx-core-security → core-security-release
Reproduced the initial crash using old Asan Nightly build from 2015-11-08 on Ubuntu 14.04 64-bit, verified that the crash did not occur on latest Asan Nightly 45.0a1, latest Asan Developer Edition 44.0a2 and Firefox 43 beta 9 builds.
Another ESR38 nominated patch for a sec-high issue that needs to be approved and checked into to ESR38.
Flags: needinfo?(sledru)
Flags: needinfo?(lhenry)
Whiteboard: [fixed by bug 1224254] → [fixed by bug 1224254][adv-main43+]
Comment on attachment 8695229 [details] [diff] [review]
patch rebased on top of esr38

Taking it in ESR
Flags: needinfo?(sledru)
Flags: needinfo?(lhenry)
Attachment #8695229 - Flags: approval-mozilla-esr38? → approval-mozilla-esr38+
Alias: CVE-2015-7212
Whiteboard: [fixed by bug 1224254][adv-main43+] → [fixed by bug 1224254][adv-main43+][adv-esr38.5+]
Also verified fixed on Firefox 38.0.5 ESR using Ubuntu 14.04 64-bit.
Flags: sec-bounty?
Flags: sec-bounty? → sec-bounty+
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.