Crash [@ JS_GetFunctionScript ] with setTimeout and XPCSafeJSObjectWrapper

RESOLVED FIXED

Status

()

Core
DOM
RESOLVED FIXED
9 years ago
6 years ago

People

(Reporter: Taral, Assigned: mrbkap)

Tracking

(5 keywords)

unspecified
x86
Windows XP
crash, regression, testcase, verified1.9.0.14, verified1.9.1
Points:
---
Bug Flags:
wanted1.9.1.x +
blocking1.9.0.14 +
wanted1.9.0.x +
wanted1.8.1.x -

Firefox Tracking Flags

(blocking1.9.1 .2+, status1.9.1 .2-fixed)

Details

(Whiteboard: [sg:investigate], crash signature, URL)

Attachments

(2 attachments)

(Reporter)

Description

9 years ago
User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9) Gecko/2008052906 Firefox/3.0
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9) Gecko/2008052906 Firefox/3.0

Based on the crash data, it looks like the calls to setTimeout are causing Firefox to crash.

Reproducible: Always

Steps to Reproduce:
1. Install Greasemonkey 0.8.20080609.0
2. Install script: http://taral.dreamhost.com/websudokuig.user.js
3. Visit http://www.websudoku.com/
4. Enable pencil marking in options
5. Hit the update button
Actual Results:  
Crash! http://crash-stats.mozilla.com/report/index/18026f7a-425b-11dd-b225-001cc45a2c28

Expected Results:  
Not crash

Comment 1

9 years ago
Created attachment 328109 [details]
testcase (crashes Firefox when loaded)

This does not require Greasemonkey.

Comment 2

9 years ago
This is a regression from bug 425139.

Due to the fix for bug 425139, setTimeout() treats an XPCSafeJSObjectWrapper
wrapping a function as a function.  But, nsJSContext::CallEventHandler does not
handle the XPCSafeJSObjectWrapper properly.


Breakpoint 1, nsJSContext::CallEventHandler (this=0xb0060240, 
    aTarget=0xb643e5c0, aScope=0xb5511e80, aHandler=0xb2c55f00, 
    aargv=0xafd3f644, arv=0xbf9e96bc) at nsJSEnvironment.cpp:1876
1876      NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
(gdb) p *(JSClass*)(((JSObject*)aHandler)->fslots[2]&~1)
$1 = {name = 0xb63aa6e0 "XPCSafeJSObjectWrapper", flags = 66820, 
  addProperty = 0xb6387a3e <XPC_SJOW_AddProperty>, 
  delProperty = 0xb63879c0 <XPC_SJOW_DelProperty>, 
  getProperty = 0xb6387776 <XPC_SJOW_GetProperty>, 
  setProperty = 0xb6387752 <XPC_SJOW_SetProperty>, 
  enumerate = 0xb638790e <XPC_SJOW_Enumerate>, 
  resolve = 0xb6387426 <XPC_SJOW_NewResolve>, 
  convert = 0xb6385fdc <XPC_SJOW_Convert>, 
  finalize = 0xb6386898 <XPC_SJOW_Finalize>, getObjectOps = 0, 
  checkAccess = 0xb6386068 <XPC_SJOW_CheckAccess>, 
  call = 0xb6387076 <XPC_SJOW_Call>, 
  construct = 0xb6387db4 <XPC_SJOW_Construct(JSContext*, JSObject*, unsigned int, long*, long*)>, xdrObject = 0, hasInstance = 0, mark = 0, reserveSlots = 0}
(gdb) n
1878      if (!mScriptsEnabled) {
(gdb) 
1883      JSObject* target = nsnull;
(gdb) 
1884      nsAutoGCRoot root(&target, &rv);
(gdb) 
1885      NS_ENSURE_SUCCESS(rv, rv);
(gdb) 
1886      rv = JSObjectFromInterface(aTarget, aScope, &target);
(gdb) 
1887      NS_ENSURE_SUCCESS(rv, rv);
(gdb) 
1889      jsval rval = JSVAL_VOID;
(gdb) 
1897        do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
(gdb) 
1898      if (NS_FAILED(rv) || NS_FAILED(stack->Push(mContext)))
(gdb) 
1902      rv = sSecurityManager->CheckFunctionAccess(mContext, aHandler, target);
(gdb) s
nsScriptSecurityManager::CheckFunctionAccess (this=0xb6dcf1a0, aCx=0xb067f0a0, 
    aFunObj=0xb2c55f00, aTargetObj=0xb5511e80)
    at nsScriptSecurityManager.cpp:1652
1652            GetFunctionObjectPrincipal(aCx, (JSObject *)aFunObj, nsnull, &rv);
(gdb) 
nsScriptSecurityManager::GetFunctionObjectPrincipal (cx=0xb067f0a0, 
    obj=0xb2c55f00, fp=0x0, rv=0xbf9e94c0) at nsScriptSecurityManager.cpp:2174
2174        NS_PRECONDITION(rv, "Null out param");
(gdb) 
2175        JSFunction *fun = (JSFunction *) caps_GetJSPrivate(obj);
(gdb) 
caps_GetJSPrivate (obj=0xb2c55f00) at nsScriptSecurityManager.cpp:138
138         JS_ASSERT(STOBJ_GET_CLASS(obj)->flags & JSCLASS_HAS_PRIVATE);
(gdb) p *(JSClass*)(obj->fslots[2]&~1)
$2 = {name = 0xb63aa6e0 "XPCSafeJSObjectWrapper", flags = 66820, 
  addProperty = 0xb6387a3e <XPC_SJOW_AddProperty>, 
  delProperty = 0xb63879c0 <XPC_SJOW_DelProperty>, 
  getProperty = 0xb6387776 <XPC_SJOW_GetProperty>, 
  setProperty = 0xb6387752 <XPC_SJOW_SetProperty>, 
  enumerate = 0xb638790e <XPC_SJOW_Enumerate>, 
  resolve = 0xb6387426 <XPC_SJOW_NewResolve>, 
  convert = 0xb6385fdc <XPC_SJOW_Convert>, 
  finalize = 0xb6386898 <XPC_SJOW_Finalize>, getObjectOps = 0, 
  checkAccess = 0xb6386068 <XPC_SJOW_CheckAccess>, 
  call = 0xb6387076 <XPC_SJOW_Call>, 
  construct = 0xb6387db4 <XPC_SJOW_Construct(JSContext*, JSObject*, unsigned int, long*, long*)>, xdrObject = 0, hasInstance = 0, mark = 0, reserveSlots = 0}
(gdb) n

Program received signal SIGTRAP, Trace/breakpoint trap.
JS_Assert (s=0xb566e850 "STOBJ_GET_CLASS(obj)->flags & JSCLASS_HAS_PRIVATE", 
    file=0xb566e031 "nsScriptSecurityManager.cpp", ln=138) at jsutil.cpp:63
63          abort();
(gdb) ret
Make JS_Assert return now? (y or n) y
#0  caps_GetJSPrivate (obj=0xb2c55f00)
    at nsScriptSecurityManager.cpp:139
139         v = obj->fslots[JSSLOT_PRIVATE];
(gdb) n
140         if (!JSVAL_IS_INT(v))
(gdb) p v
$3 = 6
(gdb) n
141             return NULL;
(gdb) 
143     }
(gdb) 
nsScriptSecurityManager::GetFunctionObjectPrincipal (cx=0xb067f0a0, 
    obj=0xb2c55f00, fp=0x0, rv=0xbf9e94c0) at nsScriptSecurityManager.cpp:2176
2176        JSScript *script = JS_GetFunctionScript(cx, fun);
(gdb) p fun
$4 = (JSFunction *) 0x0
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0xb7e6d1f7 in JS_GetFunctionScript (cx=0xb067f0a0, fun=0x0) at jsdbgapi.cpp:948
948         return FUN_SCRIPT(fun);
(gdb) 
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: crash, testcase
Still crashes 1.9.0.x: bp-f68877f6-3537-4e1f-a85c-b37ee2090521
and 1.9.1: bp-b125b377-7e34-425c-b61b-4cce02090521

This testcase crashes because fun is null so it might be safe enough, but marking as a security bug for investigation. JS_Asserts are usually bad news and mishandled wrappers are worrying too.

Moving this to the right component from the Firefox:General "lost and found" bin.
Assignee: nobody → general
Group: core-security
Component: General → JavaScript Engine
Product: Firefox → Core
QA Contact: general → general
Summary: [@ JS_GetFunctionScript ] Crash due to setTimeout in greasemonkey script → Crash [@ JS_GetFunctionScript ] with setTimeout and XPCSafeJSObjectWrapper
Blocks: 425139
Keywords: regression
(Assignee)

Comment 4

8 years ago
I'll take this. It's my fault.
Assignee: general → mrbkap
Component: JavaScript Engine → DOM
QA Contact: general → general
(Assignee)

Comment 5

8 years ago
Created attachment 381648 [details] [diff] [review]
Spot fix

Amazingly, this is the only spot in our codebase that makes the JSTYPE_FUNCTION -> JS_ObjectIsFunction connection, so protecting against it here is sufficient.
Attachment #381648 - Flags: superreview?(dveditz)
Attachment #381648 - Flags: review?(dveditz)
We should fix this on 1.9.0.x and 1.9.1.x as well (though unless we can get a non-null crash no need to try and catch the 3.5 train that's already pulling out of the station).
Flags: wanted1.9.1.x+
Flags: wanted1.9.0.x+
Flags: wanted1.8.1.x-
Whiteboard: [sg:investigate]
Attachment #381648 - Flags: superreview?(dveditz)
Attachment #381648 - Flags: superreview+
Attachment #381648 - Flags: review?(dveditz)
Attachment #381648 - Flags: review+
Comment on attachment 381648 [details] [diff] [review]
Spot fix

r/sr=dveditz
(Assignee)

Comment 8

8 years ago
http://hg.mozilla.org/mozilla-central/rev/cccc5f021924
Status: NEW → RESOLVED
Last Resolved: 8 years ago
Resolution: --- → FIXED

Comment 9

8 years ago
bkap, dveditz and josh:  could changes for bug #486574 (which has made objective c exceptions non-fatal) be causing us to hit this more often, and with non-null crashes?

for example, see http://crash-stats.mozilla.com/report/index/9d98c4be-c6d1-44b6-a9fe-283f82090628

The App Notes for that crash are:  "Obj-C Exception data:
NSInvalidArgumentException: *** -[NSCFType setStringValue:]: unrecognized selector sent to instance 0x16803c60"

Before the fix for bug #486574, this crash would have show up as 
crash @ nsObjCExceptionLogAbort (like bug #500470).

In Postbox, we had a crash (like bug #500470).  After applying the patch for bug #486574, we're now seeing a crash that might be fixed by this bug.  (We're still investigating.)

Comment 10

8 years ago
in case it helps, here's a link to all the fx crashes containing JS_GetFunctionScript() in the past week:  http://bit.ly/AW96a
Flags: blocking1.9.1.1?
Flags: blocking1.9.0.13?
Flags: blocking1.9.0.13? → blocking1.9.0.13+
Not blocking 1.9.1.1, but definitely for 1.9.1.2.

Any answer to Seth's questions in comment 9?
Flags: blocking1.9.1.1?
Whiteboard: [sg:investigate] → [sg:investigate][1.9.1.2+]
blocking1.9.1: --- → .2+
status1.9.1: --- → wanted
(Assignee)

Comment 12

8 years ago
I don't think that the two patches are related in any way. This patch might be allowing Seth to get lucky, though.
We'd take a reviewed patch with an approval1.9.1.2? request, most likely, but if it's not ready in time for 1.9.1.2 (end of July) we'll wait until 1.9.1.3.
blocking1.9.1: .2+ → .3+
Whiteboard: [sg:investigate][1.9.1.2+] → [sg:investigate][1.9.1.3+]
(Assignee)

Comment 14

8 years ago
Comment on attachment 381648 [details] [diff] [review]
Spot fix

This applies as-is.
Attachment #381648 - Flags: approval1.9.1.2?
Attachment #381648 - Flags: approval1.9.1.2? → approval1.9.1.2+
Comment on attachment 381648 [details] [diff] [review]
Spot fix

a1912=beltzner, please land on mozilla-1.9.1
(Assignee)

Comment 16

8 years ago
Fixed in http://hg.mozilla.org/releases/mozilla-1.9.1/rev/0f45c73bf86a (is this the right way to mark it?!)
status1.9.1: wanted → .2-fixed
(In reply to comment #16)
> (is this the right way to mark it?!)

(yes)
Verified using test case in comment #1. 3.5 crashes on load. 3.5.2 does not.

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2
Keywords: verified1.9.1
blake: does this patch work for 1.9.0 or do we need a separate patch? Will take your approval1.9.0.14 request as the answer :-)
blocking1.9.1: .3+ → .2+
(Assignee)

Updated

8 years ago
Attachment #381648 - Flags: approval1.9.0.14?
Whiteboard: [sg:investigate][1.9.1.3+] → [sg:investigate]
Comment on attachment 381648 [details] [diff] [review]
Spot fix

Approved for 1.9.0.14, a=dveditz for release-drivers
Attachment #381648 - Flags: approval1.9.0.14? → approval1.9.0.14+
(Assignee)

Comment 21

8 years ago
Checking in caps/src/nsScriptSecurityManager.cpp;
/cvsroot/mozilla/caps/src/nsScriptSecurityManager.cpp,v  <--  nsScriptSecurityManager.cpp
new revision: 1.365; previous revision: 1.364
done
Keywords: fixed1.9.0.14
Verified fixed for 1.9.0.14 with Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.14pre) Gecko/2009081305 GranParadiso/3.0.14pre (.NET CLR 3.5.30729).
Keywords: fixed1.9.0.14 → verified1.9.0.14
Group: core-security
Crash Signature: [@ JS_GetFunctionScript ]
You need to log in before you can comment on or make changes to this bug.