Closed Bug 303433 Opened 19 years ago Closed 19 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.
Tom Ferris has issued an advisory on this:
http://www.security-protocols.com/advisory/sp-x19-advisory.txt
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: 19 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: