Diff
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (228551 => 228552)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2018-02-16 05:27:39 UTC (rev 228552)
@@ -521,6 +521,7 @@
heap/MutatorState.h
heap/RegisterState.h
heap/RunningScope.h
+ heap/SecurityKind.h
heap/SecurityOriginToken.h
heap/SimpleMarkingConstraint.h
heap/SlotVisitor.h
Modified: trunk/Source/_javascript_Core/ChangeLog (228551 => 228552)
--- trunk/Source/_javascript_Core/ChangeLog 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-02-16 05:27:39 UTC (rev 228552)
@@ -1,3 +1,60 @@
+2018-02-15 Filip Pizlo <[email protected]>
+
+ Objects that contain dangerous things should be allocated far away from objects that can do OOB
+ https://bugs.webkit.org/show_bug.cgi?id=182843
+
+ Reviewed by Saam Barati.
+
+ To complete our object distancing plan, we need to put objects that can contain unpoisoned data
+ far away from objects that cannot. Objects referenceable from JSValues cannot contain
+ unpoisoned data, but auxiliary data can. This further divides auxiliary data that is meant for
+ storing mostly JSValues from data that is meant for storing anything.
+
+ This is achieved by having three SecurityKinds that are used for MarkedBlock selection and
+ zeroing sort of the same way SecurityOriginToken already was.
+
+ This change shouldn't make anything slower. If anything, it will be a small speed-up because it
+ removes some cases of MarkedBlock zeroing since we don't need to zero blocks used for two of
+ the SecurityKinds.
+
+ * Sources.txt:
+ * bytecode/ObjectAllocationProfileInlines.h:
+ (JSC::ObjectAllocationProfile::initializeProfile):
+ * heap/BlockDirectory.cpp:
+ (JSC::BlockDirectory::addBlock):
+ * heap/BlockDirectory.h:
+ * heap/CellAttributes.cpp:
+ (JSC::CellAttributes::dump const):
+ * heap/CellAttributes.h:
+ (JSC::CellAttributes::CellAttributes):
+ * heap/LocalAllocator.cpp:
+ (JSC::LocalAllocator::allocateSlowCase):
+ (JSC::LocalAllocator::tryAllocateWithoutCollecting):
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::Handle::didAddToDirectory):
+ (JSC::MarkedBlock::Handle::associateWithOrigin): Deleted.
+ * heap/MarkedBlock.h:
+ * heap/SecurityKind.cpp: Added.
+ (WTF::printInternal):
+ * heap/SecurityKind.h: Added.
+ * runtime/JSCellInlines.h:
+ (JSC::JSCell::subspaceFor):
+ * runtime/JSDestructibleObjectHeapCellType.cpp:
+ (JSC::JSDestructibleObjectHeapCellType::JSDestructibleObjectHeapCellType):
+ * runtime/JSObject.h:
+ (JSC::JSObject::subspaceFor):
+ * runtime/JSSegmentedVariableObjectHeapCellType.cpp:
+ (JSC::JSSegmentedVariableObjectHeapCellType::JSSegmentedVariableObjectHeapCellType):
+ * runtime/JSStringHeapCellType.cpp:
+ (JSC::JSStringHeapCellType::JSStringHeapCellType):
+ * runtime/Symbol.h:
+ (JSC::Symbol::subspaceFor):
+ * runtime/VM.cpp:
+ (JSC::VM::VM):
+ * runtime/VM.h:
+ * wasm/js/JSWebAssemblyCodeBlockHeapCellType.cpp:
+ (JSC::JSWebAssemblyCodeBlockHeapCellType::JSWebAssemblyCodeBlockHeapCellType):
+
2018-02-15 Darin Adler <[email protected]>
Web Inspector: get rid of remaining uses of OptOutput<T>
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (228551 => 228552)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2018-02-16 05:27:39 UTC (rev 228552)
@@ -334,6 +334,7 @@
0F5A6284188C98D40072C9DF /* FTLValueRange.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5A6282188C98D40072C9DF /* FTLValueRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F5AE2C41DF4F2800066EFE1 /* VMInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FE90BB3A1B7CF64E006B3F03 /* VMInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F5B4A331C84F0D600F1B17E /* SlowPathReturnType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5B4A321C84F0D600F1B17E /* SlowPathReturnType.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F5B6ED32036796B007AABF3 /* SecurityKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5B6ED120367968007AABF3 /* SecurityKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F5BF1641F2317120029D91D /* B3HoistLoopInvariantValues.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5BF1621F2317120029D91D /* B3HoistLoopInvariantValues.h */; };
0F5BF1671F23A0980029D91D /* B3BackwardsCFG.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5BF1661F23A0980029D91D /* B3BackwardsCFG.h */; };
0F5BF1691F23A0AA0029D91D /* B3NaturalLoops.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5BF1681F23A0AA0029D91D /* B3NaturalLoops.h */; };
@@ -2330,6 +2331,9 @@
0F5A6281188C98D40072C9DF /* FTLValueRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLValueRange.cpp; path = ftl/FTLValueRange.cpp; sourceTree = "<group>"; };
0F5A6282188C98D40072C9DF /* FTLValueRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLValueRange.h; path = ftl/FTLValueRange.h; sourceTree = "<group>"; };
0F5B4A321C84F0D600F1B17E /* SlowPathReturnType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlowPathReturnType.h; sourceTree = "<group>"; };
+ 0F5B6ED120367968007AABF3 /* SecurityKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecurityKind.h; sourceTree = "<group>"; };
+ 0F5B6ED220367968007AABF3 /* SecurityKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SecurityKind.cpp; sourceTree = "<group>"; };
+ 0F5B6ED42036799A007AABF3 /* SecurityOriginToken.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SecurityOriginToken.cpp; sourceTree = "<group>"; };
0F5BF1611F2317120029D91D /* B3HoistLoopInvariantValues.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = B3HoistLoopInvariantValues.cpp; path = b3/B3HoistLoopInvariantValues.cpp; sourceTree = "<group>"; };
0F5BF1621F2317120029D91D /* B3HoistLoopInvariantValues.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = B3HoistLoopInvariantValues.h; path = b3/B3HoistLoopInvariantValues.h; sourceTree = "<group>"; };
0F5BF1661F23A0980029D91D /* B3BackwardsCFG.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = B3BackwardsCFG.h; path = b3/B3BackwardsCFG.h; sourceTree = "<group>"; };
@@ -5698,6 +5702,9 @@
0FD0E5EF1E46BF230006AB08 /* RegisterState.h */,
0F7CF94E1DBEEE860098CC12 /* ReleaseHeapAccessScope.h */,
0F2C63A91E4FA42C00C13839 /* RunningScope.h */,
+ 0F5B6ED220367968007AABF3 /* SecurityKind.cpp */,
+ 0F5B6ED120367968007AABF3 /* SecurityKind.h */,
+ 0F5B6ED42036799A007AABF3 /* SecurityOriginToken.cpp */,
0F42B3C2201EC9FD00357031 /* SecurityOriginToken.h */,
0F4D8C761FCA3CF2001D32AC /* SimpleMarkingConstraint.cpp */,
0F4D8C771FCA3CF3001D32AC /* SimpleMarkingConstraint.h */,
@@ -8677,6 +8684,7 @@
0FEA0A201708B00700BB722C /* FTLTypedPointer.h in Headers */,
0FDB2CCA173DA523007B3C1B /* FTLValueFromBlock.h in Headers */,
0F5A6284188C98D40072C9DF /* FTLValueRange.h in Headers */,
+ 0F5B6ED32036796B007AABF3 /* SecurityKind.h in Headers */,
0F0332C618B53FA9005F979A /* FTLWeight.h in Headers */,
0F0332C818B546EC005F979A /* FTLWeightedTarget.h in Headers */,
0F666EC1183566F900D017F1 /* FullBytecodeLiveness.h in Headers */,
Modified: trunk/Source/_javascript_Core/Sources.txt (228551 => 228552)
--- trunk/Source/_javascript_Core/Sources.txt 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/Sources.txt 2018-02-16 05:27:39 UTC (rev 228552)
@@ -512,6 +512,7 @@
heap/MarkingConstraintSolver.cpp
heap/MutatorScheduler.cpp
heap/MutatorState.cpp
+heap/SecurityKind.cpp
heap/SecurityOriginToken.cpp
heap/SimpleMarkingConstraint.cpp
heap/SlotVisitor.cpp
Modified: trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfileInlines.h (228551 => 228552)
--- trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfileInlines.h 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfileInlines.h 2018-02-16 05:27:39 UTC (rev 228552)
@@ -99,7 +99,7 @@
ASSERT(inlineCapacity <= JSFinalObject::maxInlineCapacity());
size_t allocationSize = JSFinalObject::allocationSize(inlineCapacity);
- Allocator allocator = vm.cellSpace.allocatorForNonVirtual(allocationSize, AllocatorForMode::EnsureAllocator);
+ Allocator allocator = subspaceFor<JSFinalObject>(vm)->allocatorForNonVirtual(allocationSize, AllocatorForMode::EnsureAllocator);
// Take advantage of extra inline capacity available in the size class.
if (allocator) {
Modified: trunk/Source/_javascript_Core/heap/BlockDirectory.cpp (228551 => 228552)
--- trunk/Source/_javascript_Core/heap/BlockDirectory.cpp 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/heap/BlockDirectory.cpp 2018-02-16 05:27:39 UTC (rev 228552)
@@ -110,7 +110,7 @@
return handle;
}
-void BlockDirectory::addBlock(MarkedBlock::Handle* block)
+void BlockDirectory::addBlock(MarkedBlock::Handle* block, SecurityOriginToken securityOriginToken)
{
size_t index;
if (m_freeBlockIndices.isEmpty()) {
@@ -148,7 +148,7 @@
});
// This is the point at which the block learns of its cellSize() and attributes().
- block->didAddToDirectory(this, index);
+ block->didAddToDirectory(this, index, securityOriginToken);
setIsLive(NoLockingNecessary, index, true);
setIsEmpty(NoLockingNecessary, index, true);
Modified: trunk/Source/_javascript_Core/heap/BlockDirectory.h (228551 => 228552)
--- trunk/Source/_javascript_Core/heap/BlockDirectory.h 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/heap/BlockDirectory.h 2018-02-16 05:27:39 UTC (rev 228552)
@@ -110,7 +110,7 @@
RefPtr<SharedTask<MarkedBlock::Handle*()>> parallelNotEmptyBlockSource();
- void addBlock(MarkedBlock::Handle*);
+ void addBlock(MarkedBlock::Handle*, SecurityOriginToken);
void removeBlock(MarkedBlock::Handle*);
bool isPagedOut(MonotonicTime deadline);
Modified: trunk/Source/_javascript_Core/heap/CellAttributes.cpp (228551 => 228552)
--- trunk/Source/_javascript_Core/heap/CellAttributes.cpp 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/heap/CellAttributes.cpp 2018-02-16 05:27:39 UTC (rev 228552)
@@ -32,7 +32,7 @@
void CellAttributes::dump(PrintStream& out) const
{
- out.print("{", destruction, ", ", cellKind, "}");
+ out.print("{", destruction, ", ", cellKind, ", ", securityKind, "}");
}
} // namespace JSC
Modified: trunk/Source/_javascript_Core/heap/CellAttributes.h (228551 => 228552)
--- trunk/Source/_javascript_Core/heap/CellAttributes.h 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/heap/CellAttributes.h 2018-02-16 05:27:39 UTC (rev 228552)
@@ -27,6 +27,7 @@
#include "DestructionMode.h"
#include "HeapCell.h"
+#include "SecurityKind.h"
#include <wtf/PrintStream.h>
namespace JSC {
@@ -34,9 +35,10 @@
struct CellAttributes {
CellAttributes() { }
- CellAttributes(DestructionMode destruction, HeapCell::Kind cellKind)
+ CellAttributes(DestructionMode destruction, HeapCell::Kind cellKind, SecurityKind securityKind)
: destruction(destruction)
, cellKind(cellKind)
+ , securityKind(securityKind)
{
}
@@ -44,6 +46,7 @@
DestructionMode destruction { DoesNotNeedDestruction };
HeapCell::Kind cellKind { HeapCell::JSCell };
+ SecurityKind securityKind { SecurityKind::DangerousBits };
};
} // namespace JSC
Modified: trunk/Source/_javascript_Core/heap/LocalAllocator.cpp (228551 => 228552)
--- trunk/Source/_javascript_Core/heap/LocalAllocator.cpp 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/heap/LocalAllocator.cpp 2018-02-16 05:27:39 UTC (rev 228552)
@@ -177,8 +177,7 @@
else
return nullptr;
}
- block->associateWithOrigin(m_tlc->securityOriginToken());
- m_directory->addBlock(block);
+ m_directory->addBlock(block, m_tlc->securityOriginToken());
result = allocateIn(block);
ASSERT(result);
return result;
@@ -234,8 +233,7 @@
// because there is a remote chance that a block may have both canAllocateButNotEmpty
// and empty set at the same time.
block->removeFromDirectory();
- block->associateWithOrigin(m_tlc->securityOriginToken());
- m_directory->addBlock(block);
+ m_directory->addBlock(block, m_tlc->securityOriginToken());
return allocateIn(block);
}
}
Modified: trunk/Source/_javascript_Core/heap/MarkedBlock.cpp (228551 => 228552)
--- trunk/Source/_javascript_Core/heap/MarkedBlock.cpp 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/heap/MarkedBlock.cpp 2018-02-16 05:27:39 UTC (rev 228552)
@@ -334,7 +334,7 @@
m_directory->removeBlock(this);
}
-void MarkedBlock::Handle::didAddToDirectory(BlockDirectory* directory, size_t index)
+void MarkedBlock::Handle::didAddToDirectory(BlockDirectory* directory, size_t index, SecurityOriginToken securityOriginToken)
{
ASSERT(m_index == std::numeric_limits<size_t>::max());
ASSERT(!m_directory);
@@ -349,7 +349,20 @@
m_atomsPerCell = (cellSize + atomSize - 1) / atomSize;
m_endAtom = endAtom - m_atomsPerCell + 1;
+ if (directory->attributes().securityKind == SecurityKind::JSValueOOB) {
+ // If we are going to be used for JSValueOOB allocations, then we may need to zero the block.
+ // We don't have to zero it if it was already used for JSValues in the same security origin.
+ // It's tempting to say that this means that we don't have to zero it if it's coming from
+ // JSValueStrict, but since JSValueStrict doesn't zero when converting from DangerousBits, that
+ // would not be sound.
+
+ if (m_attributes.securityKind != SecurityKind::JSValueOOB
+ || m_securityOriginToken != securityOriginToken)
+ fastZeroFillBytes(&block(), m_endAtom * atomSize);
+ }
+
m_attributes = directory->attributes();
+ m_securityOriginToken = securityOriginToken;
if (m_attributes.cellKind != HeapCell::JSCell)
RELEASE_ASSERT(m_attributes.destruction == DoesNotNeedDestruction);
@@ -488,15 +501,6 @@
return m_directory->isFreeListedCell(target);
}
-void MarkedBlock::Handle::associateWithOrigin(SecurityOriginToken securityOriginToken)
-{
- if (m_securityOriginToken == securityOriginToken)
- return;
-
- fastZeroFillBytes(&block(), endAtom * atomSize);
- m_securityOriginToken = securityOriginToken;
-}
-
} // namespace JSC
namespace WTF {
Modified: trunk/Source/_javascript_Core/heap/MarkedBlock.h (228551 => 228552)
--- trunk/Source/_javascript_Core/heap/MarkedBlock.h 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/heap/MarkedBlock.h 2018-02-16 05:27:39 UTC (rev 228552)
@@ -190,12 +190,11 @@
void removeFromDirectory();
- void didAddToDirectory(BlockDirectory*, size_t index);
+ void didAddToDirectory(BlockDirectory*, size_t index, SecurityOriginToken);
void didRemoveFromDirectory();
void dumpState(PrintStream&);
- void associateWithOrigin(SecurityOriginToken);
SecurityOriginToken securityOriginToken() const { return m_securityOriginToken; }
private:
Added: trunk/Source/_javascript_Core/heap/SecurityKind.cpp (0 => 228552)
--- trunk/Source/_javascript_Core/heap/SecurityKind.cpp (rev 0)
+++ trunk/Source/_javascript_Core/heap/SecurityKind.cpp 2018-02-16 05:27:39 UTC (rev 228552)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include "config.h"
+#include "SecurityKind.h"
+
+#include <wtf/Assertions.h>
+#include <wtf/PrintStream.h>
+
+namespace WTF {
+
+void printInternal(PrintStream& out, JSC::SecurityKind securityKind)
+{
+ switch (securityKind) {
+ case JSC::SecurityKind::JSValueOOB:
+ out.print("JSValueOOB");
+ return;
+ case JSC::SecurityKind::JSValueStrict:
+ out.print("JSValueStrict");
+ return;
+ case JSC::SecurityKind::DangerousBits:
+ out.print("DangerousBits");
+ return;
+ }
+ RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
Added: trunk/Source/_javascript_Core/heap/SecurityKind.h (0 => 228552)
--- trunk/Source/_javascript_Core/heap/SecurityKind.h (rev 0)
+++ trunk/Source/_javascript_Core/heap/SecurityKind.h 2018-02-16 05:27:39 UTC (rev 228552)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 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
+
+namespace JSC {
+
+enum class SecurityKind : uint8_t {
+ // The JSValueOOB security kind is for cells that contain JValues and can be accessed out-of-bounds
+ // up to minimumDistanceBetweenCellsFromDifferentOrigins.
+ //
+ // JSValues can reference cells in JSValueOOB. Therefore, JSValues can only reference cells in
+ // JSValueOOB - otherwise a Spectre OOB attack would be able to violate the rules of JSValueStrict
+ // and DangerousBits.
+ //
+ // The OOB space is the space that depends on the heap's distancing to do OOB protection.
+ JSValueOOB,
+
+ // The JSValueStrict security kind is for cells that contain JSValues but cannot be accessed
+ // out-of-bounds. Currently, it's not essential to keep this separate from DangerousBits. We're
+ // using this to get some wiggle room for how we handle array elements. For example, we might want
+ // to allow OOB reads but not OOB writes.
+ //
+ // It's illegal to use this for any subclass of JSObject, JSString, or Symbol, or any other cell
+ // that could be referenced from a JSValue. You must use poisoned pointers to point at these cells.
+ JSValueStrict,
+
+ // The DangerousBits security kind is for cells that contain values that could be usefully type-
+ // confused with JSValue.
+ //
+ // It's illegal to use this for any subclass of JSObject, JSString, or Symbol, or any other cell
+ // that could be referenced from a JSValue. You must use poisoned pointers to point at these cells.
+ DangerousBits
+};
+
+} // namespace JSC
+
+namespace WTF {
+
+class PrintStream;
+
+void printInternal(PrintStream&, JSC::SecurityKind);
+
+} // namespace WTF
+
Modified: trunk/Source/_javascript_Core/runtime/JSCellInlines.h (228551 => 228552)
--- trunk/Source/_javascript_Core/runtime/JSCellInlines.h 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/runtime/JSCellInlines.h 2018-02-16 05:27:39 UTC (rev 228552)
@@ -139,7 +139,7 @@
{
if (CellType::needsDestruction)
return &vm.destructibleCellSpace;
- return &vm.cellSpace;
+ return &vm.cellDangerousBitsSpace;
}
template<typename T>
Modified: trunk/Source/_javascript_Core/runtime/JSDestructibleObjectHeapCellType.cpp (228551 => 228552)
--- trunk/Source/_javascript_Core/runtime/JSDestructibleObjectHeapCellType.cpp 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/runtime/JSDestructibleObjectHeapCellType.cpp 2018-02-16 05:27:39 UTC (rev 228552)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -39,7 +39,7 @@
};
JSDestructibleObjectHeapCellType::JSDestructibleObjectHeapCellType()
- : HeapCellType(CellAttributes(NeedsDestruction, HeapCell::JSCell))
+ : HeapCellType(CellAttributes(NeedsDestruction, HeapCell::JSCell, SecurityKind::JSValueOOB))
{
}
Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (228551 => 228552)
--- trunk/Source/_javascript_Core/runtime/JSObject.h 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h 2018-02-16 05:27:39 UTC (rev 228552)
@@ -104,6 +104,12 @@
public:
typedef JSCell Base;
+ template<typename>
+ static CompleteSubspace* subspaceFor(VM& vm)
+ {
+ return &vm.cellJSValueOOBSpace;
+ }
+
// This is a super dangerous method for JITs. Sometimes the JITs will want to create either a
// JSFinalObject or a JSArray. This is the method that will do that.
static JSObject* createRawObject(ExecState* exec, Structure* structure, Butterfly* = nullptr);
Modified: trunk/Source/_javascript_Core/runtime/JSSegmentedVariableObjectHeapCellType.cpp (228551 => 228552)
--- trunk/Source/_javascript_Core/runtime/JSSegmentedVariableObjectHeapCellType.cpp 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/runtime/JSSegmentedVariableObjectHeapCellType.cpp 2018-02-16 05:27:39 UTC (rev 228552)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -39,7 +39,7 @@
};
JSSegmentedVariableObjectHeapCellType::JSSegmentedVariableObjectHeapCellType()
- : HeapCellType(CellAttributes(NeedsDestruction, HeapCell::JSCell))
+ : HeapCellType(CellAttributes(NeedsDestruction, HeapCell::JSCell, SecurityKind::JSValueOOB))
{
}
Modified: trunk/Source/_javascript_Core/runtime/JSStringHeapCellType.cpp (228551 => 228552)
--- trunk/Source/_javascript_Core/runtime/JSStringHeapCellType.cpp 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/runtime/JSStringHeapCellType.cpp 2018-02-16 05:27:39 UTC (rev 228552)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -39,7 +39,7 @@
};
JSStringHeapCellType::JSStringHeapCellType()
- : HeapCellType(CellAttributes(NeedsDestruction, HeapCell::JSCell))
+ : HeapCellType(CellAttributes(NeedsDestruction, HeapCell::JSCell, SecurityKind::JSValueOOB))
{
}
Modified: trunk/Source/_javascript_Core/runtime/Symbol.h (228551 => 228552)
--- trunk/Source/_javascript_Core/runtime/Symbol.h 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/runtime/Symbol.h 2018-02-16 05:27:39 UTC (rev 228552)
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2018 Apple Inc. All rights reserved.
* Copyright (C) 2015-2016 Yusuke Suzuki <[email protected]>.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,6 +36,12 @@
typedef JSCell Base;
static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal | OverridesToThis;
+ template<typename>
+ static CompleteSubspace* subspaceFor(VM& vm)
+ {
+ return &vm.cellJSValueOOBSpace;
+ }
+
DECLARE_EXPORT_INFO;
static const bool needsDestruction = true;
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (228551 => 228552)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2018-02-16 05:27:39 UTC (rev 228552)
@@ -234,9 +234,11 @@
, fastMallocAllocator(std::make_unique<FastMallocAlignedMemoryAllocator>())
, primitiveGigacageAllocator(std::make_unique<GigacageAlignedMemoryAllocator>(Gigacage::Primitive))
, jsValueGigacageAllocator(std::make_unique<GigacageAlignedMemoryAllocator>(Gigacage::JSValue))
- , auxiliaryHeapCellType(std::make_unique<HeapCellType>(CellAttributes(DoesNotNeedDestruction, HeapCell::Auxiliary)))
- , cellHeapCellType(std::make_unique<HeapCellType>(CellAttributes(DoesNotNeedDestruction, HeapCell::JSCell)))
- , destructibleCellHeapCellType(std::make_unique<HeapCellType>(CellAttributes(NeedsDestruction, HeapCell::JSCell)))
+ , auxiliaryJSValueStrictHeapCellType(std::make_unique<HeapCellType>(CellAttributes(DoesNotNeedDestruction, HeapCell::Auxiliary, SecurityKind::JSValueStrict)))
+ , auxiliaryDangerousBitsHeapCellType(std::make_unique<HeapCellType>(CellAttributes(DoesNotNeedDestruction, HeapCell::Auxiliary, SecurityKind::DangerousBits)))
+ , cellJSValueOOBHeapCellType(std::make_unique<HeapCellType>(CellAttributes(DoesNotNeedDestruction, HeapCell::JSCell, SecurityKind::JSValueOOB)))
+ , cellDangerousBitsHeapCellType(std::make_unique<HeapCellType>(CellAttributes(DoesNotNeedDestruction, HeapCell::JSCell, SecurityKind::JSValueOOB)))
+ , destructibleCellHeapCellType(std::make_unique<HeapCellType>(CellAttributes(NeedsDestruction, HeapCell::JSCell, SecurityKind::DangerousBits)))
, stringHeapCellType(std::make_unique<JSStringHeapCellType>())
, destructibleObjectHeapCellType(std::make_unique<JSDestructibleObjectHeapCellType>())
, segmentedVariableObjectHeapCellType(std::make_unique<JSSegmentedVariableObjectHeapCellType>())
@@ -243,10 +245,11 @@
#if ENABLE(WEBASSEMBLY)
, webAssemblyCodeBlockHeapCellType(std::make_unique<JSWebAssemblyCodeBlockHeapCellType>())
#endif
- , primitiveGigacageAuxiliarySpace("Primitive Gigacage Auxiliary", heap, auxiliaryHeapCellType.get(), primitiveGigacageAllocator.get())
- , jsValueGigacageAuxiliarySpace("JSValue Gigacage Auxiliary", heap, auxiliaryHeapCellType.get(), jsValueGigacageAllocator.get())
- , cellSpace("JSCell", heap, cellHeapCellType.get(), fastMallocAllocator.get())
- , jsValueGigacageCellSpace("JSValue Gigacage JSCell", heap, cellHeapCellType.get(), jsValueGigacageAllocator.get())
+ , primitiveGigacageAuxiliarySpace("Primitive Gigacage Auxiliary", heap, auxiliaryDangerousBitsHeapCellType.get(), primitiveGigacageAllocator.get())
+ , jsValueGigacageAuxiliarySpace("JSValue Gigacage Auxiliary", heap, auxiliaryJSValueStrictHeapCellType.get(), jsValueGigacageAllocator.get())
+ , cellJSValueOOBSpace("JSCell JSValueOOB", heap, cellJSValueOOBHeapCellType.get(), fastMallocAllocator.get())
+ , cellDangerousBitsSpace("JSCell DangerousBits", heap, cellDangerousBitsHeapCellType.get(), fastMallocAllocator.get())
+ , jsValueGigacageCellSpace("JSValue Gigacage JSCell", heap, cellJSValueOOBHeapCellType.get(), jsValueGigacageAllocator.get())
, destructibleCellSpace("Destructible JSCell", heap, destructibleCellHeapCellType.get(), fastMallocAllocator.get())
, stringSpace("JSString", heap, stringHeapCellType.get(), fastMallocAllocator.get())
, destructibleObjectSpace("JSDestructibleObject", heap, destructibleObjectHeapCellType.get(), fastMallocAllocator.get())
@@ -255,21 +258,21 @@
#if ENABLE(WEBASSEMBLY)
, webAssemblyCodeBlockSpace("JSWebAssemblyCodeBlockSpace", heap, webAssemblyCodeBlockHeapCellType.get(), fastMallocAllocator.get())
#endif
- , asyncFunctionSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), JSAsyncFunction)
- , asyncGeneratorFunctionSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), JSAsyncGeneratorFunction)
- , boundFunctionSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), JSBoundFunction)
- , customGetterSetterFunctionSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), JSCustomGetterSetterFunction)
+ , asyncFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSAsyncFunction)
+ , asyncGeneratorFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSAsyncGeneratorFunction)
+ , boundFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSBoundFunction)
+ , customGetterSetterFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSCustomGetterSetterFunction)
, directEvalExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), DirectEvalExecutable)
- , executableToCodeBlockEdgeSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), ExecutableToCodeBlockEdge)
+ , executableToCodeBlockEdgeSpace ISO_SUBSPACE_INIT(heap, cellDangerousBitsHeapCellType.get(), ExecutableToCodeBlockEdge)
, functionExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), FunctionExecutable)
- , functionSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), JSFunction)
- , generatorFunctionSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), JSGeneratorFunction)
+ , functionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSFunction)
+ , generatorFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSGeneratorFunction)
, indirectEvalExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), IndirectEvalExecutable)
, inferredTypeSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), InferredType)
, inferredValueSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), InferredValue)
, moduleProgramExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), ModuleProgramExecutable)
, nativeExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), NativeExecutable)
- , nativeStdFunctionSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), JSNativeStdFunction)
+ , nativeStdFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSNativeStdFunction)
, programExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), ProgramExecutable)
, propertyTableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), PropertyTable)
, structureRareDataSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), StructureRareData)
@@ -277,8 +280,8 @@
, weakSetSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), JSWeakSet)
, weakMapSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), JSWeakMap)
#if ENABLE(WEBASSEMBLY)
- , webAssemblyFunctionSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), WebAssemblyFunction)
- , webAssemblyWrapperFunctionSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), WebAssemblyWrapperFunction)
+ , webAssemblyFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), WebAssemblyFunction)
+ , webAssemblyWrapperFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), WebAssemblyWrapperFunction)
#endif
, executableToCodeBlockEdgesWithConstraints(executableToCodeBlockEdgeSpace)
, executableToCodeBlockEdgesWithFinalizers(executableToCodeBlockEdgeSpace)
Modified: trunk/Source/_javascript_Core/runtime/VM.h (228551 => 228552)
--- trunk/Source/_javascript_Core/runtime/VM.h 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2018-02-16 05:27:39 UTC (rev 228552)
@@ -292,8 +292,10 @@
std::unique_ptr<GigacageAlignedMemoryAllocator> primitiveGigacageAllocator;
std::unique_ptr<GigacageAlignedMemoryAllocator> jsValueGigacageAllocator;
- std::unique_ptr<HeapCellType> auxiliaryHeapCellType;
- std::unique_ptr<HeapCellType> cellHeapCellType;
+ std::unique_ptr<HeapCellType> auxiliaryJSValueStrictHeapCellType;
+ std::unique_ptr<HeapCellType> auxiliaryDangerousBitsHeapCellType;
+ std::unique_ptr<HeapCellType> cellJSValueOOBHeapCellType;
+ std::unique_ptr<HeapCellType> cellDangerousBitsHeapCellType;
std::unique_ptr<HeapCellType> destructibleCellHeapCellType;
std::unique_ptr<JSStringHeapCellType> stringHeapCellType;
std::unique_ptr<JSDestructibleObjectHeapCellType> destructibleObjectHeapCellType;
@@ -326,8 +328,9 @@
}
// Whenever possible, use subspaceFor<CellType>(vm) to get one of these subspaces.
- CompleteSubspace cellSpace;
- CompleteSubspace jsValueGigacageCellSpace;
+ CompleteSubspace cellJSValueOOBSpace;
+ CompleteSubspace cellDangerousBitsSpace;
+ CompleteSubspace jsValueGigacageCellSpace; // FIXME: This space is problematic because we have things in here like DirectArguments and ScopedArguments; those should be split into JSValueOOB cells and JSValueStrict auxiliaries. https://bugs.webkit.org/show_bug.cgi?id=182858
CompleteSubspace destructibleCellSpace;
CompleteSubspace stringSpace;
CompleteSubspace destructibleObjectSpace;
Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyCodeBlockHeapCellType.cpp (228551 => 228552)
--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyCodeBlockHeapCellType.cpp 2018-02-16 04:27:43 UTC (rev 228551)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyCodeBlockHeapCellType.cpp 2018-02-16 05:27:39 UTC (rev 228552)
@@ -43,7 +43,7 @@
};
JSWebAssemblyCodeBlockHeapCellType::JSWebAssemblyCodeBlockHeapCellType()
- : HeapCellType(CellAttributes(NeedsDestruction, HeapCell::JSCell))
+ : HeapCellType(CellAttributes(NeedsDestruction, HeapCell::JSCell, SecurityKind::DangerousBits))
{
}