Closed
Bug 322215
Opened 19 years ago
Closed 19 years ago
CVE-2006-0297 integer overflow in nsSVGCairoSurface::Init and nsCanvasRenderingContext2D
Categories
(Core :: SVG, defect)
Tracking
()
RESOLVED
FIXED
People
(Reporter: guninski, Assigned: vlad)
Details
(Keywords: fixed1.8.0.1, fixed1.8.1, qawanted, Whiteboard: [sg:critical] need svg fix on branch; cairo fix landed)
Attachments
(3 files, 3 obsolete files)
669 bytes,
text/xml
|
Details | |
3.05 KB,
patch
|
dveditz
:
approval1.8.0.1+
dveditz
:
approval1.8.1+
|
Details | Diff | Splinter Review |
2.12 KB,
patch
|
dveditz
:
approval1.8.0.1+
dveditz
:
approval1.8.1+
|
Details | Diff | Splinter Review |
in nsSVGCairoSurface::Init
mData = new PRUint8[4*width*height];
this may overflow due to int too big.
potential exploit may be:
making a hole lower on the heap with as much memory above it, mData gets there
placing C objects in the upper heap, then a race from another thread
uses the fecked data. not sure though.
same construct:
nsCanvasRenderingContext2D.cpp
nsAutoArrayPtr<PRUint8> tmpBuf(new PRUint8[aSurfaceSize.width*aSurfaceSize.height*4]);
testcase to follow.
Reporter | ||
Comment 1•19 years ago
|
||
Reporter | ||
Comment 2•19 years ago
|
||
tested on latest trunk.
Updated•19 years ago
|
Flags: blocking1.9a1?
Flags: blocking1.8.1?
Flags: blocking1.8.0.1?
Flags: blocking-aviary1.0.8?
Whiteboard: [sg:critical?]
Comment 3•19 years ago
|
||
The code exists on the 1.8 branch, but I can only confirm the crash with the testcase on the trunk. One difference is the branch spits out a CSS error. The crash hits somewhat later, but appears to be while painting. Presumably you could trigger this code in another way on the branch.
fwiw I crash at linw 428 in nsSVGFilterFrame.cpp (FilterPaint method)
for (PRUint32 yy=0; yy<filterResY; yy++)
for (PRUint32 xx=0; xx<filterResX; xx++) {
--> alphaData[stride*yy + 4*xx] = 0;
with stride == 0x20004, yy=2, and xx=0x66ca (I think that's about 100K past the actual size of the buffer).
Assignee: nobody → vladimir
Summary: integer overflow in nsSVGCairoSurface::Init → integer overflow in nsSVGCairoSurface::Init and nsCanvasRenderingContext2D
Whiteboard: [sg:critical?] → [sg:critical]
Filters are a trunk-only thing, so that way of crashing it is out.
Ways to get into that code on the branch would be group opacity or <svg:image>.
Assignee | ||
Comment 5•19 years ago
|
||
Is there a known issue/crash with the nsCanvasRenderingContext2D tmpBuf usage? It seems correct, and the loops are bounded by the same variables that were used to create the buffer.
Comment 7•19 years ago
|
||
(In reply to comment #5)
> Is there a known issue/crash with the nsCanvasRenderingContext2D tmpBuf usage?
The code is wrong by inspection. How can I tickle that code to prove it crashes? (there may be limits elsewhere that weed out the bad values such as the ones in gfxImageFrame::Init() -- do those come into play with canvas?)
> the loops are bounded by the same variables that were
> used to create the buffer.
But the loop bounds don't overflow while the buffer creation does.
posit a width of 32052 and a height of 33500: the allocated buffer will be 704 bytes. Any loops bounded by 30K will stomp all over things.
Reporter | ||
Comment 8•19 years ago
|
||
+ if (tmp / height != width)
+ return NS_ERROR_FAILURE;
this seems to work in this case, but in the general case may lead to division by 0.
Assignee | ||
Comment 9•19 years ago
|
||
Patch for canvas; just doesn't allow width or height >= 0xffff. This is still pretty generous and could leave to OOM conditions, but those should be handled (barring throw-on-OOM vs. return NULL issues...)
Attachment #207538 -
Flags: review?(dveditz)
Comment 10•19 years ago
|
||
0xfffe * 0xfffe * 4 > 2^32. I think we need smaller limits are needed (assuming we use that approach).
Assignee | ||
Comment 11•19 years ago
|
||
Good point; how does 16k sound? Even that's pretty generous.
Comment 12•19 years ago
|
||
Comment on attachment 207538 [details] [diff] [review]
322215-canvas-size-check.patch
0x7fff would be a safe value using this approach, but r- on ffff
Attachment #207538 -
Flags: review?(dveditz) → review-
Assignee | ||
Comment 13•19 years ago
|
||
Drop the sizes down to 16k (I originally meant to do 32k even, not sure why I ended up at 64k.). This avoids all the *4 problems and is also at the upper bound of "sane size" anyway, since a 16kx16k rendering would require 1GB of memory...
Attachment #207538 -
Attachment is obsolete: true
Attachment #207544 -
Flags: review?(dveditz)
Assignee | ||
Updated•19 years ago
|
Attachment #207544 -
Flags: review?(dveditz)
Assignee | ||
Comment 14•19 years ago
|
||
Ok, this reuses the same code from http://lxr.mozilla.org/mozilla1.8/source/gfx/src/shared/gfxImageFrame.cpp#62 -- we really should pull this code out somewhere so that SVG, canvas, image frame, and whatever else can share it, but I have no idea where that common place should be (or if we even want to do that for 1.8.0.1, or just make it nice on the trunk).
Attachment #207544 -
Attachment is obsolete: true
Comment 15•19 years ago
|
||
Comment on attachment 207547 [details] [diff] [review]
reuse code from image frame for canvas size check
r=dveditz
Attachment #207547 -
Flags: review+
Attachment #207547 -
Flags: approval1.8.1?
Attachment #207547 -
Flags: approval1.8.0.1?
Reporter | ||
Comment 16•19 years ago
|
||
trying to allocate about 3GB terminates mozilla (though there is no overflow).
terminate called after throwing an instance of 'std::bad_alloc'
what(): St9bad_alloc
#3 0xb73c8049 in abort () from /lib/tls/libc.so.6
#4 0xb7579d67 in __gnu_cxx::__verbose_terminate_handler ()
from /usr/lib/libstdc++.so.6
#5 0xb75778f5 in __cxa_call_unexpected () from /usr/lib/libstdc++.so.6
#6 0xb7577932 in std::terminate () from /usr/lib/libstdc++.so.6
#7 0xb7577ab2 in __cxa_throw () from /usr/lib/libstdc++.so.6
#8 0xb7577d02 in operator new () from /usr/lib/libstdc++.so.6
#9 0xb7577dbd in operator new[] () from /usr/lib/libstdc++.so.6
#10 0x086e47d6 in nsSVGCairoSurface::Init (this=0x9616d30, width=1,
height=805306368)
Reporter | ||
Comment 17•19 years ago
|
||
nsSVGLibartBitmapAlpha::Init(nsIRenderingContext* ctx,
nsPresContext* presContext,
const nsRect & rect)
mTempLineStride = rect.width * 4; // i.e. 4-bytes per pixel (RGBA)
mTempLineStride = (mTempLineStride + 3) & ~0x3; // 32-bit align
tempSize = mTempLineStride * rect.height;
mTempBits = new PRUint8[tempSize];
if (!mTempBits) return NS_ERROR_OUT_OF_MEMORY;
i am not sure this is safe, but don't know how to trigger it.
Reporter | ||
Comment 18•19 years ago
|
||
mTempBits = new PRUint8[tempSize];
^^^^^^^^^^^^^^^ this may throw exception with gcc, i believe.
Comment 19•19 years ago
|
||
(In reply to comment #17)
> nsSVGLibartBitmapAlpha::Init(nsIRenderingContext* ctx,
> nsPresContext* presContext,
> const nsRect & rect)
The libart SVG backend is unbuilt, depreciated code.
Assignee | ||
Comment 20•19 years ago
|
||
(In reply to comment #18)
> mTempBits = new PRUint8[tempSize];
> ^^^^^^^^^^^^^^^ this may throw exception with gcc, i believe.
All of these allocations can (should?) be switched to PR_malloc, no?
Reporter | ||
Comment 21•19 years ago
|
||
> All of these allocations can (should?) be switched to PR_malloc, no?
>
probably to:
a=new(std::nothrow) char[1024*1024*1024*3];
don't know how portable is, though.
better limit numbers imho.
Comment 22•19 years ago
|
||
Attachment #207440 -
Attachment is obsolete: true
Attachment #207642 -
Flags: review?(dveditz)
Assignee | ||
Comment 23•19 years ago
|
||
Canvas patch checked in on trunk. (I noticed that gfxImage* and imagelib stuff uses new instead of PR_malloc, so I gave up on making the new->malloc changes in canvas.)
Reporter | ||
Comment 24•19 years ago
|
||
nsresult nsImageWin::Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,
nsMaskRequirements aMaskRequirements)
const PRInt32 k64KLimit = 0x0000FFFF;
if (aWidth > k64KLimit || aHeight > k64KLimit)
return NS_ERROR_FAILURE;
mImageBits = new unsigned char[mSizeImage];
this may also eventually overflow.
GTK image has lower checks.
Comment 25•19 years ago
|
||
cairo and svg aren't in 1.0.x
Flags: blocking1.9a1?
Flags: blocking1.9a1+
Flags: blocking1.8.1?
Flags: blocking1.8.1+
Flags: blocking1.8.0.1?
Flags: blocking1.8.0.1+
Flags: blocking-aviary1.0.8?
Flags: blocking-aviary1.0.8-
Assignee | ||
Comment 26•19 years ago
|
||
Ugh crap, I just landed the canvas bits on 1.8/1.8.0 along with the other two canvas bugs; thought I had approval for this bit as well. Let me know if I should back this canvas bit out.
Comment 27•19 years ago
|
||
(In reply to comment #24)
> nsresult nsImageWin::Init [...] may also eventually overflow.
> GTK image has lower checks.
all "@mozilla.org/gfx/image;1" including nsImageWin are instantiated from gfxImageFrame.cpp which has already checked the size for overflow first.
Almost all: I did find an extra use of nsImageWin from nsImageClipboard.cpp. It has its own problems so I've filed bug 322708 for the clipboard and nsImageWin issue.
This bug is already covering two independent instances of this construct, let's not add more because tracking fixes and QA gets cumbersome and more likely to miss one.
(In reply to comment #19)
> The libart SVG backend is unbuilt, depreciated code.
Can we "cvs rm" it so it doesn't clutter up these sorts of scans for problematic patterns?
Comment 28•19 years ago
|
||
Comment on attachment 207547 [details] [diff] [review]
reuse code from image frame for canvas size check
a=dveditz
Attachment #207547 -
Flags: approval1.8.1?
Attachment #207547 -
Flags: approval1.8.1+
Attachment #207547 -
Flags: approval1.8.0.1?
Attachment #207547 -
Flags: approval1.8.0.1+
Comment 29•19 years ago
|
||
Comment on attachment 207642 [details] [diff] [review]
same check for svg surface creation
>+ if (width <= 0 || height <= 0)
These can't be negative, but I guess it can't hurt in case someone later changes the types and forgets to update the checks.
r=dveditz
Attachment #207642 -
Flags: review?(dveditz)
Attachment #207642 -
Flags: review+
Attachment #207642 -
Flags: approval1.8.1?
Attachment #207642 -
Flags: approval1.8.0.1?
Reporter | ||
Comment 30•19 years ago
|
||
(In reply to comment #29)
> (From update of attachment 207642 [details] [diff] [review] [edit])
> >+ if (width <= 0 || height <= 0)
>
> These can't be negative, but I guess it can't hurt in case someone later
> changes the types and forgets to update the checks.
>
they cover the nonpositive (zero case) which may leave to div by 0.
sorry for filing several problems in one bug, but i wasn't sure they were reachable/exploitable, so basically it was request for comments.
Reporter | ||
Comment 31•19 years ago
|
||
(In reply to comment #27)
> all "@mozilla.org/gfx/image;1" including nsImageWin are instantiated from
> gfxImageFrame.cpp which has already checked the size for overflow first.
>
imho functions/methods should be as "self contained" as possible, i.e. making the necessary overflows checks because:
1. this makes analysis much easier (no need to check for all invokations)
2. prevents someone from introducing buggy code (missing checks) in the future
probably an exception may be very performance critical code.
> Almost all: I did find an extra use of nsImageWin from nsImageClipboard.cpp. It
> has its own problems so I've filed bug 322708 for the clipboard and nsImageWin
> issue.
>
dveditz: what is the correct way to determine all invocation of methods?
are you sure grep/lxr are sufficient?
> This bug is already covering two independent instances of this construct, let's
> not add more because tracking fixes and QA gets cumbersome and more likely to
> miss one.
>
> (In reply to comment #19)
> > The libart SVG backend is unbuilt, depreciated code.
>
> Can we "cvs rm" it so it doesn't clutter up these sorts of scans for
> problematic patterns?
agreed. or at least documenting dead code.
Comment 32•19 years ago
|
||
> dveditz: what is the correct way to determine all invocation of methods?
> are you sure grep/lxr are sufficient?
In all but the simple cases grep probably is *not* sufficient. There's direct C++ class use, CreateInstance/Service using the CID (probably a single macro) or using the contractids (sometimes used literally, sometimes multiple macros), use from javascript.
nsImageWin seems to be one of the simple cases.
Comment 33•19 years ago
|
||
SVG surface size test checked in on trunk.
Comment 34•19 years ago
|
||
Comment on attachment 207642 [details] [diff] [review]
same check for svg surface creation
a=dveditz, discussed in this morning's triage mtg.
Attachment #207642 -
Flags: approval1.8.1?
Attachment #207642 -
Flags: approval1.8.1+
Attachment #207642 -
Flags: approval1.8.0.1?
Attachment #207642 -
Flags: approval1.8.0.1+
Comment 35•19 years ago
|
||
Both parts of this bug are fixed on trunk, marking bug so.
tor: when you land the svg patch on the 1.8 and 1.8.0 branches please add the fixed1.8.1 and fixed1.8.0 keywords.
Status: NEW → RESOLVED
Closed: 19 years ago
Flags: blocking1.8.0.1+ → blocking1.8.0.1?
Keywords: qawanted
Resolution: --- → FIXED
Whiteboard: [sg:critical] → [sg:critical] need svg fix on branch; cairo fix landed
Updated•19 years ago
|
Flags: blocking1.8.0.1?
Flags: blocking1.8.0.1+
Flags: blocking-firefox2+
Updated•19 years ago
|
Component: General → SVG
Flags: review-
Flags: review+
Product: Firefox → Core
Comment 37•19 years ago
|
||
Moved bug from Firefox -> Core to get the right blocking flags back.
Flags: blocking1.8.1+
Flags: blocking1.7.13-
Flags: blocking-firefox2+
Comment 38•19 years ago
|
||
no crash on windows for firefox 1.5 20051111, 1.8.0.1, 1.8.1, 1.9a1 20060112
no crash on linux firefox 1.5 20051111, 1.8.0.1, 1.8.1, 1.9a1 20060112
since I couldn't reproduce the original crash on 1.5 20051111 i won't verify.
Flags: testcase?
Updated•19 years ago
|
Flags: testcase? → testcase+
Reporter | ||
Comment 39•19 years ago
|
||
the canvas stuff may be related to Bug 324005.
large width/height still crash branch, trunk seems to accept the canvas.
Reporter | ||
Comment 40•19 years ago
|
||
i mean 1.5.0.1rc1 crashes.
Updated•19 years ago
|
Summary: integer overflow in nsSVGCairoSurface::Init and nsCanvasRenderingContext2D → CVE-2006-0297 integer overflow in nsSVGCairoSurface::Init and nsCanvasRenderingContext2D
Reporter | ||
Comment 41•19 years ago
|
||
regarding CVE in the summary:
i consider mitre/CVE corporate/government's puppies and have low opinion of
them.
mitre's "Steven M. Christey" <coley@linus.mitre.org>
co-authored the "responsible disclosure draft rfc" which was
obviously a corporate plot and was ditched by even the IETF - check the
ietf archives for this corporate fiasco.
Updated•19 years ago
|
Group: security
![]() |
||
Comment 42•18 years ago
|
||
bclary, you marked this as in‑testsuite+ - can you tell me which test suite and which test covers this bug?
Comment 43•18 years ago
|
||
(In reply to comment #42)
> bclary, you marked this as in‑testsuite+ - can you tell me which test suite
> and which test covers this bug?
It was in an internal only suite that will not be continued forward.
Flags: in-testsuite+
Comment 44•16 years ago
|
||
crash test landed
http://hg.mozilla.org/mozilla-central/rev/a2f6d39a6184
Flags: in-testsuite+
You need to log in
before you can comment on or make changes to this bug.
Description
•