Closed
Bug 1145965
Opened 11 years ago
Closed 11 years ago
Heap-buffer-overflow in nsSVGPathGeometryFrame, due to Ubuntu/Debian libxrender1 having been compiled with vulnerable version of libx11-dev
Categories
(Core :: SVG, defect)
Tracking
()
RESOLVED
DUPLICATE
of bug 803762
People
(Reporter: attekett, Unassigned)
References
Details
(Keywords: reporter-external, sec-vector, testcase)
Attachments
(3 files, 1 obsolete file)
Tested on:
OS: Ubuntu 14.04
Firefox: ASAN-build from https://ftp.mozilla.org/pub/mozilla.org/firefox/tinderbox-builds/mozilla-central-linux64-asan/1426899098/
Note: To reproduce the crash you have to open the repro-file in large enough window. Full screen worked for me on 1280x768 resolution.
Not 100% sure if this bug falls under SVG component, so feel free to change it.
ASAN-trace:
==7113==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x629000031200 at pc 0x461c8b bp 0x7fff68c672e0 sp 0x7fff68c672b0
WRITE of size 20 at 0x629000031200 thread T0 (Web Content)
#0 0x461c8a in memmove /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_interceptors.cc:349
#1 0x7fe004f69cb1 in memmove /usr/include/x86_64-linux-gnu/bits/string3.h:57
#2 0x7fe004f69cb1 in XRenderCompositeTrapezoids /build/buildd/libxrender-0.9.8/build/src/../../src/Trap.c:65
#3 0x7fe010171408 in _cairo_xlib_surface_composite_trapezoids /builds/slave/m-cen-l64-asan-000000000000000/build/src/gfx/cairo/cairo/src/cairo-xlib-surface.c:2984
#4 0x7fe01021f59a in _cairo_surface_composite_trapezoids /builds/slave/m-cen-l64-asan-000000000000000/build/src/gfx/cairo/cairo/src/cairo-surface.c:2396
#5 0x7fe01023e62a in _composite_traps_draw_func /builds/slave/m-cen-l64-asan-000000000000000/build/src/gfx/cairo/cairo/src/cairo-surface-fallback.c:561
#6 0x7fe010219ca9 in _clip_and_composite /builds/slave/m-cen-l64-asan-000000000000000/build/src/gfx/cairo/cairo/src/cairo-surface-fallback.c:472
#7 0x7fe010218fa8 in _clip_and_composite_trapezoids /builds/slave/m-cen-l64-asan-000000000000000/build/src/gfx/cairo/cairo/src/cairo-surface-fallback.c:875
#8 0x7fe01021b025 in _cairo_surface_fallback_stroke /builds/slave/m-cen-l64-asan-000000000000000/build/src/gfx/cairo/cairo/src/cairo-surface-fallback.c:1111
#9 0x7fe010221717 in _cairo_surface_stroke /builds/slave/m-cen-l64-asan-000000000000000/build/src/gfx/cairo/cairo/src/cairo-surface.c:2302
#10 0x7fe0101a075b in _cairo_gstate_stroke /builds/slave/m-cen-l64-asan-000000000000000/build/src/gfx/cairo/cairo/src/cairo-gstate.c:1166
#11 0x7fe01024321a in _moz_cairo_stroke_preserve /builds/slave/m-cen-l64-asan-000000000000000/build/src/gfx/cairo/cairo/src/cairo.c:2421
#12 0x7fe00a5928a2 in mozilla::gfx::DrawTargetCairo::DrawPattern(mozilla::gfx::Pattern const&, mozilla::gfx::StrokeOptions const&, mozilla::gfx::DrawOptions const&, mozilla::gfx::DrawTargetCairo::DrawPatternType, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/gfx/2d/DrawTargetCairo.cpp:912
#13 0x7fe00a597a19 in mozilla::gfx::DrawTargetCairo::Stroke(mozilla::gfx::Path const*, mozilla::gfx::Pattern const&, mozilla::gfx::StrokeOptions const&, mozilla::gfx::DrawOptions const&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/gfx/2d/DrawTargetCairo.cpp:1115
#14 0x7fe00ebec916 in nsSVGPathGeometryFrame::Render(gfxContext*, unsigned int, gfxMatrix const&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/svg/nsSVGPathGeometryFrame.cpp:806
#15 0x7fe00ebead9f in nsSVGPathGeometryFrame::PaintSVG(gfxContext&, gfxMatrix const&, nsIntRect const*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/svg/nsSVGPathGeometryFrame.cpp:261
#16 0x7fe00ebe9824 in nsDisplaySVGPathGeometry::Paint(nsDisplayListBuilder*, nsRenderingContext*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/svg/nsSVGPathGeometryFrame.cpp:114
#17 0x7fe00e54ffe7 in mozilla::FrameLayerBuilder::PaintItems(nsTArray<mozilla::FrameLayerBuilder::ClippedDisplayItem>&, nsIntRect const&, gfxContext*, nsRenderingContext*, nsDisplayListBuilder*, nsPresContext*, nsIntPoint const&, float, float, int) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/base/FrameLayerBuilder.cpp:4672
#18 0x7fe00e552e29 in mozilla::FrameLayerBuilder::DrawPaintedLayer(mozilla::layers::PaintedLayer*, gfxContext*, nsIntRegion const&, mozilla::layers::DrawRegionClip, nsIntRegion const&, void*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/base/FrameLayerBuilder.cpp:4869
#19 0x7fe00a7fd6c9 in mozilla::layers::BasicPaintedLayer::PaintThebes(gfxContext*, mozilla::layers::Layer*, void (*)(mozilla::layers::PaintedLayer*, gfxContext*, nsIntRegion const&, mozilla::layers::DrawRegionClip, nsIntRegion const&, void*), void*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/gfx/layers/basic/BasicPaintedLayer.cpp:94
#20 0x7fe00a7f9088 in mozilla::layers::BasicLayerManager::PaintSelfOrChildren(mozilla::layers::PaintLayerContext&, gfxContext*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/gfx/layers/basic/BasicLayerManager.cpp:802
.
.
.
Comment 1•11 years ago
|
||
Is this an SVG problem? the crash is happening down in Cairo code it looks like, the bug might be there instead.
A regression range would help point the finger if we can get one (and usually fuzz-found bugs aren't ancient or the fuzzer would likely have found it earlier).
Flags: needinfo?(dholbert)
Comment 2•11 years ago
|
||
I just got a clang-with-ASAN build environment up again (hadn't had one working for a little while), and I can confirm that I get the reported issue w/ the testcase, FWIW. I'll poke around & see what I can figure out.
Comment 3•11 years ago
|
||
Here's a somewhat-cleaned-up version of the testcase. (I tried pruning out bits of the paths, but any modifications I made to the actual path data seemed to prevent the issue from occurring. So, the paths are still quite long, in terms of number-of-commands.)
Flags: needinfo?(dholbert)
Comment 4•11 years ago
|
||
(note: if it's not clear, my 'reduced' testcase is larger (in KB) than the original because I added whitespace for readability/hand-editability.)
Comment 5•11 years ago
|
||
I'm poking around in GDB, though it's giving me two forms of trouble:
(1) when ASAN detects the buffer overflow & aborts, it does so in a way that GDB doesn't intercept. (so I have to break *just* before we abort)
and more painful:
(2) gdb says every variable value is <optimized out>, even though I built with --enable-debug --disable-optimize
If anyone knows a workaround for around either of those problems, I'd love to hear it. In the meantime, I'm doing some printf debugging to try to figure out variable values around the time that the overflow happens.
Comment 6•11 years ago
|
||
(In reply to Daniel Veditz [:dveditz] from comment #1)
> Is this an SVG problem? the crash is happening down in Cairo code it looks
> like, the bug might be there instead.
Hard to say. Could also be that we're passing bogus data into Cairo. (I'm trying to find out, but it's hard with gdb not cooperating, per comment 5.)
> A regression range would help point the finger if we can get one (and
> usually fuzz-found bugs aren't ancient or the fuzzer would likely have found
> it earlier).
Unfortunately, I can reproduce this in ASAN builds from at least as far back as Jan 2014 (when we were at version 29) -- I tried this one:
http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/2014/01/2014-01-02-03-02-03-mozilla-central/
So, not a recent regression.
Comment 7•11 years ago
|
||
I'm tempted to punt to jwatt or Bas, because they know the path-drawing / draw-target / cairo code better than I do, and they're more likely to know what variables might be useful to print out here... Starting with jwatt -- any chance you have cycles to look into this?
(I didn't discover anything useful in my printf debugging. My current theory is that we're drawing off the edge of the surface that's backing our draw-target, but I'm not sure how to test for that.)
Facts:
- The XRenderCompositeTrapezoids call (inside of which the issue happens) is here:
http://mxr.mozilla.org/mozilla-central/source/gfx/cairo/cairo/src/cairo-xlib-surface.c#2984
-It looks like the points it uses are encoded in "xtraps"
- num_traps is 6554
- render_src_x/y and attributes.x_offset/y_offset are all fairly tame -- (568, 36) and (0,0) respectively.
Flags: needinfo?(jwatt)
Comment 8•11 years ago
|
||
I've spent a lot of time trying to get a working ASAN build up and running on Mac, but after working through various build errors I'm now getting startup crashes due to bug 1146189.
Flags: needinfo?(jwatt)
Comment 9•11 years ago
|
||
https://developer.mozilla.org/en-US/docs/Mozilla/Testing/Firefox_and_Address_Sanitizer has known-good clang revisions -- r214699 should work on Mac, supposedly.
Comment 10•11 years ago
|
||
Yeah, that (and other revisions that I found in various bug comments that have previously worked for people) didn't work for me, which is why most recently I ended up trying the latest revision. I thought it best to at least post an update for now though.
I'll try again with a Linux build soon, but I need to get my Linux VM working again first.
Comment 11•11 years ago
|
||
Let's start with sec-critical for now. The crash is reliable and writing 20 bytes is more than enough to exploit. When we find out what the actual problem is we can downgrade the rating if we find out it's going somewhere safe enough or would require a race with another thread to exploit.
Keywords: sec-critical
Updated•11 years ago
|
status-firefox39:
--- → affected
status-firefox40:
--- → affected
Comment 12•11 years ago
|
||
By way of an update, I've got a local asan build going now, but haven't yet made much more progress than Daniel did. I'm away until Tuesday, but I'll get back on this then.
Comment 13•11 years ago
|
||
(In reply to Daniel Holbert [:dholbert] from comment #5)
> I'm poking around in GDB, though it's giving me two forms of trouble:
> (1) when ASAN detects the buffer overflow & aborts, it does so in a way
> that GDB doesn't intercept. (so I have to break *just* before we abort)
(gdb) br __asan_report_error
> (2) gdb says every variable value is <optimized out>, even though I built
> with --enable-debug --disable-optimize
Add "-mllvm -asan-stack-dynamic-alloca=1" to CFLAGS and CXXFLAGS
in your mozconfig file. (works in a stock clang 3.6 anyway)
Comment 14•11 years ago
|
||
BTW, if you rebuild and it fails because 'genrb' leaks memory, then just
copy that binary from one of your other builds into the asan build OBJDIR
and restart the build.
Comment 15•11 years ago
|
||
(In reply to Mats Palmgren (:mats) from comment #13)
> > (2) gdb says every variable value is <optimized out>, even though I built
> > with --enable-debug --disable-optimize
>
> Add "-mllvm -asan-stack-dynamic-alloca=1" to CFLAGS and CXXFLAGS
> in your mozconfig file. (works in a stock clang 3.6 anyway)
Thanks! But, darn -- that option is apparently not supported in the LLVM/clang snapshot that MDN recommends using[1] (revision 200213, which is version 3.5). Maybe I should try stock 3.6.
[1] https://developer.mozilla.org/en-US/docs/Mozilla/Testing/Firefox_and_Address_Sanitizer#Manual_Build
Comment 16•11 years ago
|
||
OK, I was able to build using stock clang 3.6 from http://llvm.org/apt/, and (with mats' second hint in comment 13) I am able to usefully poke around in GDB. I also grabbed the libxrender source, so I could step into XRenderCompositeTrapezoids (which we're inside when we crash).
Loading the original testcase, basically what happens is:
(1) XRenderCompositeTrapezoids gets called, with num_traps (last param) equal to 6554.
(NOTE: If I manually reduce the value in that arg to 6552, I get no issues; we don't take the "bigreq" codepath described below.)
(2) That initializes 'req' with this call:
GetReq(RenderTrapezoids, req);
which is a macro for:
req = _XGetRequest(dpy, X_RenderTrapezoids, sizeof(xRenderTrapezoidsReq);
Note that sizeof(xRenderTrapezoidsReq) is 24.
(3) Then we hit this call to the SetReqLen macro, with req->length = 6 and len = 65540:
SetReqLen (req, len, len);
(This is still in XRenderCompositeTrapezoids)
In my case right now, req is 0x6290000041e8
(3) SetReqLen (defined in /usr/include/X11/Xlibint.h) checks if the passed-in len is bigger than 65535 (it is), and calls another macro, "MakeBigReq".
(4) MakeBigReq ends up setting a local var _BRlen = 5, and then calling:
memmove(((char *)req) + 8, ((char *)req) + 4, (_BRlen - 1) << 2);
(5) ASAN catches a buffer overflow inside of this memmove call.
The memmove call *should* be a write of size 16, because "(_BRlen - 1) << 2" is 16. (Because _BRlen is 5.) This should be in-bounds, because sizeof(xRenderTrapezoidsReq) is 24, and we're writing 8 bytes into this object, and we're writing a total of 16 bytes, which should exactly hit the end of the object.
But for some reason ASAN calls this a "heap-buffer-overflow on address 0x629000004200 [...] WRITE of size 20 at 0x629000004200")
I don't know why memmove is writing 20 bytes (instead of 16), and why it's writing those bytes at 0x629000004200 (which is req + 24).
Comment 17•11 years ago
|
||
FWIW, _XGetRequest() impl gives us our "req" by grabbing some space off of its internal buffer, like this:
> req = (xReq*)dpy->bufptr;
> req->reqType = type;
> req->length = len / 4;
> dpy->bufptr += len;
> dpy->request++;
> return req;
After this point, dpy->bufptr == dpy->bufmax. (So the end of our 'req' object really is the end of the buffer that it's a part of.)
I'm still not clear how we end up doing a 20-byte write, though. Stepping through the assembly, it looks like we're skipping one of the "-1" subtractions for some reason. We're supposed to start with req->length, which is 6, and subtract 1 to produce "_BRlen", and then pass in "(_BRlen - 1) << 2)" to our memmove command (which is (5 - 1) << 2 = 4 << 2 = 16). But what I actually see in GDB is: we subtract 1 from 6 to produce 5 in register $rdx, and then we shift that left by 2 (producing 20), when we set up for our memmove call. If I tweak $rdx to have the value I expect right before memmove (16 instead of 20), then we complete memmove without any ASAN issues.
Bottom line, this seems almost certainly like a bug in XRenderCompositeTrapezoids (in libxrender), and/or in the MakeBigReq macro (in libx11) -- specifically, there seems to be an off-by-one in the assembly of the compiled binary. And the bug doesn't seem to be present in the source code (from "apt-get source" on the library).
Comment 18•11 years ago
|
||
Fun fact: If I build libXrender locally from source (provided by "apt-get source libxrender") and swap in the resulting libXrender.so.1.3.0 for my distro-provided file, I get *no ASAN issues*.
So: the default libXrender.so.1.3.0 is busted, but if you get the sources from apt and build it yourself, you get something functional. This seems suspicious/nefarious (my paranoia sense is tingling), but it could also conceivably just be a bug introduced by the particular compiler / compile options that were used on the packager's system...
(I'm currently using Ubuntu 15.04 beta, btw.)
Comment 19•11 years ago
|
||
As a sanity-check, I tested the precompiled ASAN build linked in comment 0, with my locally-compiled libXrender still swapped in (in /usr/lib/x86_64-linux-gnu), and I verified that I get no issues at all.
Updated•11 years ago
|
Summary: Heap-buffer-overflow in nsSVGPathGeometryFrame → Heap-buffer-overflow in nsSVGPathGeometryFrame (bug in libxrender binary?)
| Reporter | ||
Comment 20•11 years ago
|
||
There is also some crash with the repro-file and release stable Firefox 37.0 without ASAN on Ubuntu 14.04.
Interesting thing is that the crash doesn't occur when you open the repro-file, but when you try to close the browser after opening the repro-file.
Submitted crash report IDs:
bp-4ee63f02-d2fb-4583-b1b3-293a82150407
bp-6a9a96a8-e017-4de7-8ed6-a8c2c2150407
I tried it couple of times and reproducing is pretty simple. Open the repro-file ( https://bugzilla.mozilla.org/attachment.cgi?id=8581116 ) with Firefox and shutdown Firefox.
Note: If you have multiple tabs open closing the tab is not enough. I didn't try if you could reproduce the issue via JavaScript without closing down the browser, because ASAN-build shows that the BOF occurs even without additional tricks.
Comment 21•11 years ago
|
||
Here's fairly reduced source for a C++ program that triggers the same ASAN bug.
(There's a bit of a preamble at the beginning -- that's to fill up the display buffer, so that we exactly hit the end of the buffer inside of our final XRenderCompositeTrapezoids call.)
Compile w/ ASAN like so:
CXX=clang++-3.6
FLAGS="-Wall -fsanitize=address -mllvm -asan-stack-dynamic-alloca=1"
LIBS="-lXrender -lX11"
$CXX $FLAGS $LIBS xrender-bug-demo.cpp -o xrender-bug-demo
If I run the resulting binary, with my Ubuntu-provided /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0 file in place, then I hit the same ASAN error quoted in comment 0 here. (heap-buffer-overflow, write of size 20, 0 bytes to the right of 16384-byte region)
But if I copy my own locally-compiled libXrender.so.1.3.0 file into /usr/lib/x86_64-linux-gnu/, then I get no issues.
Comment 22•11 years ago
|
||
(Here's an executable that I compiled from the previous source file, for convenience / archival purposes.)
Comment 23•11 years ago
|
||
Comment on attachment 8582741 [details]
testcase 2 (partially reduced, makes tweak after 1 second)
(I'm obsoleting my "testcase 2", since I haven't had as much success reproducing with it, as compared to the original testcase.)
Attachment #8582741 -
Attachment is obsolete: true
Comment 24•11 years ago
|
||
(In reply to Atte Kettunen from comment #20)
> There is also some crash with the repro-file and release stable Firefox 37.0
> without ASAN on Ubuntu 14.04.
I can't reproduce this, but I'm willing to bet that it's caused by the same libXrender bug that ASAN is catching.
Comment 25•11 years ago
|
||
Has anyone reproduced this on a *non* Ubuntu linux system? Right now it looks like it's a mysterious bug in the compiled version of the libXrender .so on Ubuntu, which doesn't happen if you compile libXrender locally (per comment 18 and end of comment 21). I wonder if other Linux distros have the same bug, or if it's Ubuntu-specific (since the source code seems to be fine).
Comment 26•11 years ago
|
||
(In reply to Daniel Holbert [:dholbert] from comment #25)
> Has anyone reproduced this on a *non* Ubuntu linux system?
Answering my own question: I tested Debian 7.8.0 and a Fedora 21 Live environment, in VirtualBox. I tried the ASAN build from comment 0 with the original testcase here, and also my precompiled test C++ program.
Results:
- Debian 7.8.0 is affected. (I get the same ASAN errors as on Ubuntu.)
- Fedora 21 is not affected. (Testcase loads, test program runs, no ASAN warnings.)
Comment 27•11 years ago
|
||
Can we stick the libxrender source in the build tree and statically link to it until this bug is fixed?
Comment 28•11 years ago
|
||
(In reply to Robert Longson from comment #27)
> Can we stick the libxrender source in the build tree and statically link to
> it until this bug is fixed?
(I'm not sure.)
Still poking around, though, and I found something that gives me a theory about what's going on here:
- On Debian 7.8.0, I *can reproduce the bug* even with my own locally-built (on Debian) libxrender so file.
- I think this is because the "MakeBigReq" macro, defined in /usr/include/X11/Xlibint.h, is *older and buggy* on Debian. (And I think Ubuntu's libxrender package was compiled using that old buggy version.)
Here's Ubuntu 14.10 & 15.04's version of MakeBigReq, which is what I end up using when I build libxrender on Ubuntu (& can't reproduce the bug with my library):
(This is in Xlibint.h, from package libx11-dev, version 2:1.6.2-2ubuntu2)
> #ifdef LONG64
> #define MakeBigReq(req,n) \
> { \
> CARD64 _BRdat; \
> CARD32 _BRlen = req->length - 1; \
> req->length = 0; \
> _BRdat = ((CARD32 *)req)[_BRlen]; \
> memmove(((char *)req) + 8, ((char *)req) + 4, (_BRlen - 1) << 2); \
> ((CARD32 *)req)[1] = _BRlen + n + 2; \
> Data32(dpy, &_BRdat, 4); \
> }
Here's Debian 7.8.0's version of MakeBigReq, which is what I end up using when I build libxrender on Debian (& *can* reproduce the bug):
(This is in Xlibint.h, from package libx11-dev, version 2:1.5.0-1+deb7u1)
> #ifdef LONG64
> #define MakeBigReq(req,n) \
> { \
> printf("****dholbert MakeBigReq LONG64\n"); \
> CARD64 _BRdat; \
> CARD32 _BRlen = req->length - 1; \
> req->length = 0; \
> _BRdat = ((CARD32 *)req)[_BRlen]; \
> memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \
> ((CARD32 *)req)[1] = _BRlen + n + 2; \
> Data32(dpy, &_BRdat, 4); \
> }
Note that in Debian's version of the header, we just subtract 1 from req->length, and then shift left. Vs. on Ubuntu, there's a bonus subtraction in the call to memmove (which is what should save us from writing past the end of the array.) The Debian behavior seems to be consistent with what I observed when stepping through assembly on Ubuntu.
SO: my working theory is that Ubuntu's libxrender package was compiled with an *old* version of libx11-dev, which is why it's using a broken MakeBigReq macro with insufficient subtraction. But recompiling locally gets me an updated MakeBigReq macro, which saves me from the bug. (And Debian 7.8.0 is still using an old version of libxrender and libx11-dev, so even a local compile doesn't save you there.)
Comment 29•11 years ago
|
||
(Obviously I added the printf in debian's Xlibint.h file, to make sure I was looking at the right MakeBigReq definition. Forgot to take that out before copypasting here. :))
Comment 30•11 years ago
|
||
Aha! And git blame on the Xlibint.h file shows that the "memmove" line was last touched by karlt, and the commit message mentions bug 803762, which looks very similar to this bug.
Looks like there was some delay before karl's fix was incorporated, but it finally was (bug 803762 comment 19). But system libraries like libxrender apparently haven't been recompiled to incorporate the change.
Depends on: 803762
Comment 31•11 years ago
|
||
The X11 bug where karl fixed this is https://bugs.freedesktop.org/show_bug.cgi?id=56508 , FWIW.
karl, can you suggest what to do, to get packages like libxrender rebuilt & linux distros to ship security updates that incorporate your patch? It's frightening that Debian Stable still doesn't have your fix in its libx11-dev package... (and that Ubuntu has vulnerable libraries, despite having a fixed "dev" package)
Flags: needinfo?(karlt)
Comment 32•11 years ago
|
||
Daniel, I think you should just go ahead and file a security bug to Ubuntu
and explain the situation. I don't think they are aware that 56508 is
potentially exploitable. (It looks like Karl is away so he might not be
reading bug mail for another week.)
Comment 33•11 years ago
|
||
Yeah, I just noticed that karl's away. I'll go ahead & file Ubuntu & Debian bugs.
Comment 34•11 years ago
|
||
I filed https://bugs.launchpad.net/ubuntu/+source/libxrender/+bug/1441381 on Ubuntu (as a sec bug, so probably inaccessible to most/all folks here).
Updated•11 years ago
|
See Also: → https://launchpad.net/bugs/1441381
Comment 35•11 years ago
|
||
(In reply to Daniel Holbert [:dholbert] from comment #33)
> I'll go ahead & file Ubuntu & Debian bugs.
(Following up on this: I actually only filed an Ubuntu bug on Launchpad, and I CC'd some folks who've worked on the debian libxrender1 package. I opted not to file a separate Debian bug, since there's not a lot of Ubuntu/Debian-specific activity in this library that I can see. Debian also seems to want me to file bugs via email or via a command-line tool, which seems clumsy & makes it hard to know that the bug will stay secure & let me CC folks as I discover them. Debian also doesn't have much activity for this library in their bug tracker -- there are exactly 0 open bug reports: https://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=libxrender1 )
Flags: needinfo?(karlt)
Updated•11 years ago
|
Summary: Heap-buffer-overflow in nsSVGPathGeometryFrame (bug in libxrender binary?) → Heap-buffer-overflow in nsSVGPathGeometryFrame, due to Ubuntu/Debian libxrender1 having been compiled with vulnerable version of libx11-dev
Comment 36•11 years ago
|
||
If we're filing this with vendors, what are we doing with *this* bug? Can we put a check in place or something to stop this?
Comment 37•11 years ago
|
||
FYI, Ubuntu is pushing out fixed packages as we speak, so at least that distro
is probably going to fix it faster than we could do.
Comment 38•11 years ago
|
||
If we wanted to write a hackaround/check, I think the only thing we could do would be to wrap cairo's own calls into XRender functions with checks for "is our display buffer nearly full", and skip the operation if so. (or flush the buffer if possible? not sure if that's something cairo can do. That could be fragile also.)
I'm leaning against a hackaround, because:
- It could end up preventing harmless drawing (particularly on patched systems) and causing mis-rendering.
- The cairo code in question looks a bit hairy / delicate. (The _cairo_xlib_surface_composite_trapezoids function has lots of 'goto BAIL' -- which is probably what we'd use here -- and that rhymes with a recent scary apple security bug.)
- There are likely many places where we'd need to add this check, to comprehensively protect against this -- basically any of cairo's calls into an XRender function can trigger this, I think. An attacker just needs an almost-filled-up X "Display" buffer, and a properly-timed call to the SetReqLen() macro (inside xrender) with the right object-size to exactly fill up the buffer. XRenderCompositeTrapezoids is the function that was used for this in the attached testcase, but there are 12 other SetReqLen calls in libxrender (not in XRenderCompositeTrapezoids), many of which are probably exposed to cairo.
So given that this is difficult/fragile to safely/comprehensively hack around, and given that Ubuntu's users will be fixed soon, and that we can push to get Debian to fix as well (and any other distro that we happen to see is vulnerable): I think we should just let this be fixed by the library-update. There's a cost/benefit to trying to hack around system library vulnerabilities, and I don't think it makes sense in this case.
Comment 39•11 years ago
|
||
(Also: I did end up reaching out to Debian, using their security@debian.org email address & GPG key linked here: https://www.debian.org/security/faq#contact
I'll post updates here when I hear back from them.)
Comment 40•11 years ago
|
||
(I received a reply to my Debian email, saying "Thanks for the report! We'll make sure to release an update in timely manner.")
Comment 41•11 years ago
|
||
(Also, I've now tested Debian unstable, and it seems to be unaffected by this bug. They must've rebuilt their libxrender1 package recently enough.)
Comment 42•11 years ago
|
||
This is the same underlying bug as bug 803762 so I'm resolving it as
a duplicate. There's not much we can do here except reporting it
upstream and hope they deploy the fix properly this time. I agree
with Daniel's opinion (comment 38) that the cost/benefit of making
workarounds in our code wouldn't be worth it in this case.
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → DUPLICATE
Comment 43•11 years ago
|
||
(In reply to Mats Palmgren (:mats) from comment #42)
> This is the same underlying bug as bug 803762 so I'm resolving it as
> a duplicate.
This probably makes sense, though it's interesting that the original testcase there became WFM at some point without this actually being fixed. (That may have just been luck -- it's possible that a cairo or gfx patch may have changed things a bit, so that things happened in a slightly different order, so that the perfectly-calibrated testcase there no longer triggered the issue.)
One more distro-vulnerability data point: I tested the latest stable OpenSUSE (13.2) Live DVD, in VirtualBox, and verified that it's unaffected. (No ASAN error output at all, when running my minimal C++ program & when viewing the original testcase here in the ASAN firefox linked in comment 0.)
I also briefly tried Arch Linux, but it doesn't seem to give you a graphical desktop by default; and without having used it or its package-management system before [& not knowing how well it works in VirtualBox], I'm not going to spend time trying to get an Arch environment set up right now.
If anyone here happens to be able to test Arch Linux without too much trouble, it'd probably be worth doing, though.
Comment 44•11 years ago
|
||
(With OpenSUSE / Fedora / Ubuntu / Debian all tested & reported as-appropriate, I think we're at the point of diminishing returns for trying to test distros & report the vulnerability to them. Hopefully other distros are paying attention to their Xorg security updates and have already gotten this fix. And if they aren't, they're hopefully a small enough target to make them unattractive to attackers looking to exploit this.)
| Reporter | ||
Comment 45•11 years ago
|
||
From my point-of-view it doesn't seem fair, from bounty hunting perspective, to handle this as a Duplicate of bug that was resolved 2012 and as per comment 20 on bug 803762 the test case from that bug do not even reproduce the crash anymore.
I understand that the libXrender trunk has been fixed for this issue, and some distros have even shipped the fix, but since that fix you have been vulnerable to this issue for two years in major Linux distros, while thinking that the issue was fixed.
Comment 46•11 years ago
|
||
This is a duplicate because it's the exact same underlying issue as
bug 803762, which we already reported upstream and even provided
the fix for.
Whether this bug is eligible for a bounty is a separate discussion,
independent of the bug resolution. Note though that we didn't pay
a bounty in bug 803762, presumably because the bug was in a system
library that we used correctly. It might be eligible for a bounty
from the affected Linux distros though, in case they have a similar
program.
Updated•11 years ago
|
Flags: sec-bounty?
Comment 47•11 years ago
|
||
I got an email today from my Debian security contact, saying that wheezy (Debian stable, 7.8.0) has now shipped a fixed libxrender1 package. (And as noted in comment 41, Debian unstable is unaffected.)
Their announcement:
https://lists.debian.org/debian-security-announce/2015/msg00112.html
I tested locally & verified that, after installing updates, I got no ASAN error output from my C++ testcase, nor from ASAN Firefox with the original SVG testcase here.
Comment 48•11 years ago
|
||
Ubuntu stable releases received updates this morning, as well.
I've got the latest (non-beta) Ubuntu release "14.10 utopic" installed on my main development desktop. I installed the update there & re-tested my C++ testcase and ASAN Firefox w/ the SVG testcase here, and I got no ASAN error output.
Comment 49•11 years ago
|
||
So, summing up:
* the latest stable versions of all vulnerable linux distros that I'm aware of (Ubuntu & Debian stable releases) have now received security updates to address this.
* Ubuntu 15.04 beta also received an update, and Debian unstable was already unaffected.
* Ubuntu LTS (14.04) received an update as well; I haven't tested it, but I'll trust Ubuntu QA on that. (we may want to have our QA sanity-check as well)
* Latest Fedora & OpenSuse already had safe libxrender packages, based on my testing. (I wasn't able to reproduce any ASAN issues there.)
* I haven't tested other distros beyond those 4.
So, I think this is fixed everywhere -- or at least, I'm not aware of any linux distros that are still vulnerable to this.
Comment 50•11 years ago
|
||
I'm sorry we have to draw the line somewhere, but this is clearly an OS bug and not one in Firefox, and specifically in Ubuntu who didn't apply a patch we already supplied. Have to deny the bounty here.
Flags: sec-bounty? → sec-bounty-
Updated•10 years ago
|
Group: core-security → core-security-release
Updated•9 years ago
|
Group: core-security-release
Updated•2 years ago
|
Keywords: reporter-external
You need to log in
before you can comment on or make changes to this bug.
Description
•