Title: [225659] trunk/Source
Revision
225659
Author
[email protected]
Date
2017-12-07 17:22:06 -0800 (Thu, 07 Dec 2017)

Log Message

Apply poisoning to some native code pointers.
https://bugs.webkit.org/show_bug.cgi?id=180541
<rdar://problem/35916875>

Reviewed by Filip Pizlo.

Source/_javascript_Core:

Renamed g_classInfoPoison to g_globalDataPoison.
Renamed g_masmPoison to g_jitCodePoison.
Introduced g_nativeCodePoison.
Applied g_nativeCodePoison to poisoning some native code pointers.

Introduced non-random Int32 poison values (in JSCPoison.h) for use with pointers
to malloc allocated data structures (where needed).

* API/JSCallbackFunction.h:
(JSC::JSCallbackFunction::functionCallback):
* _javascript_Core.xcodeproj/project.pbxproj:
* jit/ThunkGenerators.cpp:
(JSC::nativeForGenerator):
* llint/LowLevelInterpreter64.asm:
* runtime/CustomGetterSetter.h:
(JSC::CustomGetterSetter::getter const):
(JSC::CustomGetterSetter::setter const):
* runtime/InternalFunction.cpp:
(JSC::InternalFunction::getCallData):
(JSC::InternalFunction::getConstructData):
* runtime/InternalFunction.h:
(JSC::InternalFunction::nativeFunctionFor):
* runtime/JSCPoison.h: Added.
* runtime/JSCPoisonedPtr.cpp:
(JSC::initializePoison):
* runtime/JSCPoisonedPtr.h:
* runtime/Lookup.h:
* runtime/NativeExecutable.cpp:
(JSC::NativeExecutable::hashFor const):
* runtime/NativeExecutable.h:
* runtime/Structure.cpp:
(JSC::StructureTransitionTable::setSingleTransition):
* runtime/StructureTransitionTable.h:
(JSC::StructureTransitionTable::StructureTransitionTable):
(JSC::StructureTransitionTable::isUsingSingleSlot const):
(JSC::StructureTransitionTable::map const):
(JSC::StructureTransitionTable::weakImpl const):
(JSC::StructureTransitionTable::setMap):

Source/WTF:

Ensure that the resultant poisoned bits still looks like a pointer in that its
bottom bits are 0, just like the alignment bits of a pointer.  This allows the
client to use the bottom bits of the poisoned bits as flag bits just like the
client was previously able to do with pointer values.

Note: we only ensure that the bottom alignment bits of the generated poison
value is 0.  We're not masking out the poisoned bits.  This means that the bottom
bits of the poisoned bits will only be null if the original pointer is aligned.
Hence, if the client applies the poison to an unaligned pointer, we do not lose
any information on the low bits.

Also removed 2 wrong assertions in PoisonedImpl's constructors.  We were
asserting that Poisoned will never be used with a null value, but that's invalid.
We do want to allow a null value so that we don't have to constantly do null
checks in the clients.  This was uncovered by some layout tests.

* wtf/Poisoned.cpp:
(WTF::makePoison):
* wtf/Poisoned.h:
(WTF::PoisonedImpl::PoisonedImpl):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/API/JSCallbackFunction.h (225658 => 225659)


--- trunk/Source/_javascript_Core/API/JSCallbackFunction.h	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/API/JSCallbackFunction.h	2017-12-08 01:22:06 UTC (rev 225659)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -51,9 +51,9 @@
     JSCallbackFunction(VM&, Structure*, JSObjectCallAsFunctionCallback);
     void finishCreation(VM&, const String& name);
 
-    JSObjectCallAsFunctionCallback functionCallback() { return m_callback; }
+    JSObjectCallAsFunctionCallback functionCallback() { return m_callback.unpoisoned(); }
 
-    JSObjectCallAsFunctionCallback m_callback;
+    Poisoned<g_nativeCodePoison, JSObjectCallAsFunctionCallback> m_callback;
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/ChangeLog (225658 => 225659)


--- trunk/Source/_javascript_Core/ChangeLog	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-12-08 01:22:06 UTC (rev 225659)
@@ -1,3 +1,50 @@
+2017-12-07  Mark Lam  <[email protected]>
+
+        Apply poisoning to some native code pointers.
+        https://bugs.webkit.org/show_bug.cgi?id=180541
+        <rdar://problem/35916875>
+
+        Reviewed by Filip Pizlo.
+
+        Renamed g_classInfoPoison to g_globalDataPoison.
+        Renamed g_masmPoison to g_jitCodePoison.
+        Introduced g_nativeCodePoison.
+        Applied g_nativeCodePoison to poisoning some native code pointers.
+
+        Introduced non-random Int32 poison values (in JSCPoison.h) for use with pointers
+        to malloc allocated data structures (where needed).
+
+        * API/JSCallbackFunction.h:
+        (JSC::JSCallbackFunction::functionCallback):
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * jit/ThunkGenerators.cpp:
+        (JSC::nativeForGenerator):
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/CustomGetterSetter.h:
+        (JSC::CustomGetterSetter::getter const):
+        (JSC::CustomGetterSetter::setter const):
+        * runtime/InternalFunction.cpp:
+        (JSC::InternalFunction::getCallData):
+        (JSC::InternalFunction::getConstructData):
+        * runtime/InternalFunction.h:
+        (JSC::InternalFunction::nativeFunctionFor):
+        * runtime/JSCPoison.h: Added.
+        * runtime/JSCPoisonedPtr.cpp:
+        (JSC::initializePoison):
+        * runtime/JSCPoisonedPtr.h:
+        * runtime/Lookup.h:
+        * runtime/NativeExecutable.cpp:
+        (JSC::NativeExecutable::hashFor const):
+        * runtime/NativeExecutable.h:
+        * runtime/Structure.cpp:
+        (JSC::StructureTransitionTable::setSingleTransition):
+        * runtime/StructureTransitionTable.h:
+        (JSC::StructureTransitionTable::StructureTransitionTable):
+        (JSC::StructureTransitionTable::isUsingSingleSlot const):
+        (JSC::StructureTransitionTable::map const):
+        (JSC::StructureTransitionTable::weakImpl const):
+        (JSC::StructureTransitionTable::setMap):
+
 2017-12-07  Joseph Pecoraro  <[email protected]>
 
         Web Inspector: Fix style in remote inspector classes

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (225658 => 225659)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-12-08 01:22:06 UTC (rev 225659)
@@ -1721,6 +1721,7 @@
 		FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FE2A87601F02381600EB31B2 /* MinimumReservedZoneSize.h in Headers */ = {isa = PBXBuildFile; fileRef = FE2A875F1F02381600EB31B2 /* MinimumReservedZoneSize.h */; };
 		FE2B0B691FD227E00075DA5F /* JSCPoisonedPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = FE2B0B671FD0D2960075DA5F /* JSCPoisonedPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		FE2B0B731FD9EF700075DA5F /* JSCPoison.h in Headers */ = {isa = PBXBuildFile; fileRef = FE2B0B701FD8C4630075DA5F /* JSCPoison.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FE3022D31E3D73A500BAC493 /* SigillCrashAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3022D11E3D739600BAC493 /* SigillCrashAnalyzer.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FE3022D71E42857300BAC493 /* VMInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3022D51E42856700BAC493 /* VMInspector.h */; };
 		FE318FE01CAC982F00DFCC54 /* ECMAScriptSpecInternalFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = FE318FDE1CAC8C5300DFCC54 /* ECMAScriptSpecInternalFunctions.h */; };
@@ -4600,6 +4601,7 @@
 		FE2A875F1F02381600EB31B2 /* MinimumReservedZoneSize.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MinimumReservedZoneSize.h; sourceTree = "<group>"; };
 		FE2B0B671FD0D2960075DA5F /* JSCPoisonedPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCPoisonedPtr.h; sourceTree = "<group>"; };
 		FE2B0B681FD0D2970075DA5F /* JSCPoisonedPtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCPoisonedPtr.cpp; sourceTree = "<group>"; };
+		FE2B0B701FD8C4630075DA5F /* JSCPoison.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCPoison.h; sourceTree = "<group>"; };
 		FE2E6A7A1D6EA5FE0060F896 /* ThrowScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThrowScope.cpp; sourceTree = "<group>"; };
 		FE3022D01E3D739600BAC493 /* SigillCrashAnalyzer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SigillCrashAnalyzer.cpp; sourceTree = "<group>"; };
 		FE3022D11E3D739600BAC493 /* SigillCrashAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SigillCrashAnalyzer.h; sourceTree = "<group>"; };
@@ -6543,6 +6545,7 @@
 				F692A8870255597D01FF60F7 /* JSCJSValue.cpp */,
 				14ABB36E099C076400E2A24F /* JSCJSValue.h */,
 				865A30F0135007E100CDB49E /* JSCJSValueInlines.h */,
+				FE2B0B701FD8C4630075DA5F /* JSCPoison.h */,
 				FE2B0B681FD0D2970075DA5F /* JSCPoisonedPtr.cpp */,
 				FE2B0B671FD0D2960075DA5F /* JSCPoisonedPtr.h */,
 				72AAF7CB1D0D318B005E60BE /* JSCustomGetterSetterFunction.cpp */,
@@ -8101,6 +8104,7 @@
 				0F338DFA1BE96AA80013C88F /* B3CCallValue.h in Headers */,
 				0F33FCFB1C1625BE00323F67 /* B3CFG.h in Headers */,
 				0FEC85061BDACDAC0080FF74 /* B3CheckSpecial.h in Headers */,
+				FE2B0B731FD9EF700075DA5F /* JSCPoison.h in Headers */,
 				0FEC85081BDACDAC0080FF74 /* B3CheckValue.h in Headers */,
 				0FEC850A1BDACDAC0080FF74 /* B3Common.h in Headers */,
 				0FDCE12D1FAFB4E5006F3901 /* IsoSubspace.h in Headers */,

Modified: trunk/Source/_javascript_Core/b3/B3LowerMacros.cpp (225658 => 225659)


--- trunk/Source/_javascript_Core/b3/B3LowerMacros.cpp	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/b3/B3LowerMacros.cpp	2017-12-08 01:22:06 UTC (rev 225659)
@@ -507,7 +507,7 @@
                         GPRReg scratch = params.gpScratch(0);
                         GPRReg poisonScratch = params.gpScratch(1);
 
-                        jit.move(CCallHelpers::TrustedImm64(g_masmPoison), poisonScratch);
+                        jit.move(CCallHelpers::TrustedImm64(g_jitCodePoison), poisonScratch);
                         jit.move(CCallHelpers::TrustedImmPtr(jumpTable), scratch);
                         jit.load64(CCallHelpers::BaseIndex(scratch, index, CCallHelpers::timesPtr()), scratch);
                         jit.xor64(poisonScratch, scratch);

Modified: trunk/Source/_javascript_Core/b3/testb3.cpp (225658 => 225659)


--- trunk/Source/_javascript_Core/b3/testb3.cpp	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/b3/testb3.cpp	2017-12-08 01:22:06 UTC (rev 225659)
@@ -13033,7 +13033,7 @@
             GPRReg poisonScratch = params.gpScratch(1);
 
             jit.move(CCallHelpers::TrustedImmPtr(jumpTable), scratch);
-            jit.move(CCallHelpers::TrustedImm64(g_masmPoison), poisonScratch);
+            jit.move(CCallHelpers::TrustedImm64(g_jitCodePoison), poisonScratch);
             jit.load64(CCallHelpers::BaseIndex(scratch, params[0].gpr(), CCallHelpers::timesPtr()), scratch);
             jit.xor64(poisonScratch, scratch);
             jit.jump(scratch);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (225658 => 225659)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2017-12-08 01:22:06 UTC (rev 225659)
@@ -8706,7 +8706,7 @@
         m_jit.emitLoadStructure(*m_jit.vm(), baseGPR, otherGPR, specifiedGPR);
         m_jit.loadPtr(CCallHelpers::Address(otherGPR, Structure::classInfoOffset()), otherGPR);
 #if USE(JSVALUE64)
-        m_jit.move(CCallHelpers::TrustedImm64(g_classInfoPoison), specifiedGPR);
+        m_jit.move(CCallHelpers::TrustedImm64(g_globalDataPoison), specifiedGPR);
         m_jit.xor64(specifiedGPR, otherGPR);
 #endif
         m_jit.move(CCallHelpers::TrustedImmPtr(node->classInfo()), specifiedGPR);
@@ -9784,7 +9784,7 @@
         data->fallThrough.block);
     UNUSED_PARAM(poisonScratch); // Placate the 32-bit build.
 #if USE(JSVALUE64)
-    m_jit.move(TrustedImm64(g_masmPoison), poisonScratch);
+    m_jit.move(TrustedImm64(g_jitCodePoison), poisonScratch);
 #endif
     m_jit.move(TrustedImmPtr(table.ctiOffsets.begin()), scratch);
     m_jit.loadPtr(JITCompiler::BaseIndex(scratch, value, JITCompiler::timesPtr()), scratch);

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (225658 => 225659)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2017-12-08 01:22:06 UTC (rev 225659)
@@ -11171,7 +11171,7 @@
 
             LValue structure = loadStructure(cell);
             LValue poisonedClassInfo = m_out.loadPtr(structure, m_heaps.Structure_classInfo);
-            LValue classInfo = m_out.bitXor(poisonedClassInfo, m_out.constInt64(g_classInfoPoison));
+            LValue classInfo = m_out.bitXor(poisonedClassInfo, m_out.constInt64(g_globalDataPoison));
             ValueFromBlock otherAtStart = m_out.anchor(classInfo);
             m_out.jump(loop);
 

Modified: trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp (225658 => 225659)


--- trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp	2017-12-08 01:22:06 UTC (rev 225659)
@@ -214,7 +214,7 @@
     // Now we know that we have a CodeBlock, and we're committed to making a fast
     // call.
 #if USE(JSVALUE64)
-    jit.move(CCallHelpers::TrustedImm64(g_masmPoison), GPRInfo::regT1);
+    jit.move(CCallHelpers::TrustedImm64(g_jitCodePoison), GPRInfo::regT1);
     jit.xor64(GPRInfo::regT1, GPRInfo::regT4);
 #endif
 
@@ -307,9 +307,12 @@
     jit.emitGetFromCallFrameHeaderPtr(CallFrameSlot::callee, X86Registers::esi);
     if (thunkFunctionType == ThunkFunctionType::JSFunction) {
         jit.loadPtr(JSInterfaceJIT::Address(X86Registers::esi, JSFunction::offsetOfExecutable()), X86Registers::r9);
-        jit.call(JSInterfaceJIT::Address(X86Registers::r9, executableOffsetToFunction));
+        jit.loadPtr(JSInterfaceJIT::Address(X86Registers::r9, executableOffsetToFunction), X86Registers::r9);
     } else
-        jit.call(JSInterfaceJIT::Address(X86Registers::esi, InternalFunction::offsetOfNativeFunctionFor(kind)));
+        jit.loadPtr(JSInterfaceJIT::Address(X86Registers::esi, InternalFunction::offsetOfNativeFunctionFor(kind)), X86Registers::r9);
+    jit.move(JSInterfaceJIT::TrustedImm64(g_nativeCodePoison), X86Registers::esi);
+    jit.xor64(X86Registers::esi, X86Registers::r9);
+    jit.call(X86Registers::r9);
 
 #else
     // Calling convention:      f(ecx, edx, r8, r9, ...);
@@ -341,9 +344,13 @@
     jit.emitGetFromCallFrameHeaderPtr(CallFrameSlot::callee, ARM64Registers::x1);
     if (thunkFunctionType == ThunkFunctionType::JSFunction) {
         jit.loadPtr(JSInterfaceJIT::Address(ARM64Registers::x1, JSFunction::offsetOfExecutable()), ARM64Registers::x2);
-        jit.call(JSInterfaceJIT::Address(ARM64Registers::x2, executableOffsetToFunction));
+        jit.loadPtr(JSInterfaceJIT::Address(ARM64Registers::x2, executableOffsetToFunction), ARM64Registers::x2);
     } else
-        jit.call(JSInterfaceJIT::Address(ARM64Registers::x1, InternalFunction::offsetOfNativeFunctionFor(kind)));
+        jit.loadPtr(JSInterfaceJIT::Address(ARM64Registers::x1, InternalFunction::offsetOfNativeFunctionFor(kind)), ARM64Registers::x2);
+    jit.move(JSInterfaceJIT::TrustedImm64(g_nativeCodePoison), ARM64Registers::x1);
+    jit.xor64(ARM64Registers::x1, ARM64Registers::x2);
+    jit.call(ARM64Registers::x2);
+
 #elif CPU(ARM) || CPU(MIPS)
 #if CPU(MIPS)
     // Allocate stack space for (unused) 16 bytes (8-byte aligned) for 4 arguments.
@@ -1163,7 +1170,7 @@
     CCallHelpers::Jump noCode = jit.branchTestPtr(CCallHelpers::Zero, GPRInfo::regT0);
     
 #if USE(JSVALUE64)
-    jit.move(CCallHelpers::TrustedImm64(g_masmPoison), GPRInfo::regT1);
+    jit.move(CCallHelpers::TrustedImm64(g_jitCodePoison), GPRInfo::regT1);
     jit.xor64(GPRInfo::regT1, GPRInfo::regT0);
 #endif
     emitPointerValidation(jit, GPRInfo::regT0);

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (225658 => 225659)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2017-12-08 01:22:06 UTC (rev 225659)
@@ -1950,7 +1950,7 @@
         prepareCall(LLIntCallLinkInfo::machineCodeTarget[t1], t2, t3, t4)
         callTargetFunction(LLIntCallLinkInfo::machineCodeTarget[t1])
     else
-        loadp _g_masmPoison, t2
+        loadp _g_jitCodePoison, t2
         xorp LLIntCallLinkInfo::machineCodeTarget[t1], t2
         prepareCall(t2, t1, t3, t4)
         callTargetFunction(t2)
@@ -2080,10 +2080,12 @@
     else
         if X86_64_WIN
             subp 32, sp
-        end
-        call executableOffsetToFunction[t1]
-        if X86_64_WIN
+            call executableOffsetToFunction[t1]
             addp 32, sp
+        else
+            loadp _g_nativeCodePoison, t2
+            xorp executableOffsetToFunction[t1], t2
+            call t2
         end
     end
 
@@ -2119,10 +2121,12 @@
     else
         if X86_64_WIN
             subp 32, sp
-        end
-        call offsetOfFunction[t1]
-        if X86_64_WIN
+            call offsetOfFunction[t1]
             addp 32, sp
+        else
+            loadp _g_nativeCodePoison, t2
+            xorp offsetOfFunction[t1], t2
+            call t2
         end
     end
 

Modified: trunk/Source/_javascript_Core/runtime/CustomGetterSetter.h (225658 => 225659)


--- trunk/Source/_javascript_Core/runtime/CustomGetterSetter.h	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/runtime/CustomGetterSetter.h	2017-12-08 01:22:06 UTC (rev 225659)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include "JSCPoisonedPtr.h"
 #include "JSCell.h"
 #include "PropertySlot.h"
 #include "PutPropertySlot.h"
@@ -47,8 +48,8 @@
         return customGetterSetter;
     }
 
-    CustomGetterSetter::CustomGetter getter() const { return m_getter; }
-    CustomGetterSetter::CustomSetter setter() const { return m_setter; }
+    CustomGetterSetter::CustomGetter getter() const { return m_getter.unpoisoned(); }
+    CustomGetterSetter::CustomSetter setter() const { return m_setter.unpoisoned(); }
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
@@ -66,8 +67,11 @@
     }
 
 private:
-    CustomGetter m_getter;
-    CustomSetter m_setter;
+    template<typename T>
+    using PoisonedAccessor = Poisoned<g_nativeCodePoison, T>;
+
+    PoisonedAccessor<CustomGetter> m_getter;
+    PoisonedAccessor<CustomSetter> m_setter;
 };
 
 JS_EXPORT_PRIVATE bool callCustomSetter(ExecState*, CustomGetterSetter::CustomSetter, bool isAccessor, JSValue thisValue, JSValue);

Modified: trunk/Source/_javascript_Core/runtime/InternalFunction.cpp (225658 => 225659)


--- trunk/Source/_javascript_Core/runtime/InternalFunction.cpp	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/runtime/InternalFunction.cpp	2017-12-08 01:22:06 UTC (rev 225659)
@@ -88,7 +88,7 @@
 {
     auto* function = jsCast<InternalFunction*>(cell);
     ASSERT(function->m_functionForCall);
-    callData.native.function = function->m_functionForCall;
+    callData.native.function = function->m_functionForCall.unpoisoned();
     return CallType::Host;
 }
 
@@ -97,7 +97,7 @@
     auto* function = jsCast<InternalFunction*>(cell);
     if (function->m_functionForConstruct == callHostFunctionAsConstructor)
         return ConstructType::None;
-    constructData.native.function = function->m_functionForConstruct;
+    constructData.native.function = function->m_functionForConstruct.unpoisoned();
     return ConstructType::Host;
 }
 

Modified: trunk/Source/_javascript_Core/runtime/InternalFunction.h (225658 => 225659)


--- trunk/Source/_javascript_Core/runtime/InternalFunction.h	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/runtime/InternalFunction.h	2017-12-08 01:22:06 UTC (rev 225659)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten ([email protected])
- *  Copyright (C) 2003, 2006, 2007, 2008, 2016 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Cameron Zwarich ([email protected])
  *  Copyright (C) 2007 Maks Orlovich
  *
@@ -24,6 +24,7 @@
 #pragma once
 
 #include "CodeSpecializationKind.h"
+#include "JSCPoisonedPtr.h"
 #include "JSDestructibleObject.h"
 
 namespace JSC {
@@ -55,9 +56,9 @@
     NativeFunction nativeFunctionFor(CodeSpecializationKind kind)
     {
         if (kind == CodeForCall)
-            return m_functionForCall;
+            return m_functionForCall.unpoisoned();
         ASSERT(kind == CodeForConstruct);
-        return m_functionForConstruct;
+        return m_functionForConstruct.unpoisoned();
     }
 
     static ptrdiff_t offsetOfNativeFunctionFor(CodeSpecializationKind kind)
@@ -69,6 +70,8 @@
     }
 
 protected:
+    using PoisonedNativeFunction = Poisoned<g_nativeCodePoison, NativeFunction>;
+
     JS_EXPORT_PRIVATE InternalFunction(VM&, Structure*, NativeFunction functionForCall, NativeFunction functionForConstruct);
 
     enum class NameVisibility { Visible, Anonymous };
@@ -79,8 +82,8 @@
     JS_EXPORT_PRIVATE static ConstructType getConstructData(JSCell*, ConstructData&);
     JS_EXPORT_PRIVATE static CallType getCallData(JSCell*, CallData&);
 
-    NativeFunction m_functionForCall;
-    NativeFunction m_functionForConstruct;
+    PoisonedNativeFunction m_functionForCall;
+    PoisonedNativeFunction m_functionForConstruct;
     WriteBarrier<JSString> m_originalName;
 };
 

Added: trunk/Source/_javascript_Core/runtime/JSCPoison.h (0 => 225659)


--- trunk/Source/_javascript_Core/runtime/JSCPoison.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/JSCPoison.h	2017-12-08 01:22:06 UTC (rev 225659)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/Poisoned.h>
+
+namespace JSC {
+
+enum Poison {
+    NotPoisoned = 0,
+    TransitionMapPoison,
+    WeakImplPoison,
+};
+
+} // namespace JSC
+

Modified: trunk/Source/_javascript_Core/runtime/JSCPoisonedPtr.cpp (225658 => 225659)


--- trunk/Source/_javascript_Core/runtime/JSCPoisonedPtr.cpp	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/runtime/JSCPoisonedPtr.cpp	2017-12-08 01:22:06 UTC (rev 225659)
@@ -28,15 +28,17 @@
 
 namespace JSC {
 
-uintptr_t g_classInfoPoison;
-uintptr_t g_masmPoison;
+uintptr_t g_globalDataPoison;
+uintptr_t g_jitCodePoison;
+uintptr_t g_nativeCodePoison;
 
 void initializePoison()
 {
     static std::once_flag initializeOnceFlag;
     std::call_once(initializeOnceFlag, [] {
-        g_classInfoPoison = makePoison();
-        g_masmPoison = makePoison();
+        g_globalDataPoison = makePoison();
+        g_jitCodePoison = makePoison();
+        g_nativeCodePoison = makePoison();
     });
 }
 

Modified: trunk/Source/_javascript_Core/runtime/JSCPoisonedPtr.h (225658 => 225659)


--- trunk/Source/_javascript_Core/runtime/JSCPoisonedPtr.h	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/runtime/JSCPoisonedPtr.h	2017-12-08 01:22:06 UTC (rev 225659)
@@ -29,13 +29,14 @@
 
 namespace JSC {
 
-extern "C" JS_EXPORTDATA uintptr_t g_classInfoPoison;
-extern "C" JS_EXPORTDATA uintptr_t g_masmPoison;
+extern "C" JS_EXPORTDATA uintptr_t g_globalDataPoison;
+extern "C" JS_EXPORTDATA uintptr_t g_jitCodePoison;
+extern "C" JS_EXPORTDATA uintptr_t g_nativeCodePoison;
 
 struct ClassInfo;
 
-using PoisonedClassInfoPtr = Poisoned<g_classInfoPoison, const ClassInfo*>;
-using PoisonedMasmPtr = Poisoned<g_masmPoison, void*>;
+using PoisonedClassInfoPtr = Poisoned<g_globalDataPoison, const ClassInfo*>;
+using PoisonedMasmPtr = Poisoned<g_jitCodePoison, void*>;
 
 void initializePoison();
 

Modified: trunk/Source/_javascript_Core/runtime/NativeExecutable.cpp (225658 => 225659)


--- trunk/Source/_javascript_Core/runtime/NativeExecutable.cpp	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/runtime/NativeExecutable.cpp	2017-12-08 01:22:06 UTC (rev 225659)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009, 2010, 2013, 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -79,10 +79,10 @@
 CodeBlockHash NativeExecutable::hashFor(CodeSpecializationKind kind) const
 {
     if (kind == CodeForCall)
-        return CodeBlockHash(static_cast<unsigned>(bitwise_cast<size_t>(m_function)));
-    
+        return CodeBlockHash(m_function.bits());
+
     RELEASE_ASSERT(kind == CodeForConstruct);
-    return CodeBlockHash(static_cast<unsigned>(bitwise_cast<size_t>(m_constructor)));
+    return CodeBlockHash(m_constructor.bits());
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/NativeExecutable.h (225658 => 225659)


--- trunk/Source/_javascript_Core/runtime/NativeExecutable.h	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/runtime/NativeExecutable.h	2017-12-08 01:22:06 UTC (rev 225659)
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "ExecutableBase.h"
+#include "JSCPoisonedPtr.h"
 
 namespace JSC {
 namespace DOMJIT {
@@ -51,8 +52,8 @@
 
     CodeBlockHash hashFor(CodeSpecializationKind) const;
 
-    NativeFunction function() { return m_function; }
-    NativeFunction constructor() { return m_constructor; }
+    NativeFunction function() { return m_function.unpoisoned(); }
+    NativeFunction constructor() { return m_constructor.unpoisoned(); }
         
     NativeFunction nativeFunctionFor(CodeSpecializationKind kind)
     {
@@ -89,11 +90,12 @@
 
 private:
     friend class ExecutableBase;
+    using PoisonedNativeFunction = Poisoned<g_nativeCodePoison, NativeFunction>;
 
     NativeExecutable(VM&, NativeFunction function, NativeFunction constructor, Intrinsic, const DOMJIT::Signature*);
 
-    NativeFunction m_function;
-    NativeFunction m_constructor;
+    PoisonedNativeFunction m_function;
+    PoisonedNativeFunction m_constructor;
     const DOMJIT::Signature* m_signature;
 
     String m_name;

Modified: trunk/Source/_javascript_Core/runtime/Structure.cpp (225658 => 225659)


--- trunk/Source/_javascript_Core/runtime/Structure.cpp	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/runtime/Structure.cpp	2017-12-08 01:22:06 UTC (rev 225659)
@@ -86,7 +86,7 @@
     if (WeakImpl* impl = this->weakImpl())
         WeakSet::deallocate(impl);
     WeakImpl* impl = WeakSet::allocate(structure, &singleSlotTransitionWeakOwner(), this);
-    m_data = reinterpret_cast<intptr_t>(impl) | UsingSingleSlotFlag;
+    m_data = PoisonedWeakImplPtr(impl).bits() | UsingSingleSlotFlag;
 }
 
 bool StructureTransitionTable::contains(UniquedStringImpl* rep, unsigned attributes) const

Modified: trunk/Source/_javascript_Core/runtime/StructureTransitionTable.h (225658 => 225659)


--- trunk/Source/_javascript_Core/runtime/StructureTransitionTable.h	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/_javascript_Core/runtime/StructureTransitionTable.h	2017-12-08 01:22:06 UTC (rev 225659)
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "IndexingType.h"
+#include "JSCPoison.h"
 #include "WeakGCMap.h"
 #include <wtf/HashFunctions.h>
 #include <wtf/text/UniquedStringImpl.h>
@@ -186,6 +187,8 @@
 
 private:
     friend class SingleSlotTransitionWeakOwner;
+    using PoisonedTransitionMapPtr = Int32Poisoned<TransitionMapPoison, TransitionMap*>;
+    using PoisonedWeakImplPtr = Int32Poisoned<WeakImplPoison, WeakImpl*>;
 
     bool isUsingSingleSlot() const
     {
@@ -195,13 +198,13 @@
     TransitionMap* map() const
     {
         ASSERT(!isUsingSingleSlot());
-        return reinterpret_cast<TransitionMap*>(m_data);
+        return PoisonedTransitionMapPtr(m_data).unpoisoned();
     }
 
     WeakImpl* weakImpl() const
     {
         ASSERT(isUsingSingleSlot());
-        return reinterpret_cast<WeakImpl*>(m_data & ~UsingSingleSlotFlag);
+        return PoisonedWeakImplPtr(m_data & ~UsingSingleSlotFlag).unpoisoned();
     }
 
     void setMap(TransitionMap* map)
@@ -212,7 +215,7 @@
             WeakSet::deallocate(impl);
 
         // This implicitly clears the flag that indicates we're using a single transition
-        m_data = reinterpret_cast<intptr_t>(map);
+        m_data = PoisonedTransitionMapPtr(map).bits();
 
         ASSERT(!isUsingSingleSlot());
     }

Modified: trunk/Source/WTF/ChangeLog (225658 => 225659)


--- trunk/Source/WTF/ChangeLog	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/WTF/ChangeLog	2017-12-08 01:22:06 UTC (rev 225659)
@@ -1,5 +1,34 @@
 2017-12-07  Mark Lam  <[email protected]>
 
+        Apply poisoning to some native code pointers.
+        https://bugs.webkit.org/show_bug.cgi?id=180541
+        <rdar://problem/35916875>
+
+        Reviewed by Filip Pizlo.
+
+        Ensure that the resultant poisoned bits still looks like a pointer in that its
+        bottom bits are 0, just like the alignment bits of a pointer.  This allows the
+        client to use the bottom bits of the poisoned bits as flag bits just like the
+        client was previously able to do with pointer values.
+
+        Note: we only ensure that the bottom alignment bits of the generated poison
+        value is 0.  We're not masking out the poisoned bits.  This means that the bottom
+        bits of the poisoned bits will only be null if the original pointer is aligned.
+        Hence, if the client applies the poison to an unaligned pointer, we do not lose
+        any information on the low bits.
+
+        Also removed 2 wrong assertions in PoisonedImpl's constructors.  We were
+        asserting that Poisoned will never be used with a null value, but that's invalid.
+        We do want to allow a null value so that we don't have to constantly do null
+        checks in the clients.  This was uncovered by some layout tests.
+
+        * wtf/Poisoned.cpp:
+        (WTF::makePoison):
+        * wtf/Poisoned.h:
+        (WTF::PoisonedImpl::PoisonedImpl):
+
+2017-12-07  Mark Lam  <[email protected]>
+
         [Re-landing r225620] Refactoring: Rename ScrambledPtr to Poisoned.
         https://bugs.webkit.org/show_bug.cgi?id=180514
 

Modified: trunk/Source/WTF/wtf/Poisoned.cpp (225658 => 225659)


--- trunk/Source/WTF/wtf/Poisoned.cpp	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/WTF/wtf/Poisoned.cpp	2017-12-08 01:22:06 UTC (rev 225659)
@@ -39,6 +39,11 @@
     // cannot be 0. We ensure that it is zero so that the poisoned bits can also be
     // used for a notmal zero check without needing to decoded first.
     key |= (static_cast<uintptr_t>(0x1) << 63);
+    // Ensure that the bottom alignment bits are still 0 so that the poisoned bits will
+    // still preserve the properties of a pointer where these bits are expected to be 0.
+    // This allows the poisoned bits to be used in place of the pointer by clients that
+    // rely on this property of pointers and sets flags in the low bits.
+    key &= ~static_cast<uintptr_t>(0x7);
 #else
     key = 0; // Poisoning is not supported on 32-bit or non-darwin platforms yet.
 #endif

Modified: trunk/Source/WTF/wtf/Poisoned.h (225658 => 225659)


--- trunk/Source/WTF/wtf/Poisoned.h	2017-12-08 01:12:18 UTC (rev 225658)
+++ trunk/Source/WTF/wtf/Poisoned.h	2017-12-08 01:22:06 UTC (rev 225659)
@@ -47,17 +47,13 @@
 
     explicit PoisonedImpl(T ptr)
         : m_poisonedBits(poison(ptr))
-    {
-        ASSERT(ptr && m_poisonedBits);
-    }
+    { }
 
     PoisonedImpl(const PoisonedImpl&) = default;
 
     explicit PoisonedImpl(PoisonedBits poisonedBits)
         : m_poisonedBits(poisonedBits)
-    {
-        ASSERT(m_poisonedBits);
-    }
+    { }
 
 #if ENABLE(POISON_ASSERTS)
     template<typename U = void*>
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to