Closed Bug 659920 Opened 13 years ago Closed 13 years ago

Crash [@ JSString::isLinear()]

Categories

(Core :: JavaScript Engine, defect)

5 Branch
x86
All
defect
Not set
critical

Tracking

()

RESOLVED FIXED
Tracking Status
firefox5 - affected

People

(Reporter: bc, Unassigned)

References

()

Details

(Keywords: crash, reproducible, valgrind, Whiteboard: [sg:dupe 652438] null deref fixed by 652438)

Crash Data

Attachments

(7 files)

Attached file crash report
1. Firefox beta http://stuff.rebro.org/test.html
2. Crash

Operating system: Windows NT
                  6.1.7601 Service Pack 1
CPU: x86
     GenuineIntel family 6 model 44 stepping 2
     2 CPUs

Crash reason:  EXCEPTION_ACCESS_VIOLATION_READ
Crash address: 0x0

Thread 0 (crashed)
 0  mozjs.dll!JSString::isLinear() [jsstr.h : 288 + 0x3]
    eip = 0x71e9f88a   esp = 0x0033af78   ebp = 0x0033af7c   ebx = 0x04980080
    esi = 0x052fc7a0   edi = 0x049800d0   eax = 0x00000000   ecx = 0x00000000
    edx = 0x052fc7a0   efl = 0x00010246
    Found by: given as instruction pointer in context
 1  mozjs.dll!JSLinearString::chars() [jsstr.h : 412 + 0x7]
    eip = 0x71e9f83f   esp = 0x0033af84   ebp = 0x0033af88
    Found by: previous frame's frame pointer
 2  mozjs.dll!JSString::getCharsZ(JSContext *) [jsstr.h : 685 + 0x12]
    eip = 0x71ec75ba   esp = 0x0033af90   ebp = 0x0033af94
    Found by: previous frame's frame pointer
 3  mozjs.dll!JS_GetStringCharsZAndLength [jsapi.cpp : 5395 + 0xb]
    eip = 0x71ec766d   esp = 0x0033af9c   ebp = 0x0033afa8
    Found by: previous frame's frame pointer
 4  xul.dll!xpc_qsDOMString::xpc_qsDOMString(JSContext *,jsval_layout,jsval_layout *,xpc_qsBasicString<nsAString_internal,nsDependentString>::StringificationBehavior,xpc_qsBasicString<nsAString_internal,nsDependentString>::Stringificat
ionBehavior) [xpcquickstubs.cpp : 727 + 0x11]
    eip = 0x6dac2006   esp = 0x0033afb0   ebp = 0x0033afd4
    Found by: previous frame's frame pointer
 5  xul.dll!nsIDOMHTMLDocument_Write [dom_quickstubs.cpp : 17037 + 0x49]
    eip = 0x6db04f31   esp = 0x0033afdc   ebp = 0x0033b05c
    Found by: call frame info
 6  mozjs.dll!js::mjit::EnterMethodJIT(JSContext *,JSStackFrame *,void *,js::Value *) [MethodJIT.cpp : 683 + 0x14]
    eip = 0x7211767a   esp = 0x0033b0b4   ebp = 0x0033b0ac
    Found by: call frame info with scanning

Note same signature from 

http://eaea.sirdarckcat.net/firefox-memoryexhaust1.html
http://xgold-team-en-or.xooit.fr/index.php

Seen on Windows XP, Linux so far.
Aurora/Nightly(Linux 32bit) throws an mozalloc_handle_oom()

security sensitive since it appears these folks are searching for memory exploits.
> http://eaea.sirdarckcat.net/firefox-memoryexhaust1.html

wonder if we should ask sirdarckcat@gmail.com whats up here?  he's been part of the bounty program in the past.  he also has an account in bugzilla.
The crash is most confusing since it crashes at null *right* after a null check.  I tried to repro the JSString::isLinear() crash on Win7 with Nightly/Beta and all I get is the mozalloc_handle_oom-type aborts under the HTML5 parser.  There was a missing NULL-check bug in JSString::getCharsZ that was fixed a few months ago (after 4.0 and before 5.0), by any chance is this crash for an old nightly?  If you can repro the JSString::isLinear crash on a current Windows nightly/aurora/beta, could you post a link to the crash-stats crash?
This was with current betas. I couldn't reproduce with either Nightly or Aurora debug builds. The Win* crashes were from the automation which produced minidumps that reproduced the stack. Trying to reproduce these locally on WinXP I just get the oom stuff too. I was able to get Linux to crash in gdb with this stack though.

I'll try to reproduce with a "nightly" beta build and submit any crash reports I get.

If you don't have Linux, I can try to get it in gdb again and ping you. Let me know.
What is the bug? Is it that we are OOMing? Or is it that we are crashing somewhere other than the OOM abort handler?
I'm retarded; I should've checked hg.mozilla.org/releases/mozilla-beta first before assuming aforementioned bugfix was on beta.  Its clearly not: http://hg.mozilla.org/releases/mozilla-beta/file/eba2dce26189/js/src/jsstr.h#l682.

So that means that the fix will come with the next aurora->beta merge.  This is not exploitable (always NULL or 1 word offset from NULL) and apparently happens when the browser is already about to crash on OOM; should I land the fix to mozilla-beta or just wait for the next aurora merge?
I don't think they are going to do another aurora->beta merge until they are getting ready for Firefox 6. I guess it depends on if this should be in Firefox 5 or not. "They" are already testing us, so maybe it should.
bc: Please capture the remote testcases you found and attach to the bug in case they go away.

Since it's a simple fix and found on three separate sites we might as well land this in Fx5 -- maybe we'll take away a little BlackHat fun.

(In reply to comment #1)
> wonder if we should ask sirdarckcat@gmail.com whats up here?  he's been part
> of the bounty program in the past.  he also has an account in bugzilla.

Most likely he didn't have time to bother with an unexploitable crash.
Keywords: testcase-wanted
Comment 1 is private: false
Whiteboard: [sg:dupe 652438] null deref fixed by 652438
Attached file stuff.rebro.org test
Attached file sirdarckcat test
the xgold team's test is essentially

<!--
URL: http://h.ackack.net/
-->
<script>
var a=String.fromCharCode(60,115,99,114,105,112,116,62,118,97,114,32,97,61,34,60,109,97,114,113,117,101,101,62,97,34,59,119,104,105,108,101,40,49,41,123,97,61,97,43,97,59,100,111,99,117,109,101,110,116,46,119,114,105,116,101,40,97,41,5
9,125,60,47,115,99,114,105,112,116,62);
while(1){
a=a+a;
document.write(a);
}
</script>

where a decodes as "<script>var a=\"<marquee>a\";while(1){a=a+a;document.write(a);}</script>"

It appears h.ackack.net is a trio of Swedish IT security researchers.
Keywords: testcase-wanted
Note the automation just crashed win7 nightly at http://stuff.rebro.org/test.html again with a different stack which the breakpad exploitable tool flagged as a high exploitable crash.

Crash reason:  EXCEPTION_ACCESS_VIOLATION_READ
Crash address: 0x3e10000

Thread 0 (crashed)
 0  msvcr80d.dll + 0x3d53a
    eip = 0x7369d53a   esp = 0x0031b38c   ebp = 0x0031b394   ebx = 0x04a00080
    esi = 0x03e10000   edi = 0x4bcfbfe8   eax = 0x0b8874b8   ecx = 0x01e9dd2e
    edx = 0x00000000   efl = 0x00010202
    Found by: given as instruction pointer in context
 1  xul.dll!nsHtml5Parser::Parse(nsAString_internal const &,void *,nsACString_internal const &,int,nsDTDMode) [nsHtml5Parser.cpp : 302 + 0x28]
    eip = 0x6e2b1063   esp = 0x0031b39c   ebp = 0x0031b40c
    Found by: previous frame's frame pointer
Operating system: Linux
                  0.0.0 Linux 2.6.35.13-91.fc14.x86_64 #1 SMP Tue May 3 13:23:06 UTC 2011 x86_64
CPU: amd64
     family 6 model 44 stepping 2
     1 CPU

Crash reason:  SIGSEGV
Crash address: 0x0

Thread 0 (crashed)
 0  libxul.so!NS_CopyUnicodeToNative [nsNativeCharsetUtils.cpp : 869 + 0x9]
    rbx = 0x9090909090909090   r12 = 0x00007f61ef565262
    r13 = 0x00007f61ef32a718   r14 = 0x0000000001729ec0
    r15 = 0x000000000172d600   rip = 0x00007f61ef54cc15
    rsp = 0x00007fff8d656be8   rbp = 0x9090909090909090
    Found by: given as instruction pointer in context
 1  0x909090909090908f
    rbx = 0x9090909090909090   r12 = 0x00007f61ef565262
    r13 = 0x00007f61ef32a718   r14 = 0x0000000001729ec0
    r15 = 0x000000000172d600   rip = 0x9090909090909090
    rsp = 0x00007fff8d656bf0   rbp = 0x9090909090909090
    Found by: call frame info
Operating system: Linux
                  0.0.0 Linux 2.6.35.13-91.fc14.i686.PAE #1 SMP Tue May 3 13:29:55 UTC 2011 i686
CPU: x86
     GenuineIntel family 6 model 44 stepping 2
     1 CPU

Crash reason:  SIGSEGV
Crash address: 0x90909090

Thread 0 (crashed)
 0  libc-2.13.so + 0x7d526
    eip = 0x007ee526   esp = 0xbf91fae4   ebp = 0xbf91fb28   ebx = 0x001e8464
    esi = 0x01a85574   edi = 0x90909090   eax = 0x00000000   ecx = 0x00000010
    edx = 0x00000000   efl = 0x00010283
    Found by: given as instruction pointer in context
 1  libnspr4.so!dosprintf [prprf.c : 980 + 0x26]
    eip = 0x001bbaf2   esp = 0xbf91fb30   ebp = 0xbf91fca8
    Found by: previous frame's frame pointer
Operating system: Linux
                  0.0.0 Linux 2.6.35.13-91.fc14.x86_64 #1 SMP Tue May 3 13:23:06 UTC 2011 x86_64
CPU: amd64
     family 6 model 44 stepping 2
     1 CPU

Crash reason:  SIGSEGV
Crash address: 0x7f02c27a8e84

Thread 0 (crashed)
 0  libxul.so!utf16_to_isolatin1 [nsNativeCharsetUtils.cpp : 123 + 0xe]
    rbx = 0x00007fff97ec3dbc   r12 = 0x00007f026e72e242
    r13 = 0x00007f026e4fb2d8   r14 = 0x0000000001a05e50
    r15 = 0x0000000001a09580   rip = 0x00007f026e71525d
    rsp = 0x00007fff97ec2d10   rbp = 0x00007fff97ec2d10
    Found by: given as instruction pointer in context
 1  libxul.so!nsNativeCharsetConverter::UnicodeToNative [nsNativeCharsetUtils.cpp : 624 + 0x1a]
    rbx = 0x00007fff97ec3dbc   r12 = 0x00007f026e72e242
    r13 = 0x00007f026e4fb2d8   r14 = 0x0000000001a05e50
    r15 = 0x0000000001a09580   rip = 0x00007f026e71593a
    rsp = 0x00007fff97ec2d20   rbp = 0x00007fff97ec2d80
    Found by: call frame info
I don't have a currently working valgrind on Linux for Firefox, but if someone else can valgrind these urls it might be interesting to find what the memory issue these urls randomly tickle.
running the rebro url http://stuff.rebro.org/test.html with a 2G ram 32bit fedora vm and a nightly build I get

==24279== Conditional jump or move depends on uninitialised value(s)
==24279==    at 0x528EA4B: nsIDOMHTMLDocument_Write(JSContext*, unsigned int, jsval_layout*) (dom_quickstubs.cpp:17469)
==24279==    by 0x131C62C4: ???
==24279==    by 0x5FD25F9: js::mjit::EnterMethodJIT(JSContext*, js::StackFrame*, void*, js::Value*) (MethodJIT.cpp:686)
==24279==    by 0x5FD2724: CheckStackAndEnterMethodJIT(JSContext*, js::StackFrame*, void*) (MethodJIT.cpp:716)
==24279==    by 0x5FD2867: js::mjit::JaegerShotAtSafePoint(JSContext*, void*) (MethodJIT.cpp:743)
==24279==    by 0x60AD760: js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) (jsinterp.cpp:3483)
==24279==    by 0x5E6196A: js::RunScript(JSContext*, JSScript*, js::StackFrame*) (jsinterp.cpp:613)
==24279==    by 0x5E62BB3: js::Execute(JSContext*, JSObject&, JSScript*, js::StackFrame*, unsigned int, js::Value*) (jsinterp.cpp:974)
==24279==    by 0x5DCABD4: EvaluateUCScriptForPrincipalsCommon(JSContext*, JSObject*, JSPrincipals*, unsigned short const*, unsigned int, char const*, unsigned int, jsval_layout*, JSVersion) (jsapi.cpp:4973)
==24279==    by 0x5DCAC7F: JS_EvaluateUCScriptForPrincipalsVersion (jsapi.cpp:4989)
==24279==    by 0x4CE3FC9: nsJSContext::EvaluateString(nsAString_internal const&, void*, nsIPrincipal*, char const*, unsigned int, unsigned int, nsAString_internal*, int*) (nsJSEnvironment.cpp:1453)
==24279==    by 0x4A599AE: nsScriptLoader::EvaluateScript(nsScriptLoadRequest*, nsString const&) (nsScriptLoader.cpp:906)
==24279== 
==24279== Conditional jump or move depends on uninitialised value(s)
==24279==    at 0x4E885FA: nsHtml5Parser::Parse(nsAString_internal const&, void*, nsACString_internal const&, int, nsDTDMode) (nsHtml5Parser.cpp:277)
==24279==    by 0x4BE6D18: nsHTMLDocument::WriteCommon(JSContext*, nsAString_internal const&, int) (nsHTMLDocument.cpp:1942)
==24279==    by 0x4BE6DA4: nsHTMLDocument::Write(nsAString_internal const&, JSContext*) (nsHTMLDocument.cpp:1955)
==24279==    by 0x528EB49: nsIDOMHTMLDocument_Write(JSContext*, unsigned int, jsval_layout*) (dom_quickstubs.cpp:17484)
==24279==    by 0x131C62C4: ???
==24279==    by 0x5FD25F9: js::mjit::EnterMethodJIT(JSContext*, js::StackFrame*, void*, js::Value*) (MethodJIT.cpp:686)
==24279==    by 0x5FD2724: CheckStackAndEnterMethodJIT(JSContext*, js::StackFrame*, void*) (MethodJIT.cpp:716)
==24279==    by 0x5FD2867: js::mjit::JaegerShotAtSafePoint(JSContext*, void*) (MethodJIT.cpp:743)
==24279==    by 0x60AD760: js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) (jsinterp.cpp:3483)
==24279==    by 0x5E6196A: js::RunScript(JSContext*, JSScript*, js::StackFrame*) (jsinterp.cpp:613)
==24279==    by 0x5E62BB3: js::Execute(JSContext*, JSObject&, JSScript*, js::StackFrame*, unsigned int, js::Value*) (jsinterp.cpp:974)
==24279==    by 0x5DCABD4: EvaluateUCScriptForPrincipalsCommon(JSContext*, JSObject*, JSPrincipals*, unsigned short const*, unsigned int, char const*, unsigned int, jsval_layout*, JSVersion) (jsapi.cpp:4973)
==24279== 
==24279== Conditional jump or move depends on uninitialised value(s)
==24279==    at 0x4E8874E: nsHtml5Parser::Parse(nsAString_internal const&, void*, nsACString_internal const&, int, nsDTDMode) (nsHtml5Parser.cpp:294)
==24279==    by 0x4BE6D18: nsHTMLDocument::WriteCommon(JSContext*, nsAString_internal const&, int) (nsHTMLDocument.cpp:1942)
==24279==    by 0x4BE6DA4: nsHTMLDocument::Write(nsAString_internal const&, JSContext*) (nsHTMLDocument.cpp:1955)
==24279==    by 0x528EB49: nsIDOMHTMLDocument_Write(JSContext*, unsigned int, jsval_layout*) (dom_quickstubs.cpp:17484)
==24279==    by 0x131C62C4: ???
==24279==    by 0x5FD25F9: js::mjit::EnterMethodJIT(JSContext*, js::StackFrame*, void*, js::Value*) (MethodJIT.cpp:686)
==24279==    by 0x5FD2724: CheckStackAndEnterMethodJIT(JSContext*, js::StackFrame*, void*) (MethodJIT.cpp:716)
==24279==    by 0x5FD2867: js::mjit::JaegerShotAtSafePoint(JSContext*, void*) (MethodJIT.cpp:743)
==24279==    by 0x60AD760: js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) (jsinterp.cpp:3483)
==24279==    by 0x5E6196A: js::RunScript(JSContext*, JSScript*, js::StackFrame*) (jsinterp.cpp:613)
==24279==    by 0x5E62BB3: js::Execute(JSContext*, JSObject&, JSScript*, js::StackFrame*, unsigned int, js::Value*) (jsinterp.cpp:974)
==24279==    by 0x5DCABD4: EvaluateUCScriptForPrincipalsCommon(JSContext*, JSObject*, JSPrincipals*, unsigned short const*, unsigned int, char const*, unsigned int, jsval_layout*, JSVersion) (jsapi.cpp:4973)

I tried to add --track-origins=yes but it oom before it reported anything but these warnings are reproducible without the track origins. I'll try to bump the memory and also try 64bit.
Upping the memory on 32bit fedora didn't help. On 64bit fedora I got:

==27412== Thread 1:
==27412== Invalid read of size 8
==27412==    at 0x6FF23E3: js::MarkRangeConservatively(JSTracer*, unsigned long const*, unsigned long const*) (jsgc.cpp:808)
==27412==    by 0x6FF24A7: js::MarkThreadDataConservatively(JSTracer*, js::ThreadData*) (jsgc.cpp:825)
==27412==    by 0x6FF25DB: js::MarkConservativeStackRoots(JSTracer*) (jsgc.cpp:857)
==27412==    by 0x6FF4187: js::MarkRuntime(JSTracer*) (jsgc.cpp:1819)
==27412==    by 0x6FF5834: MarkAndSweep(JSContext*, JSCompartment*, JSGCInvocationKind, js::GCTimer&) (jsgc.cpp:2280)
==27412==    by 0x6FF64C1: GCCycle(JSContext*, JSCompartment*, JSGCInvocationKind, js::GCTimer&) (jsgc.cpp:2643)
==27412==    by 0x6FF67A9: js_GC(JSContext*, JSCompartment*, JSGCInvocationKind) (jsgc.cpp:2707)
==27412==    by 0x6F6869F: JS_CompartmentGC (jsapi.cpp:2606)
==27412==    by 0x6F686ED: JS_GC (jsapi.cpp:2613)
==27412==    by 0x6304EB3: nsXPConnect::Collect() (nsXPConnect.cpp:413)
==27412==    by 0x6304F0C: nsXPConnect::GarbageCollect() (nsXPConnect.cpp:421)
==27412==    by 0x5DBE5F0: nsJSContext::GarbageCollectNow() (nsJSEnvironment.cpp:3252)
==27412==  Address 0x7feff6d20 is not stack'd, malloc'd or (recently) free'd

see bug 626064
Keywords: valgrind
Crash Signature: [@ JSString::isLinear()]
Beta/5's train left long ago. For the most part this appears to have changed to an oom abort. See bug 652438. I can't reproduce this stack/crash on current Beta/8, Aurora/9, Nightly/10 though Beta/8, Aurora/9 on Windows 7 64bit running 32bit builds does crash [@ nsHtml5Parser::Parse(nsAString_internal const&, void*, nsACString_internal const&, int, nsDTDMode) ]. See bug 687744
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
Group: core-security
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: