Skip to content

Commit b97ba99

Browse files
WebAssembly: poison JS object's secrets
https://bugs.webkit.org/show_bug.cgi?id=181339 <rdar://problem/36325001> Reviewed by Mark Lam. Source/JavaScriptCore: Separating WebAssembly's JS objects from their non-JS implementation means that all interesting information lives outside of the JS object itself. This patch poisons each JS object's pointer to non-JS implementation using the poisoning mechanism and a unique key per JS object type origin. * runtime/JSCPoison.h: * wasm/js/JSToWasm.cpp: (JSC::Wasm::createJSToWasmWrapper): JS -> wasm stores the JS object in a stack slot when fast TLS is disabled. This requires that we unpoison the Wasm::Instance. * wasm/js/JSWebAssemblyCodeBlock.h: * wasm/js/JSWebAssemblyInstance.h: (JSC::JSWebAssemblyInstance::offsetOfPoisonedInstance): renamed to be explicit that the pointer is poisoned. * wasm/js/JSWebAssemblyMemory.h: * wasm/js/JSWebAssemblyModule.h: * wasm/js/JSWebAssemblyTable.h: Source/WTF: swapping a poisoned pointer with a non-poisoned one (as is done in JSWebAssembyMemory::adopt) was missing. * wtf/Poisoned.h: (WTF::PoisonedImpl::swap): (WTF::ConstExprPoisonedPtrTraits::swap): Tools: Update tests for swap(Poisoned<k, T>, T*) * TestWebKitAPI/Tests/WTF/ConstExprPoisoned.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/Poisoned.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/PoisonedRef.cpp: (TestWebKitAPI::TEST): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@226485 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent a1b7310 commit b97ba99

14 files changed

+187
-19
lines changed

Source/JavaScriptCore/ChangeLog

+27
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,30 @@
1+
2018-01-05 JF Bastien <[email protected]>
2+
3+
WebAssembly: poison JS object's secrets
4+
https://bugs.webkit.org/show_bug.cgi?id=181339
5+
<rdar://problem/36325001>
6+
7+
Reviewed by Mark Lam.
8+
9+
Separating WebAssembly's JS objects from their non-JS
10+
implementation means that all interesting information lives
11+
outside of the JS object itself. This patch poisons each JS
12+
object's pointer to non-JS implementation using the poisoning
13+
mechanism and a unique key per JS object type origin.
14+
15+
* runtime/JSCPoison.h:
16+
* wasm/js/JSToWasm.cpp:
17+
(JSC::Wasm::createJSToWasmWrapper): JS -> wasm stores the JS
18+
object in a stack slot when fast TLS is disabled. This requires
19+
that we unpoison the Wasm::Instance.
20+
* wasm/js/JSWebAssemblyCodeBlock.h:
21+
* wasm/js/JSWebAssemblyInstance.h:
22+
(JSC::JSWebAssemblyInstance::offsetOfPoisonedInstance): renamed to
23+
be explicit that the pointer is poisoned.
24+
* wasm/js/JSWebAssemblyMemory.h:
25+
* wasm/js/JSWebAssemblyModule.h:
26+
* wasm/js/JSWebAssemblyTable.h:
27+
128
2018-01-05 Michael Saboff <[email protected]>
229

330
Add ability to disable indexed property masking for testing

Source/JavaScriptCore/runtime/JSCPoison.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017 Apple Inc. All rights reserved.
2+
* Copyright (C) 2017-2018 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -31,6 +31,11 @@ namespace JSC {
3131

3232
enum Poison {
3333
NotPoisoned = 0,
34+
JSWebAssemblyCodeBlockPoison,
35+
JSWebAssemblyInstancePoison,
36+
JSWebAssemblyMemoryPoison,
37+
JSWebAssemblyModulePoison,
38+
JSWebAssemblyTablePoison,
3439
TransitionMapPoison,
3540
WeakImplPoison,
3641
};

Source/JavaScriptCore/wasm/js/JSToWasm.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2016-2017 Apple Inc. All rights reserved.
2+
* Copyright (C) 2016-2018 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -117,7 +117,9 @@ std::unique_ptr<InternalFunction> createJSToWasmWrapper(CompilationContext& comp
117117
// Wasm::Context*'s instance.
118118
if (!Context::useFastTLS()) {
119119
jit.loadPtr(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), wasmContextInstanceGPR);
120-
jit.loadPtr(CCallHelpers::Address(wasmContextInstanceGPR, JSWebAssemblyInstance::offsetOfInstance()), wasmContextInstanceGPR);
120+
jit.loadPtr(CCallHelpers::Address(wasmContextInstanceGPR, JSWebAssemblyInstance::offsetOfPoisonedInstance()), wasmContextInstanceGPR);
121+
jit.move(CCallHelpers::TrustedImm64(makeConstExprPoison(JSWebAssemblyInstancePoison)), scratchReg);
122+
jit.xor64(scratchReg, wasmContextInstanceGPR);
121123
jsOffset += sizeof(EncodedJSValue);
122124
}
123125

Source/JavaScriptCore/wasm/js/JSWebAssemblyCodeBlock.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017 Apple Inc. All rights reserved.
2+
* Copyright (C) 2017-2018 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
2828
#if ENABLE(WEBASSEMBLY)
2929

3030
#include "CallLinkInfo.h"
31+
#include "JSCPoison.h"
3132
#include "JSCell.h"
3233
#include "PromiseDeferredTimer.h"
3334
#include "Structure.h"
@@ -36,6 +37,7 @@
3637
#include "WasmFormat.h"
3738
#include "WasmModule.h"
3839
#include <wtf/Bag.h>
40+
#include <wtf/Ref.h>
3941
#include <wtf/Vector.h>
4042

4143
namespace JSC {
@@ -90,7 +92,7 @@ class JSWebAssemblyCodeBlock final : public JSCell {
9092
void finalizeUnconditionally() override;
9193
};
9294

93-
Ref<Wasm::CodeBlock> m_codeBlock;
95+
PoisonedRef<JSWebAssemblyCodeBlockPoison, Wasm::CodeBlock> m_codeBlock;
9496
Vector<MacroAssemblerCodeRef> m_wasmToJSExitStubs;
9597
UnconditionalFinalizer m_unconditionalFinalizer;
9698
Bag<CallLinkInfo> m_callLinkInfos;

Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2016-2017 Apple Inc. All rights reserved.
2+
* Copyright (C) 2016-2018 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -27,12 +27,14 @@
2727

2828
#if ENABLE(WEBASSEMBLY)
2929

30+
#include "JSCPoison.h"
3031
#include "JSDestructibleObject.h"
3132
#include "JSObject.h"
3233
#include "JSWebAssemblyCodeBlock.h"
3334
#include "JSWebAssemblyMemory.h"
3435
#include "JSWebAssemblyTable.h"
3536
#include "WasmInstance.h"
37+
#include <wtf/Ref.h>
3638

3739
namespace JSC {
3840

@@ -74,7 +76,7 @@ class JSWebAssemblyInstance : public JSDestructibleObject {
7476
instance().setTable(makeRef(*table()->table()));
7577
}
7678

77-
static size_t offsetOfInstance() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_instance); }
79+
static size_t offsetOfPoisonedInstance() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_instance); }
7880
static size_t offsetOfCallee() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_callee); }
7981

8082
protected:
@@ -86,7 +88,7 @@ class JSWebAssemblyInstance : public JSDestructibleObject {
8688
private:
8789
JSWebAssemblyModule* module() const { return m_module.get(); }
8890

89-
Ref<Wasm::Instance> m_instance;
91+
PoisonedRef<JSWebAssemblyInstancePoison, Wasm::Instance> m_instance;
9092

9193
WriteBarrier<JSWebAssemblyModule> m_module;
9294
WriteBarrier<JSWebAssemblyCodeBlock> m_codeBlock;

Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2016-2017 Apple Inc. All rights reserved.
2+
* Copyright (C) 2016-2018 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -27,9 +27,11 @@
2727

2828
#if ENABLE(WEBASSEMBLY)
2929

30+
#include "JSCPoison.h"
3031
#include "JSDestructibleObject.h"
3132
#include "JSObject.h"
3233
#include "WasmMemory.h"
34+
#include <wtf/Ref.h>
3335
#include <wtf/RefPtr.h>
3436

3537
namespace JSC {
@@ -65,9 +67,9 @@ class JSWebAssemblyMemory : public JSDestructibleObject {
6567
static void destroy(JSCell*);
6668
static void visitChildren(JSCell*, SlotVisitor&);
6769

68-
Ref<Wasm::Memory> m_memory;
70+
PoisonedRef<JSWebAssemblyMemoryPoison, Wasm::Memory> m_memory;
6971
WriteBarrier<JSArrayBuffer> m_bufferWrapper;
70-
RefPtr<ArrayBuffer> m_buffer;
72+
PoisonedRefPtr<JSWebAssemblyMemoryPoison, ArrayBuffer> m_buffer;
7173
};
7274

7375
} // namespace JSC

Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2016-2017 Apple Inc. All rights reserved.
2+
* Copyright (C) 2016-2018 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -27,13 +27,15 @@
2727

2828
#if ENABLE(WEBASSEMBLY)
2929

30+
#include "JSCPoison.h"
3031
#include "JSDestructibleObject.h"
3132
#include "JSObject.h"
3233
#include "UnconditionalFinalizer.h"
3334
#include "WasmMemoryMode.h"
3435
#include <wtf/Bag.h>
3536
#include <wtf/Expected.h>
3637
#include <wtf/Forward.h>
38+
#include <wtf/Ref.h>
3739
#include <wtf/text/WTFString.h>
3840

3941
namespace JSC {
@@ -79,7 +81,7 @@ class JSWebAssemblyModule : public JSDestructibleObject {
7981
static void destroy(JSCell*);
8082
static void visitChildren(JSCell*, SlotVisitor&);
8183

82-
Ref<Wasm::Module> m_module;
84+
PoisonedRef<JSWebAssemblyModulePoison, Wasm::Module> m_module;
8385
WriteBarrier<SymbolTable> m_exportSymbolTable;
8486
WriteBarrier<JSWebAssemblyCodeBlock> m_codeBlocks[Wasm::NumberOfMemoryModes];
8587
WriteBarrier<WebAssemblyToJSCallee> m_callee;

Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2016-2017 Apple Inc. All rights reserved.
2+
* Copyright (C) 2016-2018 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -27,13 +27,15 @@
2727

2828
#if ENABLE(WEBASSEMBLY)
2929

30+
#include "JSCPoison.h"
3031
#include "JSDestructibleObject.h"
3132
#include "JSObject.h"
3233
#include "WasmLimits.h"
3334
#include "WasmTable.h"
3435
#include "WebAssemblyWrapperFunction.h"
3536
#include "WebAssemblyFunction.h"
3637
#include <wtf/MallocPtr.h>
38+
#include <wtf/Ref.h>
3739

3840
namespace JSC {
3941

@@ -63,7 +65,7 @@ class JSWebAssemblyTable : public JSDestructibleObject {
6365
static void destroy(JSCell*);
6466
static void visitChildren(JSCell*, SlotVisitor&);
6567

66-
Ref<Wasm::Table> m_table;
68+
PoisonedRef<JSWebAssemblyTablePoison, Wasm::Table> m_table;
6769
MallocPtr<WriteBarrier<JSObject>> m_jsFunctions;
6870
};
6971

Source/WTF/ChangeLog

+15
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
2018-01-05 JF Bastien <[email protected]>
2+
3+
WebAssembly: poison JS object's secrets
4+
https://bugs.webkit.org/show_bug.cgi?id=181339
5+
<rdar://problem/36325001>
6+
7+
Reviewed by Mark Lam.
8+
9+
swapping a poisoned pointer with a non-poisoned one (as is done in
10+
JSWebAssembyMemory::adopt) was missing.
11+
12+
* wtf/Poisoned.h:
13+
(WTF::PoisonedImpl::swap):
14+
(WTF::ConstExprPoisonedPtrTraits::swap):
15+
116
2018-01-05 David Kilzer <[email protected]>
217

318
Re-enable -Wcast-qual in WebCore for Apple ports

Source/WTF/wtf/Poisoned.h

+17-1
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,13 @@ class PoisonedImpl {
182182
o = t2;
183183
}
184184

185+
void swap(T& t2)
186+
{
187+
T t1 = this->unpoisoned();
188+
std::swap(t1, t2);
189+
m_poisonedBits = poison(t1);
190+
}
191+
185192
template<class U>
186193
T exchange(U&& newValue)
187194
{
@@ -212,6 +219,12 @@ inline void swap(PoisonedImpl<K1, k1, T1>& a, PoisonedImpl<K2, k2, T2>& b)
212219
a.swap(b);
213220
}
214221

222+
template<typename K1, K1 k1, typename T1>
223+
inline void swap(PoisonedImpl<K1, k1, T1>& a, T1& b)
224+
{
225+
a.swap(b);
226+
}
227+
215228
WTF_EXPORT_PRIVATE uintptr_t makePoison();
216229

217230
inline constexpr uintptr_t makeConstExprPoison(uint32_t key)
@@ -241,6 +254,9 @@ struct ConstExprPoisonedPtrTraits {
241254

242255
template<class U> static ALWAYS_INLINE T* exchange(StorageType& ptr, U&& newValue) { return ptr.exchange(newValue); }
243256

257+
template<typename K1, K1 k1, typename T1>
258+
static ALWAYS_INLINE void swap(PoisonedImpl<K1, k1, T1>& a, T1& b) { a.swap(b); }
259+
244260
template<typename K1, K1 k1, typename T1, typename K2, K2 k2, typename T2>
245261
static ALWAYS_INLINE void swap(PoisonedImpl<K1, k1, T1>& a, PoisonedImpl<K2, k2, T2>& b) { a.swap(b); }
246262

@@ -252,5 +268,5 @@ struct ConstExprPoisonedPtrTraits {
252268
using WTF::ConstExprPoisoned;
253269
using WTF::Poisoned;
254270
using WTF::PoisonedBits;
271+
using WTF::makeConstExprPoison;
255272
using WTF::makePoison;
256-

Tools/ChangeLog

+17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
2018-01-05 JF Bastien <[email protected]>
2+
3+
WebAssembly: poison JS object's secrets
4+
https://bugs.webkit.org/show_bug.cgi?id=181339
5+
<rdar://problem/36325001>
6+
7+
Reviewed by Mark Lam.
8+
9+
Update tests for swap(Poisoned<k, T>, T*)
10+
11+
* TestWebKitAPI/Tests/WTF/ConstExprPoisoned.cpp:
12+
(TestWebKitAPI::TEST):
13+
* TestWebKitAPI/Tests/WTF/Poisoned.cpp:
14+
(TestWebKitAPI::TEST):
15+
* TestWebKitAPI/Tests/WTF/PoisonedRef.cpp:
16+
(TestWebKitAPI::TEST):
17+
118
2018-01-05 Wenson Hsieh <[email protected]>
219

320
REGRESSION(r226396) DataInteractionTests: ContentEditableToContentEditable and ContentEditableToTextarea are failing

Tools/TestWebKitAPI/Tests/WTF/ConstExprPoisoned.cpp

+25-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017 Apple Inc. All rights reserved.
2+
* Copyright (C) 2017-2018 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -337,6 +337,30 @@ TEST(WTF_ConstExprPoisoned, Swap)
337337
ASSERT_TRUE(p1.bits() == p3.bits());
338338
ASSERT_TRUE(p2.bits() != p4.bits());
339339
}
340+
341+
{
342+
ConstExprPoisoned<PoisonA, RefLogger*> p1(&a);
343+
RefLogger* p2(&b);
344+
ASSERT_EQ(&a, p1.unpoisoned());
345+
ASSERT_EQ(&b, p2);
346+
swap(p1, p2);
347+
ASSERT_EQ(&b, p1.unpoisoned());
348+
ASSERT_EQ(&a, p2);
349+
350+
ASSERT_TRUE(p1.bits() != bitwise_cast<uintptr_t>(p2));
351+
}
352+
353+
{
354+
ConstExprPoisoned<PoisonA, RefLogger*> p1(&a);
355+
RefLogger* p2(&b);
356+
ASSERT_EQ(&a, p1.unpoisoned());
357+
ASSERT_EQ(&b, p2);
358+
p1.swap(p2);
359+
ASSERT_EQ(&b, p1.unpoisoned());
360+
ASSERT_EQ(&a, p2);
361+
362+
ASSERT_TRUE(p1.bits() != bitwise_cast<uintptr_t>(p2));
363+
}
340364
}
341365

342366
static ConstExprPoisoned<PoisonA, RefLogger*> poisonedPtrFoo(RefLogger& logger)

Tools/TestWebKitAPI/Tests/WTF/Poisoned.cpp

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017 Apple Inc. All rights reserved.
2+
* Copyright (C) 2017-2018 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -376,6 +376,32 @@ TEST(WTF_Poisoned, Swap)
376376
ASSERT_TRUE(p2.bits() != p4.bits());
377377
#endif
378378
}
379+
380+
#if ENABLE(MIXED_POISON)
381+
{
382+
Poisoned<g_testPoisonA, RefLogger*> p1(&a);
383+
RefLogger* p2(&b);
384+
ASSERT_EQ(&a, p1.unpoisoned());
385+
ASSERT_EQ(&b, p2);
386+
swap(p1, p2);
387+
ASSERT_EQ(&b, p1.unpoisoned());
388+
ASSERT_EQ(&a, p2);
389+
390+
ASSERT_TRUE(p1.bits() != bitwise_cast<uintptr_t>(p2));
391+
}
392+
393+
{
394+
Poisoned<g_testPoisonA, RefLogger*> p1(&a);
395+
RefLogger* p2(&b);
396+
ASSERT_EQ(&a, p1.unpoisoned());
397+
ASSERT_EQ(&b, p2);
398+
p1.swap(p2);
399+
ASSERT_EQ(&b, p1.unpoisoned());
400+
ASSERT_EQ(&a, p2);
401+
402+
ASSERT_TRUE(p1.bits() != bitwise_cast<uintptr_t>(p2));
403+
}
404+
#endif
379405
}
380406

381407
static Poisoned<g_testPoisonA, RefLogger*> poisonedPtrFoo(RefLogger& logger)

0 commit comments

Comments
 (0)