The following sample triggers a debug assertion failure on JSC build from latest HEAD: function main() { const v2 = new Uint8Array(7792); function v3(v4,v5,...v6) { const v9 = createGlobalObject(); const v11 = function() { return 42; } const v15 = {"get":v11}; const v17 = new Proxy(v9,v15); const v18 = v17.foobar; } const v20 = v2.find(v3); gc(); } noDFG(main); noFTL(main); main(); // CRASH INFO // ========== // TERMSIG: 6 // STDERR: // ASSERTION FAILED: isCell() // /home/builder/webkit/Source/JavaScriptCore/runtime/JSCJSValueInlines.h(605) : JSC::JSCell *JSC::JSValue::asCell() const Here is the backtrace from gdb: #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:49 #1 0x00007ffff1649546 in __GI_abort () at abort.c:79 #2 0x00007ffff5532b1b in WTFCrashWithInfo () at WTF/Headers/wtf/Assertions.h:754 #3 0x00007ffff55ab9cb in JSC::JSValue::asCell (this=0x7fffffffc2f8) at Source/JavaScriptCore/runtime/JSCJSValueInlines.h:605 #4 0x00007ffff55b91a5 in JSC::asObject (value=...) at Source/JavaScriptCore/runtime/JSObject.h:1369 #5 0x00007ffff6e0a8a4 in JSC::globalFuncHandleProxyGetTrapResult (globalObject=0x7fffa541a068, callFrame=0x7fffffffc4b0) at Source/JavaScriptCore/runtime/JSGlobalObject.cpp:377 #6 0x00007fffa6e2c038 in ?? () #7 0x00007fffffffc550 in ?? () #8 0x00007ffff54f11e1 in js_trampoline_op_call () from WebKitBuild/Debug/lib/libJavaScriptCore.so.1 #9 0x0000000000000000 in ?? () It seems what happens here is that globalFuncHandleProxyGetTrapResult expects parameter 1 to be a JSObject but in this case it is the undefined value. The issue may only affect the jsc shell (as it seems to require the createGlobalObject builtin) and may only lead to this specific type confusion (undefined treated as JSObject), which is probably not exploitable. I'm still filing this issue as a security issue as a precaution.
<rdar://problem/100315084>
I believe the checking here should have been done in the performProxyObjectGet JavaScript function, which is why globalFuncHandleProxyGetTrapResult thinks it can just get the arguments without type checking.
We should not pass global object as |this| since it will be converted to `undefined` in strict mode code. I'll take a look super quickly.
Only possible case is it becomes undefined (bit pattern is 0xa, which cannot be used for any other pointer), thus, it does not have security issue (just crash).
And maybe, this is JSC shell only issue. GlobalObject is not exposed directly in the normal environment (it is always JSProxy to GlobalObject).
Yeah, this is JSC shell only issue with crash. Making it to non-security.
Pull request: https://github.com/WebKit/WebKit/pull/4649
Committed 254815@main (6848dafe458b): <https://commits.webkit.org/254815@main> Reviewed commits have been landed. Closing PR #4649 and removing active labels.