Closed
Bug 873249
Opened 12 years ago
Closed 11 years ago
Use-after-free crash with linear gradients with Skia/GL
Categories
(Core :: Graphics: Canvas2D, defect)
Tracking
()
RESOLVED
WORKSFORME
Tracking | Status | |
---|---|---|
firefox22 | --- | disabled |
firefox23 | --- | disabled |
firefox24 | --- | disabled |
firefox25 | --- | disabled |
firefox-esr17 | --- | unaffected |
b2g18 | --- | unaffected |
People
(Reporter: bjacob, Assigned: gw280)
References
()
Details
(Keywords: crash, csectype-uaf, sec-critical)
Crash Data
STR:
1. using Linux x86-64
2. enable GL layers and Skia/GL
3. reload a few times (less than 10 times) this page:
http://philip.html5.org/tests/canvas/suite/tests/framed.2d.gradient.interpolate.zerosize.html
Result: segfault with this stack:
(gdb) bt
#0 0x00007f02cc22e83d in nanosleep () at ../sysdeps/unix/syscall-template.S:82
#1 0x00007f02cc22e6dc in __sleep (seconds=0) at ../sysdeps/unix/sysv/linux/sleep.c:138
#2 0x00007f02c6a54b96 in ah_crap_handler (signum=11) at /hack/mozilla-central/toolkit/xre/nsSigHandlers.cpp:88
#3 0x00007f02c6a5f2f6 in nsProfileLock::FatalSignalHandler (signo=11, info=0x7fff49e6b830, context=0x7fff49e6b700) at /hack/mozilla-central/obj-firefox-debug-dmd/toolkit/profile/nsProfileLock.cpp:190
#4 <signal handler called>
#5 0x00007f02c92ac93e in GrTBinHashKey<AtlasEntry, 24ul>::compare (this=0x7f02a16f9908, key=...) at /hack/mozilla-central/gfx/skia/src/gpu/GrBinHashKey.h:74
#6 0x00007f02c92ab605 in AtlasEntry::compare (this=0x7f02a16f9908, key=...) at /hack/mozilla-central/gfx/skia/src/gpu/effects/GrTextureStripAtlas.cpp:32
#7 0x00007f02c92ad421 in GrTBinHashKey<AtlasEntry, 24ul>::LT (entry=..., key=...) at /hack/mozilla-central/gfx/skia/src/gpu/GrBinHashKey.h:85
#8 0x00007f02c92ad125 in GrTHashTable<AtlasEntry, GrTBinHashKey<AtlasEntry, 24ul>, 8ul>::searchArray (this=0x7f02cb7f1940, key=...) at /hack/mozilla-central/gfx/skia/src/gpu/GrTHashCache.h:88
#9 0x00007f02c92acb73 in GrTHashTable<AtlasEntry, GrTBinHashKey<AtlasEntry, 24ul>, 8ul>::insert (this=0x7f02cb7f1940, key=..., elem=0x7f02943c18f0) at /hack/mozilla-central/gfx/skia/src/gpu/GrTHashCache.h:130
#10 0x00007f02c92ab7a7 in GrTextureStripAtlas::GetAtlas (desc=...) at /hack/mozilla-central/gfx/skia/src/gpu/effects/GrTextureStripAtlas.cpp:49
#11 0x00007f02c921dff0 in GrGradientEffect::GrGradientEffect (this=0x7f029ceca038, ctx=0x7f02b30a65c0, shader=..., sampler=0x7fff49e6c190) at /hack/mozilla-central/gfx/skia/src/effects/gradients/SkGradientShader.cpp:751
#12 0x00007f02c92229e0 in GrLinearGradient::GrLinearGradient (this=0x7f029ceca038, ctx=0x7f02b30a65c0, shader=..., sampler=0x7fff49e6c190) at /hack/mozilla-central/gfx/skia/src/effects/gradients/SkLinearGradient.cpp:524
#13 0x00007f02c9222d72 in SkLinearGradient::asNewCustomStage (this=0x7f029b896a40, context=0x7f02b30a65c0, sampler=0x7fff49e6c190) at /hack/mozilla-central/gfx/skia/src/effects/gradients/SkLinearGradient.cpp:584
#14 0x00007f02c92a0e89 in (anonymous namespace)::skPaint2GrPaintShader (dev=0x7f02935b7520, skPaint=..., constantColor=true, textures=0x7fff49e6c280, grPaint=0x7fff49e6c120) at /hack/mozilla-central/gfx/skia/src/gpu/SkGpuDevice.cpp:597
#15 0x00007f02c92a18b2 in SkGpuDevice::drawRect (this=0x7f02935b7520, draw=..., rect=..., paint=...) at /hack/mozilla-central/gfx/skia/src/gpu/SkGpuDevice.cpp:782
#16 0x00007f02c91f9bf5 in SkCanvas::drawRect (this=0x7f0296959140, r=..., paint=...) at /hack/mozilla-central/gfx/skia/src/core/SkCanvas.cpp:1521
#17 0x00007f02c91ae784 in mozilla::gfx::DrawTargetSkia::FillRect (this=0x7f02935abcc0, aRect=..., aPattern=..., aOptions=...) at /hack/mozilla-central/gfx/2d/DrawTargetSkia.cpp:367
#18 0x00007f02c740ba6c in mozilla::dom::CanvasRenderingContext2D::FillRect (this=0x7f02948f6800, x=0, y=0, w=100, h=50) at /hack/mozilla-central/content/canvas/src/CanvasRenderingContext2D.cpp:1576
#19 0x00007f02c8621b7e in mozilla::dom::CanvasRenderingContext2DBinding::fillRect (cx=0x7f02a7e25400, obj=(JSObject * const) 0x7f0297938700 [object CanvasRenderingContext2D], self=0x7f02948f6800, argc=4, vp=0x7f02b6dfe168)
at /hack/mozilla-central/obj-firefox-debug-dmd/dom/bindings/CanvasRenderingContext2DBinding.cpp:1706
#20 0x00007f02c8627754 in mozilla::dom::CanvasRenderingContext2DBinding::genericMethod (cx=0x7f02a7e25400, argc=4, vp=0x7f02b6dfe168) at /hack/mozilla-central/obj-firefox-debug-dmd/dom/bindings/CanvasRenderingContext2DBinding.cpp:4153
#21 0x00007f02c9740490 in js::CallJSNative (cx=0x7f02a7e25400, native=0x7f02c862758e <mozilla::dom::CanvasRenderingContext2DBinding::genericMethod(JSContext*, unsigned int, JS::Value*)>, args=...) at /hack/mozilla-central/js/src/jscntxtinlines.h:337
#22 0x00007f02c974a3ee in js::Invoke (cx=0x7f02a7e25400, args=..., construct=js::NO_CONSTRUCT) at /hack/mozilla-central/js/src/jsinterp.cpp:426
#23 0x00007f02c9752116 in js::Interpret (cx=0x7f02a7e25400, entryFrame=0x7f02b6dfe050, interpMode=js::JSINTERP_NORMAL, useNewType=false) at /hack/mozilla-central/js/src/jsinterp.cpp:2393
#24 0x00007f02c9749f9d in js::RunScript (cx=0x7f02a7e25400, fp=0x7f02b6dfe050) at /hack/mozilla-central/js/src/jsinterp.cpp:383
#25 0x00007f02c974a4c4 in js::Invoke (cx=0x7f02a7e25400, args=..., construct=js::NO_CONSTRUCT) at /hack/mozilla-central/js/src/jsinterp.cpp:440
#26 0x00007f02c974a7b7 in js::Invoke (cx=0x7f02a7e25400, thisv=..., fval=..., argc=1, argv=0x7fff49e6e250, rval=0x7fff49e6e1c0) at /hack/mozilla-central/js/src/jsinterp.cpp:473
#27 0x00007f02c9664f51 in JS_CallFunctionValue (cx=0x7f02a7e25400, objArg=(JSObject *) 0x7f02979384c0 [object Proxy], fval=$jsval((JSObject *) 0x7f029797d5c0 [object Function "window.onload"]), argc=1, argv=0x7fff49e6e250, rval=0x7fff49e6e1c0)
at /hack/mozilla-central/js/src/jsapi.cpp:5851
#28 0x00007f02c868e99b in mozilla::dom::EventHandlerNonNull::Call (this=0x7f02941ff860, cx=0x7f02a7e25400, aThisObj=(JSObject * const) 0x7f02979384c0 [object Proxy], event=..., aRv=...)
at /hack/mozilla-central/obj-firefox-debug-dmd/dom/bindings/EventHandlerBinding.cpp:48
#29 0x00007f02c78d7196 in mozilla::dom::EventHandlerNonNull::Call<nsISupports*> (this=0x7f02941ff860, thisObj=@0x7f02942c33d8: 0x7f02956e4800, event=..., aRv=..., aExceptionHandling=mozilla::dom::CallbackObject::eReportExceptions)
at ../../../dist/include/mozilla/dom/EventHandlerBinding.h:58
#30 0x00007f02c78d6644 in nsJSEventListener::HandleEvent (this=0x7f02942c33c0, aEvent=0x7f02b3093160) at /hack/mozilla-central/dom/src/events/nsJSEventListener.cpp:247
#31 0x00007f02c74a1356 in nsEventListenerManager::HandleEventSubType (this=0x7f0294299680, aListenerStruct=0x7f02942996b8, aListener=..., aDOMEvent=0x7f02b3093160, aCurrentTarget=0x7f02956e4800, aPusher=0x7fff49e6e900)
at /hack/mozilla-central/content/events/src/nsEventListenerManager.cpp:922
#32 0x00007f02c74a161e in nsEventListenerManager::HandleEventInternal (this=0x7f0294299680, aPresContext=0x7f02965dc000, aEvent=0x7fff49e6ea10, aDOMEvent=0x7fff49e6e8e0, aCurrentTarget=0x7f02956e4800, aEventStatus=0x7fff49e6e8e8, aPusher=0x7fff49e6e900)
at /hack/mozilla-central/content/events/src/nsEventListenerManager.cpp:993
#33 0x00007f02c74d4fba in nsEventListenerManager::HandleEvent (this=0x7f0294299680, aPresContext=0x7f02965dc000, aEvent=0x7fff49e6ea10, aDOMEvent=0x7fff49e6e8e0, aCurrentTarget=0x7f02956e4800, aEventStatus=0x7fff49e6e8e8, aPusher=0x7fff49e6e900)
at /hack/mozilla-central/content/events/src/nsEventListenerManager.h:327
#34 0x00007f02c74d5583 in nsEventTargetChainItem::HandleEvent (this=0x7f02a7a61100, aVisitor=..., aMayHaveNewListenerManagers=false, aPusher=0x7fff49e6e900) at /hack/mozilla-central/content/events/src/nsEventDispatcher.cpp:202
#35 0x00007f02c74d5a47 in nsEventTargetChainItem::HandleEventTargetChain (this=0x7f02a3da3640, aVisitor=..., aCallback=0x0, aMayHaveNewListenerManagers=false, aPusher=0x7fff49e6e900) at /hack/mozilla-central/content/events/src/nsEventDispatcher.cpp:328
#36 0x00007f02c74d6bf8 in nsEventDispatcher::Dispatch (aTarget=0x7f02a7ca2c18, aPresContext=0x7f02965dc000, aEvent=0x7fff49e6ea10, aDOMEvent=0x0, aEventStatus=0x7fff49e6eab4, aCallback=0x0, aTargets=0x0)
at /hack/mozilla-central/content/events/src/nsEventDispatcher.cpp:634
#37 0x00007f02c6f23817 in nsDocumentViewer::LoadComplete (this=0x7f029ed0b860, aStatus=NS_OK) at /hack/mozilla-central/layout/base/nsDocumentViewer.cpp:1036
#38 0x00007f02c7e758c8 in nsDocShell::EndPageLoad (this=0x7f02a7ca2400, aProgress=0x7f02a7ca2428, aChannel=0x7f02965d9858, aStatus=NS_OK) at /hack/mozilla-central/docshell/base/nsDocShell.cpp:6610
#39 0x00007f02c7e74be9 in nsDocShell::OnStateChange (this=0x7f02a7ca2400, aProgress=0x7f02a7ca2428, aRequest=0x7f02965d9858, aStateFlags=131088, aStatus=NS_OK) at /hack/mozilla-central/docshell/base/nsDocShell.cpp:6407
#40 0x00007f02c7ea705d in nsDocLoader::DoFireOnStateChange (this=0x7f02a7ca2400, aProgress=0x7f02a7ca2428, aRequest=0x7f02965d9858, aStateFlags=@0x7fff49e6f124: 131088, aStatus=NS_OK) at /hack/mozilla-central/uriloader/base/nsDocLoader.cpp:1323
#41 0x00007f02c7ea59ce in nsDocLoader::doStopDocumentLoad (this=0x7f02a7ca2400, request=0x7f02965d9858, aStatus=NS_OK) at /hack/mozilla-central/uriloader/base/nsDocLoader.cpp:865
#42 0x00007f02c7ea5527 in nsDocLoader::DocLoaderIsEmpty (this=0x7f02a7ca2400, aFlushLayout=true) at /hack/mozilla-central/uriloader/base/nsDocLoader.cpp:755
#43 0x00007f02c7ea5021 in nsDocLoader::OnStopRequest (this=0x7f02a7ca2400, aRequest=0x7f02b3093cc0, aCtxt=0x0, aStatus=NS_OK) at /hack/mozilla-central/uriloader/base/nsDocLoader.cpp:639
#44 0x00007f02c6b1668b in nsLoadGroup::RemoveRequest (this=0x7f02a7fc1b50, request=0x7f02b3093cc0, ctxt=0x0, aStatus=NS_OK) at /hack/mozilla-central/netwerk/base/src/nsLoadGroup.cpp:684
#45 0x00007f02c6e5d010 in imgRequestProxy::RemoveFromLoadGroup (this=0x7f02b3093cc0, releaseLoadGroup=true) at /hack/mozilla-central/image/src/imgRequestProxy.cpp:260
#46 0x00007f02c6e5e9cd in imgRequestProxy::OnStopRequest (this=0x7f02b3093cc0, lastPart=true) at /hack/mozilla-central/image/src/imgRequestProxy.cpp:829
#47 0x00007f02c6e64091 in imgStatusTracker::SyncNotifyState (proxies=..., hasImage=true, state=63, dirtyRect=..., hadLastPart=true) at /hack/mozilla-central/image/src/imgStatusTracker.cpp:518
#48 0x00007f02c6e648dc in imgStatusTracker::SyncNotify (this=0x7f02a39e8ce0, proxy=0x7f02b3093cc0) at /hack/mozilla-central/image/src/imgStatusTracker.cpp:628
#49 0x00007f02c6e5f1d5 in imgRequestProxy::SyncNotifyListener (this=0x7f02b3093cc0) at /hack/mozilla-central/image/src/imgRequestProxy.cpp:963
#50 0x00007f02c6e50cbc in imgCacheValidator::OnStartRequest (this=0x7f0294299600, aRequest=0x7f02942b6858, ctxt=0x0) at /hack/mozilla-central/image/src/imgLoader.cpp:2180
#51 0x00007f02c6c494a1 in mozilla::net::nsHttpChannel::CallOnStartRequest (this=0x7f02942b6800) at /hack/mozilla-central/netwerk/protocol/http/nsHttpChannel.cpp:970
#52 0x00007f02c6c59eae in mozilla::net::nsHttpChannel::ContinueOnStartRequest3 (this=0x7f02942b6800, result=NS_OK) at /hack/mozilla-central/netwerk/protocol/http/nsHttpChannel.cpp:4965
#53 0x00007f02c6c59e77 in mozilla::net::nsHttpChannel::ContinueOnStartRequest2 (this=0x7f02942b6800, result=NS_OK) at /hack/mozilla-central/netwerk/protocol/http/nsHttpChannel.cpp:4956
#54 0x00007f02c6c59d46 in mozilla::net::nsHttpChannel::OnStartRequest (this=0x7f02942b6800, request=0x7f02941fde00, ctxt=0x0) at /hack/mozilla-central/netwerk/protocol/http/nsHttpChannel.cpp:4929
#55 0x00007f02c6b09296 in nsInputStreamPump::OnStateStart (this=0x7f02941fde00) at /hack/mozilla-central/netwerk/base/src/nsInputStreamPump.cpp:418
#56 0x00007f02c6b09029 in nsInputStreamPump::OnInputStreamReady (this=0x7f02941fde00, stream=0x7f029532ab78) at /hack/mozilla-central/netwerk/base/src/nsInputStreamPump.cpp:369
#57 0x00007f02c899d123 in nsInputStreamReadyEvent::Run (this=0x7f02941f18c0) at /hack/mozilla-central/xpcom/io/nsStreamUtils.cpp:82
#58 0x00007f02c89c1db7 in nsThread::ProcessNextEvent (this=0x7f02cbc5e4f0, mayWait=true, result=0x7fff49e6fd5f) at /hack/mozilla-central/xpcom/threads/nsThread.cpp:627
#59 0x00007f02c894e7f3 in NS_ProcessNextEvent (thread=0x7f02cbc5e4f0, mayWait=true) at /hack/mozilla-central/obj-firefox-debug-dmd/xpcom/build/nsThreadUtils.cpp:238
#60 0x00007f02c83ed7d7 in mozilla::ipc::MessagePump::Run (this=0x7f02cbc5d440, aDelegate=0x7f02cbe99560) at /hack/mozilla-central/ipc/glue/MessagePump.cpp:117
#61 0x00007f02c8a1ed65 in MessageLoop::RunInternal (this=0x7f02cbe99560) at /hack/mozilla-central/ipc/chromium/src/base/message_loop.cc:219
#62 0x00007f02c8a1ecf6 in MessageLoop::RunHandler (this=0x7f02cbe99560) at /hack/mozilla-central/ipc/chromium/src/base/message_loop.cc:212
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) frame 5
#5 0x00007f02c92ac93e in GrTBinHashKey<AtlasEntry, 24ul>::compare (this=0x7f02a16f9908, key=...) at /hack/mozilla-central/gfx/skia/src/gpu/GrBinHashKey.h:74
74 GrAssert(fIsValid && key.fIsValid);
(gdb) p this
$1 = (const GrTBinHashKey<AtlasEntry, 24ul> * const) 0x7f02a16f9908
(gdb) p *this
$2 = {fHash = 1515870810, fData = 'Z' <repeats 24 times>, fIsValid = 90}
(gdb) p/x 'Z'
$3 = 0x5a
(gdb) p/x 90
$4 = 0x5a
The gdb prints at the end above ^ show that the |this| pointer points to already free'd memory.
Reporter | ||
Comment 1•12 years ago
|
||
Note: I'm using a debug build; that probably helps a lot with reproducibility by filling free'd memory with 0x5a bytes.
Assignee | ||
Comment 2•12 years ago
|
||
ah_crap_handler, indeed.
Updated•12 years ago
|
Severity: normal → critical
Crash Signature: [@ GrTBinHashKey<AtlasEntry, 24ul>::compare(GrTBinHashKey&)]
Keywords: crash
Reporter | ||
Comment 3•12 years ago
|
||
Reproduced in Valgrind!
The first few reloads are fine. Then at about the 5th reload I get a bunch of 1-byte use-after-free's like this:
==17158== Invalid read of size 1
==17158== at 0x402EE40: bcmp (mc_replace_strmem.c:930)
==17158== by 0x85E3A6A: GrTBinHashKey<AtlasEntry, 24ul>::EQ(AtlasEntry const&, GrTBinHashKey<AtlasEntry, 24ul> const&) (GrBinHashKey.h:80)
==17158== by 0x85E3E97: GrTHashTable<AtlasEntry, GrTBinHashKey<AtlasEntry, 24ul>, 8ul>::searchArray(GrTBinHashKey<AtlasEntry, 24ul> const&) const (GrTHashCache.h:96)
==17158== by 0x85E4158: GrTHashTable<AtlasEntry, GrTBinHashKey<AtlasEntry, 24ul>, 8ul>::insert(GrTBinHashKey<AtlasEntry, 24ul> const&, AtlasEntry*) (GrTHashCache.h:130)
==17158== by 0x85E4426: GrTextureStripAtlas::GetAtlas(GrTextureStripAtlas::Desc const&) (GrTextureStripAtlas.cpp:49)
==17158== by 0x8584CDF: GrGradientEffect::GrGradientEffect(GrContext*, SkGradientShaderBase const&, GrSamplerState*) (SkGradientShader.cpp:751)
==17158== by 0x85879A1: GrLinearGradient::GrLinearGradient(GrContext*, SkLinearGradient const&, GrSamplerState*) (SkLinearGradient.cpp:524)
==17158== by 0x8587A5E: SkLinearGradient::asNewCustomStage(GrContext*, GrSamplerState*) const (SkLinearGradient.cpp:584)
==17158== by 0x85DC1E7: (anonymous namespace)::skPaint2GrPaintShader(SkGpuDevice*, SkPaint const&, bool, SkGpuDevice::SkAutoCachedTexture*, GrPaint*) (SkGpuDevice.cpp:597)
==17158== by 0x85DCF7D: SkGpuDevice::drawRect(SkDraw const&, SkRect const&, SkPaint const&) (SkGpuDevice.cpp:782)
==17158== by 0x856D0B4: SkCanvas::drawRect(SkRect const&, SkPaint const&) (SkCanvas.cpp:1521)
==17158== by 0x8539BAD: mozilla::gfx::DrawTargetSkia::FillRect(mozilla::gfx::Rect const&, mozilla::gfx::Pattern const&, mozilla::gfx::DrawOptions const&) (DrawTargetSkia.cpp:367)
==17158== Address 0x2dd2bfd5 is 165 bytes inside a block of size 240 free'd
==17158== at 0x402C787: realloc (vg_replace_malloc.c:663)
==17158== by 0x858CA53: sk_realloc_throw(void*, unsigned long) (SkMemory_malloc.cpp:27)
==17158== by 0x85E4203: SkTDArray<AtlasEntry>::growBy(unsigned long) (SkTDArray.h:332)
==17158== by 0x85E4295: SkTDArray<AtlasEntry>::append(unsigned long, AtlasEntry const*) (SkTDArray.h:162)
==17158== by 0x85E43D6: GrTextureStripAtlas::GetAtlas(GrTextureStripAtlas::Desc const&) (GrTextureStripAtlas.cpp:46)
==17158== by 0x8584CDF: GrGradientEffect::GrGradientEffect(GrContext*, SkGradientShaderBase const&, GrSamplerState*) (SkGradientShader.cpp:751)
==17158== by 0x85879A1: GrLinearGradient::GrLinearGradient(GrContext*, SkLinearGradient const&, GrSamplerState*) (SkLinearGradient.cpp:524)
==17158== by 0x8587A5E: SkLinearGradient::asNewCustomStage(GrContext*, GrSamplerState*) const (SkLinearGradient.cpp:584)
==17158== by 0x85DC1E7: (anonymous namespace)::skPaint2GrPaintShader(SkGpuDevice*, SkPaint const&, bool, SkGpuDevice::SkAutoCachedTexture*, GrPaint*) (SkGpuDevice.cpp:597)
==17158== by 0x85DCF7D: SkGpuDevice::drawRect(SkDraw const&, SkRect const&, SkPaint const&) (SkGpuDevice.cpp:782)
==17158== by 0x856D0B4: SkCanvas::drawRect(SkRect const&, SkPaint const&) (SkCanvas.cpp:1521)
==17158== by 0x8539BAD: mozilla::gfx::DrawTargetSkia::FillRect(mozilla::gfx::Rect const&, mozilla::gfx::Pattern const&, mozilla::gfx::DrawOptions const&) (DrawTargetSkia.cpp:367)
Then the next reload crashes with a failure of the assertion, the evaluation of which crashed in comment 0.
/hack/mozilla-central/gfx/skia/src/gpu/GrBinHashKey.h(74) : fIsValid && key.fIsValid failed
==17158== Invalid write of size 4
==17158== at 0x85E320F: GrTBinHashKey<AtlasEntry, 24ul>::compare(GrTBinHashKey<AtlasEntry, 24ul> const&) const (GrBinHashKey.h:74)
==17158== by 0x85E3E0D: GrTBinHashKey<AtlasEntry, 24ul>::LT(AtlasEntry const&, GrTBinHashKey<AtlasEntry, 24ul> const&) (GrBinHashKey.h:85)
==17158== by 0x85E3E71: GrTHashTable<AtlasEntry, GrTBinHashKey<AtlasEntry, 24ul>, 8ul>::searchArray(GrTBinHashKey<AtlasEntry, 24ul> const&) const (GrTHashCache.h:88)
==17158== by 0x85E3F99: GrTHashTable<AtlasEntry, GrTBinHashKey<AtlasEntry, 24ul>, 8ul>::find(GrTBinHashKey<AtlasEntry, 24ul> const&) const (GrTHashCache.h:117)
==17158== by 0x85E43BF: GrTextureStripAtlas::GetAtlas(GrTextureStripAtlas::Desc const&) (GrTextureStripAtlas.cpp:42)
==17158== by 0x8584CDF: GrGradientEffect::GrGradientEffect(GrContext*, SkGradientShaderBase const&, GrSamplerState*) (SkGradientShader.cpp:751)
==17158== by 0x85879A1: GrLinearGradient::GrLinearGradient(GrContext*, SkLinearGradient const&, GrSamplerState*) (SkLinearGradient.cpp:524)
==17158== by 0x8587A5E: SkLinearGradient::asNewCustomStage(GrContext*, GrSamplerState*) const (SkLinearGradient.cpp:584)
==17158== by 0x85DC1E7: (anonymous namespace)::skPaint2GrPaintShader(SkGpuDevice*, SkPaint const&, bool, SkGpuDevice::SkAutoCachedTexture*, GrPaint*) (SkGpuDevice.cpp:597)
==17158== by 0x85DCF7D: SkGpuDevice::drawRect(SkDraw const&, SkRect const&, SkPaint const&) (SkGpuDevice.cpp:782)
==17158== by 0x856D0B4: SkCanvas::drawRect(SkRect const&, SkPaint const&) (SkCanvas.cpp:1521)
==17158== by 0x8539BAD: mozilla::gfx::DrawTargetSkia::FillRect(mozilla::gfx::Rect const&, mozilla::gfx::Pattern const&, mozilla::gfx::DrawOptions const&) (DrawTargetSkia.cpp:367)
==17158== Address 0xffffffffbeefcafe is not stack'd, malloc'd or (recently) free'd
==17158==
Reporter | ||
Comment 4•12 years ago
|
||
So, this:
==17158== Address 0x2dd2bfd5 is 165 bytes inside a block of size 240 free'd
==17158== at 0x402C787: realloc (vg_replace_malloc.c:663)
==17158== by 0x858CA53: sk_realloc_throw(void*, unsigned long) (SkMemory_malloc.cpp:27)
==17158== by 0x85E4203: SkTDArray<AtlasEntry>::growBy(unsigned long) (SkTDArray.h:332)
==17158== by 0x85E4295: SkTDArray<AtlasEntry>::append(unsigned long, AtlasEntry const*) (SkTDArray.h:162)
Suggests a bug in Skia where they grow an array by reallocating it and don't update existing pointers pointing to the old array, so they go dangling.
Reporter | ||
Comment 5•12 years ago
|
||
OK, so here is the faulty code in Skia, in GrTextureStripAtlas.cpp:
GrTextureStripAtlas* GrTextureStripAtlas::GetAtlas(const GrTextureStripAtlas::Desc& desc) {
static SkTDArray<AtlasEntry> gAtlasEntries;
static GrTHashTable<AtlasEntry, AtlasHashKey, 8> gAtlasCache;
AtlasHashKey key;
key.setKeyData(desc.asKey());
AtlasEntry* entry = gAtlasCache.find(key);
if (NULL != entry) {
return entry->fAtlas;
} else {
entry = gAtlasEntries.push(); // <--- line 46
entry->fAtlas = SkNEW_ARGS(GrTextureStripAtlas, (desc));
entry->fKey = key;
gAtlasCache.insert(key, entry); // <--- line 49
return entry->fAtlas;
}
}
The Valgrind stacks in comment 3 show that the invalid read occurs at line 49, as the |entry| pointer is no longer valid; it became invalid as line 46 in a realloc().
So what's happening here --- skia's code here is nicely self-contained, kudos to that --- is that Skia wants to manage a bunch of AtlasEntry's in a hash table of raw pointers, |gAtlasCache|; the actual storage of the AtlasEntry's is in a separate array, |gAtlasEntries|.
As we push a new entry into the |gAtlasEntries| array at line 46, the array storage of |gAtlasEntries| gets reallocated; that causes all the AtlasEntry* raw pointers in |gAtlasCache| to become bad dangling pointers.
Reporter | ||
Comment 6•12 years ago
|
||
This code looks completely different in trunk Skia, and the anti pattern here of using a separate array and hash-table-of-raw-pointers for managing the Entry's is no longer apparently present:
http://code.google.com/p/skia/source/browse/trunk/src/gpu/effects/GrTextureStripAtlas.cpp#54
So this is fairly likely fixed in there... need to try with George's rebasing.
Reporter | ||
Comment 7•11 years ago
|
||
Yay, this is fixed by the rebasing to Skia r8495 from George's git tree. Is there a bug for that, that I can block this one on?
Reporter | ||
Comment 8•11 years ago
|
||
Should have flagged this sec-critical from the beginning --- this is a use-after-free with unclear implications.
Brad: I claim that this is by itself reason enough to rebase Skia before turning on Skia/GL anywhere. In addition to being a security bug, this also prevents completing a canvas 2d tests run in Valgrind.
Group: core-security
Keywords: sec-critical
Comment 9•11 years ago
|
||
:bjacob, for easier reproduction try to use a ASan build next time, it will provide you a precise stack for alloc, free and re-use.
Updated•11 years ago
|
Assignee: nobody → gwright
Comment 10•11 years ago
|
||
It looks like this is disabled everywhere.
status-b2g18:
--- → unaffected
status-firefox22:
--- → disabled
status-firefox23:
--- → disabled
status-firefox24:
--- → disabled
status-firefox-esr17:
--- → unaffected
Updated•11 years ago
|
status-firefox25:
--- → disabled
Comment 11•11 years ago
|
||
ASAN comes out clean for me with the latest Skia when this is enabled. At least on the OS X.
Comment 12•11 years ago
|
||
Marking works for me based on comment 7.
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → WORKSFORME
Updated•9 years ago
|
Group: core-security → core-security-release
Updated•8 years ago
|
Group: core-security-release
You need to log in
before you can comment on or make changes to this bug.
Description
•