Changeset 265151 in webkit
- Timestamp:
- Jul 31, 2020 11:46:18 AM (4 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r265142 r265151 1 2020-07-31 Saam Barati <sbarati@apple.com> 2 3 validate untagArrayPtr 4 https://bugs.webkit.org/show_bug.cgi?id=214953 5 6 Reviewed by Keith Miller. 7 8 This patch adds validation to untagArrayPtr along paths where we don't 9 immediately store/load from the result. 10 11 This patch also changes the removeArrayPtrTag macro assembler function to 12 use shifts instead of xpacd to strip the tag, because it's faster. 13 14 * assembler/MacroAssemblerARM64E.h: 15 (JSC::MacroAssemblerARM64E::untagArrayPtr): 16 (JSC::MacroAssemblerARM64E::removeArrayPtrTag): 17 * assembler/testmasm.cpp: 18 (JSC::testCagePreservesPACFailureBit): 19 * bytecode/AccessCase.cpp: 20 (JSC::AccessCase::generateWithGuard): 21 * dfg/DFGSpeculativeJIT.cpp: 22 (JSC::DFG::SpeculativeJIT::cageTypedArrayStorage): 23 * dfg/DFGSpeculativeJIT.h: 24 * dfg/DFGSpeculativeJIT64.cpp: 25 (JSC::DFG::SpeculativeJIT::compile): 26 * ftl/FTLLowerDFGToB3.cpp: 27 (JSC::FTL::DFG::LowerDFGToB3::untagArrayPtr): 28 (JSC::FTL::DFG::LowerDFGToB3::caged): 29 * jit/AssemblyHelpers.cpp: 30 (JSC::AssemblyHelpers::cageWithoutUntagging): 31 (JSC::AssemblyHelpers::cageConditionallyAndUntag): 32 * jit/AssemblyHelpers.h: 33 (JSC::AssemblyHelpers::cageWithoutUntagging): Deleted. 34 (JSC::AssemblyHelpers::cageConditionally): Deleted. 35 * jit/JITPropertyAccess.cpp: 36 (JSC::JIT::emitIntTypedArrayPutByVal): 37 (JSC::JIT::emitFloatTypedArrayPutByVal): 38 * wasm/WasmAirIRGenerator.cpp: 39 (JSC::Wasm::AirIRGenerator::restoreWebAssemblyGlobalState): 40 (JSC::Wasm::AirIRGenerator::addCallIndirect): 41 * wasm/WasmB3IRGenerator.cpp: 42 (JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState): 43 (JSC::Wasm::B3IRGenerator::addCallIndirect): 44 * wasm/WasmBinding.cpp: 45 (JSC::Wasm::wasmToWasm): 46 * wasm/js/JSToWasm.cpp: 47 (JSC::Wasm::createJSToWasmWrapper): 48 * wasm/js/WebAssemblyFunction.cpp: 49 (JSC::WebAssemblyFunction::jsCallEntrypointSlow): 50 1 51 2020-07-31 Keith Miller <keith_miller@apple.com> 2 52 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64E.h
r265122 r265151 91 91 } 92 92 93 ALWAYS_INLINE void untagArrayPtr(RegisterID length, RegisterID target) 94 { 93 ALWAYS_INLINE void untagArrayPtr(RegisterID length, RegisterID target, bool validateAuth, RegisterID scratch) 94 { 95 if (validateAuth) { 96 ASSERT(scratch != InvalidGPRReg); 97 move(target, scratch); 98 } 99 95 100 m_assembler.autdb(target, length); 96 } 97 98 ALWAYS_INLINE void untagArrayPtr(Address length, RegisterID target) 101 102 if (validateAuth) { 103 ASSERT(target != ARM64Registers::sp); 104 ASSERT(scratch != ARM64Registers::sp); 105 removeArrayPtrTag(scratch); 106 auto isValidPtr = branch64(Equal, scratch, target); 107 breakpoint(0xabcd); 108 isValidPtr.link(this); 109 } 110 } 111 112 ALWAYS_INLINE void untagArrayPtr(Address length, RegisterID target, bool validateAuth) 99 113 { 100 114 auto lengthGPR = getCachedDataTempRegisterIDAndInvalidate(); 101 115 load32(length, lengthGPR); 116 auto scratch = InvalidGPRReg; 117 if (validateAuth) { 118 scratch = getCachedMemoryTempRegisterIDAndInvalidate(); 119 move(target, scratch); 120 } 121 102 122 m_assembler.autdb(target, lengthGPR); 123 124 if (validateAuth) { 125 ASSERT(target != ARM64Registers::sp); 126 removeArrayPtrTag(scratch); 127 auto isValidPtr = branch64(Equal, scratch, target); 128 breakpoint(0xabcd); 129 isValidPtr.link(this); 130 } 103 131 } 104 132 105 133 ALWAYS_INLINE void removeArrayPtrTag(RegisterID target) 106 134 { 107 m_assembler.xpacd(target); 135 // If we couldn't fit this into a single instruction, we'd be better 136 // off emitting two shifts to mask off the top bits. 137 ASSERT(LogicalImmediate::create64(nonPACBitsMask).isValid()); 138 and64(TrustedImmPtr(nonPACBitsMask), target); 108 139 } 109 140 -
trunk/Source/JavaScriptCore/assembler/testmasm.cpp
r265036 r265151 2461 2461 auto cage = compile([] (CCallHelpers& jit) { 2462 2462 emitFunctionPrologue(jit); 2463 jit.cageConditionally (Gigacage::Primitive, GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, GPRInfo::argumentGPR2);2463 jit.cageConditionallyAndUntag(Gigacage::Primitive, GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, GPRInfo::argumentGPR2); 2464 2464 jit.move(GPRInfo::argumentGPR0, GPRInfo::returnValueGPR); 2465 2465 emitFunctionEpilogue(jit); -
trunk/Source/JavaScriptCore/bytecode/AccessCase.cpp
r263824 r265151 1022 1022 1023 1023 jit.loadPtr(CCallHelpers::Address(baseGPR, JSArrayBufferView::offsetOfVector()), scratch2GPR); 1024 jit.cageConditionally (Gigacage::Primitive, scratch2GPR, scratchGPR, scratchGPR);1024 jit.cageConditionallyAndUntag(Gigacage::Primitive, scratch2GPR, scratchGPR, scratchGPR, false); 1025 1025 1026 1026 jit.signExtend32ToPtr(propertyGPR, scratchGPR); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r265097 r265151 7240 7240 } 7241 7241 7242 void SpeculativeJIT::cageTypedArrayStorage(GPRReg baseReg, GPRReg storageReg )7242 void SpeculativeJIT::cageTypedArrayStorage(GPRReg baseReg, GPRReg storageReg, bool validateAuth) 7243 7243 { 7244 7244 auto untagArrayPtr = [&]() { 7245 7245 #if CPU(ARM64E) 7246 m_jit.untagArrayPtr(MacroAssembler::Address(baseReg, JSArrayBufferView::offsetOfLength()), storageReg );7246 m_jit.untagArrayPtr(MacroAssembler::Address(baseReg, JSArrayBufferView::offsetOfLength()), storageReg, validateAuth); 7247 7247 #else 7248 UNUSED_PARAM(validateAuth); 7248 7249 UNUSED_PARAM(baseReg); 7249 7250 UNUSED_PARAM(storageReg); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r262252 r265151 1661 1661 GPRReg fillSpeculateInt32Internal(Edge, DataFormat& returnFormat); 1662 1662 1663 void cageTypedArrayStorage(GPRReg, GPRReg );1663 void cageTypedArrayStorage(GPRReg, GPRReg, bool validateAuth = true); 1664 1664 1665 1665 void recordSetLocal( -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r265000 r265151 5124 5124 5125 5125 m_jit.loadPtr(JITCompiler::Address(dataViewGPR, JSArrayBufferView::offsetOfVector()), t2); 5126 cageTypedArrayStorage(dataViewGPR, t2 );5126 cageTypedArrayStorage(dataViewGPR, t2, false); 5127 5127 5128 5128 m_jit.zeroExtend32ToWord(indexGPR, t1); … … 5325 5325 5326 5326 m_jit.loadPtr(JITCompiler::Address(dataViewGPR, JSArrayBufferView::offsetOfVector()), t2); 5327 cageTypedArrayStorage(dataViewGPR, t2 );5327 cageTypedArrayStorage(dataViewGPR, t2, false); 5328 5328 5329 5329 m_jit.zeroExtend32ToWord(indexGPR, t1); -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r265097 r265151 15939 15939 authenticate->appendSomeRegister(ptr); 15940 15940 authenticate->append(size, B3::ValueRep(B3::ValueRep::SomeLateRegister)); 15941 authenticate->numGPScratchRegisters = 1; 15941 15942 authenticate->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) { 15942 15943 jit.move(params[1].gpr(), params[0].gpr()); 15943 jit.untagArrayPtr(params[2].gpr(), params[0].gpr() );15944 jit.untagArrayPtr(params[2].gpr(), params[0].gpr(), true, params.gpScratch(0)); 15944 15945 }); 15945 15946 return authenticate; … … 15995 15996 LValue masked = m_out.bitAnd(ptr, mask); 15996 15997 LValue result = m_out.add(masked, basePtr); 15998 #if CPU(ARM64E) 15999 result = m_out.select( 16000 m_out.equal(ptr, m_out.constIntPtr(JSArrayBufferView::nullVectorPtr())), 16001 ptr, result); 16002 #endif 15997 16003 15998 16004 #if CPU(ARM64E) -
trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp
r263546 r265151 1140 1140 } 1141 1141 1142 void AssemblyHelpers::cageWithoutUntagging(Gigacage::Kind kind, GPRReg storage) 1143 { 1144 #if GIGACAGE_ENABLED 1145 if (!Gigacage::isEnabled(kind)) 1146 return; 1147 1148 #if CPU(ARM64E) 1149 RegisterID tempReg = InvalidGPRReg; 1150 Jump skip; 1151 if (kind == Gigacage::Primitive) { 1152 skip = branchPtr(Equal, storage, TrustedImmPtr(JSArrayBufferView::nullVectorPtr())); 1153 tempReg = getCachedMemoryTempRegisterIDAndInvalidate(); 1154 move(storage, tempReg); 1155 // Flip the registers since bitFieldInsert only inserts into the low bits. 1156 std::swap(storage, tempReg); 1157 } 1158 #endif 1159 andPtr(TrustedImmPtr(Gigacage::mask(kind)), storage); 1160 addPtr(TrustedImmPtr(Gigacage::basePtr(kind)), storage); 1161 #if CPU(ARM64E) 1162 if (kind == Gigacage::Primitive) 1163 bitFieldInsert64(storage, 0, 64 - numberOfPACBits, tempReg); 1164 if (skip.isSet()) 1165 skip.link(this); 1166 #endif 1167 1168 #else 1169 UNUSED_PARAM(kind); 1170 UNUSED_PARAM(storage); 1171 #endif 1172 } 1173 1174 // length may be the same register as scratch. 1175 void AssemblyHelpers::cageConditionallyAndUntag(Gigacage::Kind kind, GPRReg storage, GPRReg length, GPRReg scratch, bool validateAuth) 1176 { 1177 #if GIGACAGE_ENABLED 1178 if (Gigacage::isEnabled(kind)) { 1179 if (kind != Gigacage::Primitive || Gigacage::disablingPrimitiveGigacageIsForbidden()) 1180 cageWithoutUntagging(kind, storage); 1181 else { 1182 #if CPU(ARM64E) 1183 if (length == scratch) 1184 scratch = getCachedMemoryTempRegisterIDAndInvalidate(); 1185 #endif 1186 JumpList done; 1187 #if CPU(ARM64E) 1188 done.append(branchPtr(Equal, storage, TrustedImmPtr(JSArrayBufferView::nullVectorPtr()))); 1189 #endif 1190 done.append(branchTest8(NonZero, AbsoluteAddress(&Gigacage::disablePrimitiveGigacageRequested))); 1191 1192 loadPtr(Gigacage::addressOfBasePtr(kind), scratch); 1193 done.append(branchTest64(Zero, scratch)); 1194 #if CPU(ARM64E) 1195 GPRReg tempReg = getCachedDataTempRegisterIDAndInvalidate(); 1196 move(storage, tempReg); 1197 ASSERT(LogicalImmediate::create64(Gigacage::mask(kind)).isValid()); 1198 andPtr(TrustedImmPtr(Gigacage::mask(kind)), tempReg); 1199 addPtr(scratch, tempReg); 1200 bitFieldInsert64(tempReg, 0, 64 - numberOfPACBits, storage); 1201 #else 1202 andPtr(TrustedImmPtr(Gigacage::mask(kind)), storage); 1203 addPtr(scratch, storage); 1204 #endif // CPU(ARM64E) 1205 done.link(this); 1206 } 1207 } 1208 #endif 1209 1210 #if CPU(ARM64E) 1211 if (kind == Gigacage::Primitive) 1212 untagArrayPtr(length, storage, validateAuth, scratch); 1213 #endif 1214 UNUSED_PARAM(validateAuth); 1215 UNUSED_PARAM(kind); 1216 UNUSED_PARAM(storage); 1217 UNUSED_PARAM(length); 1218 UNUSED_PARAM(scratch); 1219 } 1220 1142 1221 } // namespace JSC 1143 1222 -
trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h
r263824 r265151 1733 1733 } 1734 1734 1735 void cageWithoutUntagging(Gigacage::Kind kind, GPRReg storage) 1736 { 1737 #if GIGACAGE_ENABLED 1738 if (!Gigacage::isEnabled(kind)) 1739 return; 1740 1741 #if CPU(ARM64E) 1742 RegisterID tempReg = InvalidGPRReg; 1743 if (kind == Gigacage::Primitive) { 1744 tempReg = getCachedMemoryTempRegisterIDAndInvalidate(); 1745 move(storage, tempReg); 1746 // Flip the registers since bitFieldInsert only inserts into the low bits. 1747 std::swap(storage, tempReg); 1748 } 1749 #endif 1750 andPtr(TrustedImmPtr(Gigacage::mask(kind)), storage); 1751 addPtr(TrustedImmPtr(Gigacage::basePtr(kind)), storage); 1752 #if CPU(ARM64E) 1753 if (kind == Gigacage::Primitive) 1754 bitFieldInsert64(storage, 0, 64 - numberOfPACBits, tempReg); 1755 #endif 1756 1757 #else 1758 UNUSED_PARAM(kind); 1759 UNUSED_PARAM(storage); 1760 #endif 1761 } 1762 1735 JS_EXPORT_PRIVATE void cageWithoutUntagging(Gigacage::Kind, GPRReg storage); 1763 1736 // length may be the same register as scratch. 1764 void cageConditionally(Gigacage::Kind kind, GPRReg storage, GPRReg length, GPRReg scratch) 1765 { 1766 #if GIGACAGE_ENABLED 1767 if (Gigacage::isEnabled(kind)) { 1768 if (kind != Gigacage::Primitive || Gigacage::disablingPrimitiveGigacageIsForbidden()) 1769 cageWithoutUntagging(kind, storage); 1770 else { 1771 #if CPU(ARM64E) 1772 if (length == scratch) 1773 scratch = getCachedMemoryTempRegisterIDAndInvalidate(); 1774 #endif 1775 JumpList done; 1776 done.append(branchTest8(NonZero, AbsoluteAddress(&Gigacage::disablePrimitiveGigacageRequested))); 1777 1778 loadPtr(Gigacage::addressOfBasePtr(kind), scratch); 1779 done.append(branchTest64(Zero, scratch)); 1780 #if CPU(ARM64E) 1781 GPRReg tempReg = getCachedDataTempRegisterIDAndInvalidate(); 1782 move(storage, tempReg); 1783 ASSERT(LogicalImmediate::create64(Gigacage::mask(kind)).isValid()); 1784 andPtr(TrustedImmPtr(Gigacage::mask(kind)), tempReg); 1785 addPtr(scratch, tempReg); 1786 bitFieldInsert64(tempReg, 0, 64 - numberOfPACBits, storage); 1787 #else 1788 andPtr(TrustedImmPtr(Gigacage::mask(kind)), storage); 1789 addPtr(scratch, storage); 1790 #endif // CPU(ARM64E) 1791 done.link(this); 1792 } 1793 } 1794 #endif 1795 1796 #if CPU(ARM64E) 1797 if (kind == Gigacage::Primitive) 1798 untagArrayPtr(length, storage); 1799 #endif 1800 UNUSED_PARAM(kind); 1801 UNUSED_PARAM(storage); 1802 UNUSED_PARAM(length); 1803 UNUSED_PARAM(scratch); 1804 } 1737 JS_EXPORT_PRIVATE void cageConditionallyAndUntag(Gigacage::Kind, GPRReg storage, GPRReg length, GPRReg scratch, bool validateAuth = true); 1805 1738 1806 1739 void emitComputeButterflyIndexingMask(GPRReg vectorLengthGPR, GPRReg scratchGPR, GPRReg resultGPR) -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
r265000 r265151 1631 1631 // path expects the base to be unclobbered. 1632 1632 loadPtr(Address(base, JSArrayBufferView::offsetOfVector()), lateScratch); 1633 cageConditionally (Gigacage::Primitive, lateScratch, lateScratch2, lateScratch2);1633 cageConditionallyAndUntag(Gigacage::Primitive, lateScratch, lateScratch2, lateScratch2, false); 1634 1634 1635 1635 if (isClamped(type)) { … … 1720 1720 // path expects the base to be unclobbered. 1721 1721 loadPtr(Address(base, JSArrayBufferView::offsetOfVector()), lateScratch); 1722 cageConditionally (Gigacage::Primitive, lateScratch, lateScratch2, lateScratch2);1722 cageConditionallyAndUntag(Gigacage::Primitive, lateScratch, lateScratch2, lateScratch2, false); 1723 1723 1724 1724 switch (elementSize(type)) { -
trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp
r264995 r265151 955 955 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), baseMemory); 956 956 957 jit.cageConditionally (Gigacage::Primitive, baseMemory, pinnedRegs->sizeRegister, scratchOrSize);957 jit.cageConditionallyAndUntag(Gigacage::Primitive, baseMemory, pinnedRegs->sizeRegister, scratchOrSize); 958 958 }); 959 959 … … 2301 2301 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*. 2302 2302 2303 jit.cageConditionally (Gigacage::Primitive, baseMemory, pinnedRegs.sizeRegister, scratchOrSize);2303 jit.cageConditionallyAndUntag(Gigacage::Primitive, baseMemory, pinnedRegs.sizeRegister, scratchOrSize); 2304 2304 }); 2305 2305 -
trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
r264995 r265151 581 581 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), baseMemory); 582 582 583 jit.cageConditionally (Gigacage::Primitive, baseMemory, pinnedRegs->sizeRegister, scratchOrSize);583 jit.cageConditionallyAndUntag(Gigacage::Primitive, baseMemory, pinnedRegs->sizeRegister, scratchOrSize); 584 584 }); 585 585 } … … 1855 1855 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*. 1856 1856 1857 jit.cageConditionally (Gigacage::Primitive, baseMemory, pinnedRegs.sizeRegister, scratchOrSize);1857 jit.cageConditionallyAndUntag(Gigacage::Primitive, baseMemory, pinnedRegs.sizeRegister, scratchOrSize); 1858 1858 }); 1859 1859 doContextSwitch->appendNewControlValue(m_proc, Jump, origin(), continuation); -
trunk/Source/JavaScriptCore/wasm/WasmBinding.cpp
r261755 r265151 73 73 jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size. 74 74 jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemory()), baseMemory); // Wasm::Memory::TaggedArrayStoragePtr<void> (void*). 75 jit.cageConditionally (Gigacage::Primitive, baseMemory, pinnedRegs.sizeRegister, scratchOrSize);75 jit.cageConditionallyAndUntag(Gigacage::Primitive, baseMemory, pinnedRegs.sizeRegister, scratchOrSize); 76 76 } 77 77 -
trunk/Source/JavaScriptCore/wasm/js/JSToWasm.cpp
r263824 r265151 238 238 239 239 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); 240 jit.cageConditionally (Gigacage::Primitive, baseMemory, scratchOrSize, scratchOrSize);240 jit.cageConditionallyAndUntag(Gigacage::Primitive, baseMemory, scratchOrSize, scratchOrSize); 241 241 } 242 242 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp
r264400 r265151 369 369 370 370 jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); 371 jit.cageConditionally (Gigacage::Primitive, baseMemory, scratchOrSize, scratchOrSize);371 jit.cageConditionallyAndUntag(Gigacage::Primitive, baseMemory, scratchOrSize, scratchOrSize); 372 372 } 373 373
Note: See TracChangeset
for help on using the changeset viewer.