Closed Bug 303433 Opened 20 years ago Closed 20 years ago

CVE-2005-4720 Firefox 1.0.6 segfaults on this malformed .html page

Categories

(Core :: Layout, defect)

1.7 Branch
x86
Linux
defect
Not set
critical

Tracking

()

RESOLVED FIXED

People

(Reporter: tommy, Unassigned)

References

Details

(Keywords: crash, verified1.8)

Attachments

(4 files)

User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6 Build Identifier: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6 When browsing to a malformed .html page, Firefox will segfault. Reproducible: Always Steps to Reproduce: 1.Browse to malformed page. 2. 3. Actual Results: program sefaults, creating a core file. Expected Results: parsed the page properly. not sure.
"malformed .html page" is pretty general. There are millions of them on the Web that we don't segfault on. Could you attach an example of the HTML that we do segfault on? (See "Create a New Attachment" above.)
Sorry, I thought I had attached it. Will the file be kept private? Also, since this is a security bug will I be eligable for the bug bounty program?
Attached file firefox-death.html
The following attached file will cause firefox 1.0.6 on linux to sefault. This file must be placed on a webserver in order to reproduce the crash.
It appears that this flaw is in fact exploitable. I was finally able to get a debug version of firefox working.
Component: General → Layout
Product: Firefox → Core
QA Contact: general → layout
Version: unspecified → Trunk
Version: Trunk → 1.7 Branch
Can someone host that attachment on a public web server in a way that allows anyone to run under a debugger and see what's going wrong? Confirming based on Tom's testimony and some correspondence with dveditz, which started with Tom's mail to security@mozilla.org last week (Dan is at OSCON this week, not sure where that correspondence left off). We need to diagnose this and make some decisions, pronto. /be
Status: UNCONFIRMED → NEW
Ever confirmed: true
(In reply to comment #2) > Sorry, I thought I had attached it. Will the file be kept private? Also, since > this is a security bug will I be eligable for the bug bounty program? Yes, and yes. We can use brute force to remove the attachment before making the bug world-readable. Dan Veditz remains your point of contact for this bug and any bounty issues, but while he's out of town I think we need others to help here. Did you run under a debugger and get a stack backtrace? If so, please attach it. /be
I have put the .html file up here: https://hak.us/firefox-death.html _PLEASE KEEP IT PRIVATE_ I have not disclosed this flaw to anyone else. Also, I am having problems getting firefox src to compile on my mandrake box. Once I get it working, Ill post the stack backtrace.
Attached file stdout/err log
My debug build of the AVIARY_1_0_1_20050124_BRANCH corresponding to 1.0.6 does not crash on that URL. Attached here is the stdout/err from my run. The result in the browser is: Not Found The requested URL /0 was not found on this server. Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request. /be
Here is what I get when I run it: Core was generated by `./firefox-bin'. Program terminated with signal 11, Segmentation fault. #0 0x409b447c in ?? () Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6 I am running the binary downloaded from the site. -- Tom
No crash for me either. Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6
Keywords: crash
Summary: Firefox 1.0.6 will segfault when browsing a malformed .html page → Firefox 1.0.6 segfaults on this malformed .html page, seems exploitable
(In reply to comment #10) > No crash for me either. > > Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.10) Gecko/20050716 > Firefox/1.0.6 Did you try hitting it from the webserver? It doesnt seem to work when just doing a File --> Open. Also, I noticed your running on Mac OS X. I have not tried it on Mac OS X. -- Tom
Blocks: Zalewski
tom: i don't suppose you could try: ./firefox -d -g `which valgrind` run (you'd need to install valgrind)
(In reply to comment #12) > tom: i don't suppose you could try: > > ./firefox -d -g `which valgrind` > run > > (you'd need to install valgrind) When doing this, firefox tries to launch the valgrind file?
./run-mozilla.sh -d -g `which valgrind` ./firefox-bin
i probably have -g and -d backwards, sorry. i've been using other os's lately...
(In reply to comment #15) > i probably have -g and -d backwards, sorry. i've been using other os's lately... [tommy@mandrake firefox-installer]$ ./run-mozilla.sh -d -g `which valgrind` ./firefox-bin valgrind: Missing --tool option Available tools: addrcheck cachegrind corecheck helgrind lackey massif memcheck none valgrind: Use --help for more information. ? Any other updates on this issue?
*sigh* ./run-mozilla.sh -g -d `which sh` then use valgrind --help to figure out how to properly pick the right tool i believe the one we want is memcheck so probably from the shell: valgrind --tool=memcheck ./firefox-bin
(In reply to comment #17) > *sigh* > > ./run-mozilla.sh -g -d `which sh` > > then use valgrind --help to figure out how to properly pick the right tool i > believe the one we want is memcheck > > so probably from the shell: > valgrind --tool=memcheck ./firefox-bin /me runs... No such luck... Is anyone else looking/working on this? Doesnt really seem to be a very big deal.
sorry, nothing bad happens for me on windows (i'm running under purify). and i don't have resources allocated to test under linux from work.
I've had no luck getting this to crash. Did you ever get a crash with a stacktrace? Does our official release crash? If so you could make sure Talkback is installed and just give us a talkback number. If you simplify the testcase does it still crash for you? Is it just one of the junk attributes that causes the problem, or do you need a combination to confuse Firefox. A stack trace or talkback report would quite probably point us at the problem attribute. In mail to security@mozilla.org you mention a crash on a windows version that looked like a null dereference. That was the most common result of the various mangler-style crashes we've seen, though there were one or two that were different and potentially exploitable. Is the linux crash also a null dereference?
(In reply to comment #20) > I've had no luck getting this to crash. Did you ever get a crash with a > stacktrace? Does our official release crash? If so you could make sure Talkback > is installed and just give us a talkback number. > > If you simplify the testcase does it still crash for you? Is it just one of the > junk attributes that causes the problem, or do you need a combination to confuse > Firefox. A stack trace or talkback report would quite probably point us at the > problem attribute. > > In mail to security@mozilla.org you mention a crash on a windows version that > looked like a null dereference. That was the most common result of the various > mangler-style crashes we've seen, though there were one or two that were > different and potentially exploitable. Is the linux crash also a null dereference? No, this Linux issue seems to be a format string. I am not 100% sure though. I find it amazing that _noone_ can get this to crash??~!~!? I am just running 1.0.6 linux version from the download site. Talkback is installed, but does not popup after the crash because the browser just dies.
Attachment 191611 [details] doesn't crash for me on Linux branch. Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.7.10) Gecko/20050715 Firefox/1.0.6 SUSE/1.0.6-4.1
Works for me as well on Linux build from AVIARY_1_0_1_20050124_BRANCH (plus my patch for bug 307259). No valgrind warnings other than the usual ones.
Er, sorry, that was a trunk build. But I don't see a crash or valgrind warnings with an aviary 1.0.1 branch build either.
I'm able to reproduce crash here on Mandriva cooker, with mozilla.org 1.0.6 tarball (and also with our own package). it is crashing gdk, with both gtk2.8 or gtk2.6 (well, it is not really gtk fault, window witdh is set to 33364810 :) : stack with gtk 2.8 : #0 0xb7a8c2d7 in IA__gdk_window_object_get_type () at gdkwindow.c:199 #1 0xb7aa97c8 in gdk_window_compute_parent_pos (window=0x8f0c910, parent_pos=0xbf6570a0) at gdkgeometry-x11.c:828 #2 0xb7aa8e88 in _gdk_window_move_resize_child (window=0x94945f8, x=0, y=0, width=33364810, height=150) at gdkgeometry-x11.c:613 #3 0xb7ab84fe in IA__gdk_window_resize (window=0x94945f8, width=33364810, height=150) at gdkwindow-x11.c:1740 #4 0x08216184 in nsReadingIterator<unsigned short>::advance () #5 0x08210f29 in nsReadingIterator<unsigned short>::advance () #6 0x0821495e in nsReadingIterator<unsigned short>::advance () #7 0x0839734e in nsPRUint32Key::Clone () #8 0x08399ac0 in nsPRUint32Key::Clone () #9 0x0839c044 in nsPRUint32Key::Clone () #10 0x0839681a in nsPRUint32Key::Clone () #11 0x082147a5 in nsReadingIterator<unsigned short>::advance () #12 0x08214737 in nsReadingIterator<unsigned short>::advance () crash with gtk 2.6 : Program received signal SIGSEGV, Segmentation fault. [Switching to Thread -1220467008 (LWP 4426)] 0xb75bbbff in free () from /lib/tls/libc.so.6 (gdb) bt #0 0xb75bbbff in free () from /lib/tls/libc.so.6 #1 0xb75bd6ef in malloc () from /lib/tls/libc.so.6 #2 0xb79f29d6 in IA__g_malloc (n_bytes=3077056640) at gmem.c:137 #3 0xb7b13676 in IA__gdk_region_rectangle (rectangle=0x933098c) at gdkregion-generic.c:146 #4 0xb7b2eca0 in gdk_window_clip_changed (window=0x944e428, old_clip=0x933098c, new_clip=0xbf388134) at gdkgeometry-x11.c:1080 #5 0xb7b2dc2d in _gdk_window_move_resize_child (window=0x944e428, x=0, y=0, width=33364830, height=150) at gdkgeometry-x11.c:505 #6 0xb7b3a288 in IA__gdk_window_resize (window=0x944e428, width=33364830, height=150) at gdkwindow-x11.c:1739 #7 0x08216184 in nsReadingIterator<unsigned short>::advance () #8 0x08210f29 in nsReadingIterator<unsigned short>::advance () #9 0x0821495e in nsReadingIterator<unsigned short>::advance () #10 0x0839734e in nsPRUint32Key::Clone () #11 0x08399ac0 in nsPRUint32Key::Clone () #12 0x0839c044 in nsPRUint32Key::Clone ()
OK, so I managed to reproduce this with a 1.0.6 Firefox opt Linux build. I can't reproduce with a debug build or even an opt -g build... In the build in which I did reproduce, I get an infinite recursion stack overflow with the following basic unit: #3357 0xb7ab4990 in nsWidget::DispatchEvent () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libwidget_gtk.so #3358 0xb7ab486d in nsWidget::DispatchWindowEvent () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libwidget_gtk.so #3359 0xb7ab39b4 in nsWidget::OnResize () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libwidget_gtk.so #3360 0xb7abbaf4 in nsWindow::Resize () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libwidget_gtk.so #3361 0xb6d020a9 in nsView::SetDimensions () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libgklayout.so #3362 0xb6d04eaa in nsViewManager::SetWindowDimensions () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libgklayout.so #3363 0xb6d07c0f in nsViewManager::DispatchEvent () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libgklayout.so #3364 0xb6d012be in HandleEvent () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libgklayout.so #3365 0xb7ab4990 in nsWidget::DispatchEvent () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libwidget_gtk.so
Though I just realized that might have been a GTK1 build... Let me do some more testing.
OK, with a GTK2 build I get basically the same thing: #29 0xb7ad32ec in nsCommonWidget::DispatchEvent () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libwidget_gtk2.so #30 0xb7ad32b1 in nsCommonWidget::DispatchResizeEvent () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libwidget_gtk2.so #31 0xb7ad3532 in nsCommonWidget::Resize () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libwidget_gtk2.so #32 0xb6d48361 in nsView::SetDimensions () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libgklayout.so #33 0xb6d4b162 in nsViewManager::SetWindowDimensions () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libgklayout.so #34 0xb6d4dec7 in nsViewManager::DispatchEvent () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libgklayout.so #35 0xb6d47576 in HandleEvent () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libgklayout.so #36 0xb7ad32ec in nsCommonWidget::DispatchEvent () from /home/bzbarsky/mozilla/1.0.6/obj-opt/dist/bin/components/libwidget_gtk2.so
OK, so I've managed to reproduce in a "-Os -g" build. Apparently just building completely without -Osomething makes the bug not happen... I see the same sort of infinite recursion: (gdb) frame 11 #11 0xb6dad556 in nsViewManager::SetWindowDimensions (this=0x82f8f60, aWidth=466924892, aHeight=2100) at ../../../mozilla/view/src/nsViewManager.h:361 361 mRootView->SetDimensions(newDim); (gdb) frame 18 #18 0xb6dad556 in nsViewManager::SetWindowDimensions (this=0x82f8f60, aWidth=466924878, aHeight=2100) at ../../../mozilla/view/src/nsViewManager.h:361 361 mRootView->SetDimensions(newDim);
So here's the problem, I think. The stack has: (gdb) frame 19 #19 0xb6d4c162 in nsViewManager::SetWindowDimensions (this=0x0, aWidth=466901708, aHeight=2100) at ../../../mozilla/view/src/nsViewManager.h:361 361 mRootView->SetDimensions(newDim); (gdb) frame 17 #17 0xb7ad4532 in nsCommonWidget::Resize (this=0xb533ea18, aWidth=33350123, aHeight=150, aRepaint=1) at ../../../../mozilla/widget/src/gtk2/nsCommonWidget.cpp:319 319 DispatchResizeEvent(rect, status); My p2t is 14. Note that 14 * 33350123 == 466901722 (not 466901708). So when the widget resizes and notifies the viewmanager, we end up back in nsView::SetDimensions with a new width, 14 twips bigger. Repeat ad infinitum. Now I did some tests, and 466901708 is quite definitely an integral multiple of 14, and the quotient is 33350122 (not 33350123). I'm not sure _why_ the optimizer is screwing us over here (again, without -O there is no crash). I tried writing a simple program that duplicates what we do here, which is (once you inline stuff): PRInt32((float(466901708) * 0.0714285746f) + 0.5f) but that gives me the right results even compiled with optimization enabled...
One two other things: 1) If all the crashes involved are stack overflow (and that's the only kind I've been able to reproduce), is this exploitable? 2) On trunk we explicitly don't resize the widget right then, so this issue can't arise.
The other possibility to consider, of course, is that we had an overflow that clobbered the stack...
We really need to at least sort out what's going on here for sure.
Flags: blocking1.7.13?
Flags: blocking-aviary1.0.8?
Attached file simplified test case
a more simplified test case.
Yeah. So in this case the iframe has width 33333333 and the t2p is 14 and we have: (gdb) p 33333333 * (float)(1/14.0) * (float)14 $44 = 33333334.490116104 And so forth. Note that casting is actually very important here. That is: (gdb) p (float)(33333333) * (float)(1/14.0) * (float)14 $47 = 33333333.49011606 because (gdb) p (float)(33333333) $48 = 33333332 Also note: (gdb) p 1/14.0 $49 = 0.071428571428571425 (gdb) p (float)(1/14.0) $51 = 0.0714285746 So the basic problems are: 1) 1/14 cannot be represented very well in a float; the error is on the order of 3 parts in 10^6. 2) 33333333 cannot be represented in a float either; it becomes 33333333 when cast.
When I compile this with 'g++ test.cpp' I get: 33350124 0 33350122 Real test: 33333334.000000 If I compile with 'g++ -O test.cpp' I get: 33350122 0 33350122 Real test: 33333334.000000 If I cast aTwips to double instead of float in NSTwipsToIntPixels, I get the 33350124 result no matter what. So this seems like an inlining issue of some sort. If I multiply by float(1/14.0) first (before multiplying by float(14.0)) I get 33333336.000000.
So summary: This is a stack overflow. I don't know whether those are exploitable in general or not; dveditz, jruderman would have to comment on that. There's no clear way to fix this given our use of equality testing here; even switching to floats all over wouldn't help. :(
Stack overflows are every researchers dream. ;-] Of course they are exploitable..
(In reply to comment #38) > Stack overflows are every researchers dream. ;-] Of course they are > exploitable.. You are confusing stack buffer overflows, which may be used to overwrite return addresses and direct control flow to code written by the attacker, with a stack overflow, which causes the OS to kill the entire process -- at which point no exploit is possible. /be
Right. This is not a buffer overflow. This is a "there are 700,000 function calls on the stack and the kernel kills the process the next time a function call is attempted" overflow.
Opening bug (which I actually meant to ask about doing a few days ago, but it dropped off my list of things to do).
Group: security
As others have said, this is not an exploitable bug. A stack overflow can either cause the system to get slow due to disk IO or to kill the process (depends on memory, VM, and how much the OS will allow a stack to grow before killing the process). The only systems where stack overflows are exploitable are ones without memory protection. This can occur in some small devices like a network processor or router with no MMU; that's not the case here.
Summary: Firefox 1.0.6 segfaults on this malformed .html page, seems exploitable → Firefox 1.0.6 segfaults on this malformed .html page
no crash for me on a firefox 1.5 beta 2 candidate build on windows. Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8b5) Gecko/20051004 Firefox/1.4.1 Can someone check a recent Mac build? Are others still seeing this on Linux?
On trunk this was almost certainly fixed by widget change caching.
No problem on Mac 1.5beta2
No problem on Linux 1.5beta2
I guess we should close this one out and mark fixed-1.5b2
>Additional Comment #45 From Boris Zbarsky 2005-10-06 19:59 PDT > >On trunk this was almost certainly fixed by widget change caching. this widget caching bug? -> https://bugzilla.mozilla.org/show_bug.cgi?id=238493
Yeah.
marking fixed
Status: NEW → RESOLVED
Closed: 20 years ago
Resolution: --- → FIXED
Keywords: fixed1.8
Which direction of duping ought we to have with bug 292279 which also reported <iframe width="33333333">, back in April?
*** Bug 292279 has been marked as a duplicate of this bug. ***
no crash in either testcase firefox 1.5 rc2 winxp/linux
Keywords: fixed1.8verified1.8
bz: should this really block 1.0.8? It's non-exploitable, fixed in recent builds, and the widget caching patch (bug 238493) might be a little more risk than we want in 1.0.x
> Which direction of duping ought we to have with bug 292279 which also reported > <iframe width="33333333">, back in April? Well I think it is clear I saw it first! So if there's a bounty I'd claim it ;) Otherwise it doesn't really matter too much. Steve --
(In reply to comment #56) > > Which direction of duping ought we to have with bug 292279 which also reported > > <iframe width="33333333">, back in April? > > Well I think it is clear I saw it first! So if there's a bounty I'd claim it > ;) Its all you buddy.. ;) hehe > > Otherwise it doesn't really matter too much. > > Steve > -- > Is there anything else I can help with? -- Tom
> bz: should this really block 1.0.8? Nope. I set that nomination flag back when we still didn't know what was going on here. We definitely do not want widget caching on the 1.7 branch.
Flags: blocking1.7.13?
Flags: blocking-aviary1.0.8?
Summary: Firefox 1.0.6 segfaults on this malformed .html page → CVE-2005-4720 Firefox 1.0.6 segfaults on this malformed .html page
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: