Skip to content
This repository was archived by the owner on Jun 24, 2022. It is now read-only.

Commit 81d6d5b

Browse files
Only cache bytecode for API clients in data vaults
https://bugs.webkit.org/show_bug.cgi?id=197898 Source/JavaScriptCore: <rdar://problem/45945449> Reviewed by Keith Miller. Enforce that API clients only store cached bytecode in data vaults. This prevents another process from compromising the current one by tampering with the bytecode. * API/JSScript.mm: (validateBytecodeCachePath): (+[JSScript scriptOfType:withSource:andSourceURL:andBytecodeCache:inVirtualMachine:error:]): (+[JSScript scriptOfType:memoryMappedFromASCIIFile:withSourceURL:andBytecodeCache:inVirtualMachine:error:]): * API/tests/testapi.mm: (cacheFileInDataVault): (testModuleBytecodeCache): (testProgramBytecodeCache): (testBytecodeCacheWithSyntaxError): (testBytecodeCacheWithSameCacheFileAndDifferentScript): (testCacheFileFailsWhenItsAlreadyCached): (testCanCacheManyFilesWithTheSameVM): (testIsUsingBytecodeCacheAccessor): (testBytecodeCacheValidation): (testObjectiveCAPI): * Configurations/ToolExecutable.xcconfig: * JavaScriptCore.xcodeproj/project.pbxproj: * testapi.entitlements: Added. Source/WTF: Reviewed by Keith Miller. Add SPI to check if a filesystem path is restricted as a data vault. * WTF.xcodeproj/project.pbxproj: * wtf/spi/darwin/DataVaultSPI.h: Added. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@245564 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 4131aa2 commit 81d6d5b

File tree

9 files changed

+235
-12
lines changed

9 files changed

+235
-12
lines changed

Source/JavaScriptCore/API/JSScript.mm

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@
3838
#import "ParserError.h"
3939
#import "Symbol.h"
4040
#include <sys/stat.h>
41+
#include <wtf/FileMetadata.h>
4142
#include <wtf/FileSystem.h>
4243
#include <wtf/Scope.h>
44+
#include <wtf/spi/darwin/DataVaultSPI.h>
4345

4446
#if JSC_OBJC_API_ENABLED
4547

@@ -60,9 +62,52 @@ @implementation JSScript {
6062
return nil;
6163
}
6264

65+
static bool validateBytecodeCachePath(NSURL* cachePath, NSError** error)
66+
{
67+
if (!cachePath)
68+
return true;
69+
70+
URL cachePathURL([cachePath absoluteURL]);
71+
if (!cachePathURL.isLocalFile()) {
72+
createError([NSString stringWithFormat:@"Cache path `%@` is not a local file", static_cast<NSString *>(cachePathURL)], error);
73+
return false;
74+
}
75+
76+
String systemPath = cachePathURL.fileSystemPath();
77+
78+
if (auto metadata = FileSystem::fileMetadata(systemPath)) {
79+
if (metadata->type != FileMetadata::Type::File) {
80+
createError([NSString stringWithFormat:@"Cache path `%s` already exists and is not a file", systemPath.utf8().data()], error);
81+
return false;
82+
}
83+
}
84+
85+
String directory = FileSystem::directoryName(systemPath);
86+
if (directory.isNull()) {
87+
createError([NSString stringWithFormat:@"Cache path `%s` does not contain in a valid directory", systemPath.utf8().data()], error);
88+
return false;
89+
}
90+
91+
if (!FileSystem::fileIsDirectory(directory, FileSystem::ShouldFollowSymbolicLinks::No)) {
92+
createError([NSString stringWithFormat:@"Cache directory `%s` is not a directory or does not exist", directory.utf8().data()], error);
93+
return false;
94+
}
95+
96+
#if USE(APPLE_INTERNAL_SDK)
97+
if (rootless_check_datavault_flag(FileSystem::fileSystemRepresentation(directory).data(), nullptr)) {
98+
createError([NSString stringWithFormat:@"Cache directory `%s` is not a data vault", directory.utf8().data()], error);
99+
return false;
100+
}
101+
#endif
102+
103+
return true;
104+
}
105+
63106
+ (instancetype)scriptOfType:(JSScriptType)type withSource:(NSString *)source andSourceURL:(NSURL *)sourceURL andBytecodeCache:(NSURL *)cachePath inVirtualMachine:(JSVirtualMachine *)vm error:(out NSError **)error
64107
{
65-
UNUSED_PARAM(error);
108+
if (!validateBytecodeCachePath(cachePath, error))
109+
return nil;
110+
66111
JSScript *result = [[[JSScript alloc] init] autorelease];
67112
result->m_virtualMachine = vm;
68113
result->m_type = type;
@@ -75,7 +120,9 @@ + (instancetype)scriptOfType:(JSScriptType)type withSource:(NSString *)source an
75120

76121
+ (instancetype)scriptOfType:(JSScriptType)type memoryMappedFromASCIIFile:(NSURL *)filePath withSourceURL:(NSURL *)sourceURL andBytecodeCache:(NSURL *)cachePath inVirtualMachine:(JSVirtualMachine *)vm error:(out NSError **)error
77122
{
78-
UNUSED_PARAM(error);
123+
if (!validateBytecodeCachePath(cachePath, error))
124+
return nil;
125+
79126
URL filePathURL([filePath absoluteURL]);
80127
if (!filePathURL.isLocalFile())
81128
return createError([NSString stringWithFormat:@"File path %@ is not a local file", static_cast<NSString *>(filePathURL)], error);

Source/JavaScriptCore/API/tests/testapi.mm

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#import "JSWrapperMapTests.h"
4141
#import "Regress141275.h"
4242
#import "Regress141809.h"
43+
#import <wtf/spi/darwin/DataVaultSPI.h>
4344

4445
#if __has_include(<libproc.h>)
4546
#define HAS_LIBPROC 1
@@ -2076,6 +2077,27 @@ static void testImportModuleTwice()
20762077
return [tempDirectory URLByAppendingPathComponent:string];
20772078
}
20782079

2080+
static NSURL* cacheFileInDataVault(NSString* name)
2081+
{
2082+
#if USE(APPLE_INTERNAL_SDK)
2083+
static NSURL* dataVaultURL;
2084+
static dispatch_once_t once;
2085+
dispatch_once(&once, ^{
2086+
char userDir[PATH_MAX];
2087+
RELEASE_ASSERT(confstr(_CS_DARWIN_USER_DIR, userDir, sizeof(userDir)));
2088+
2089+
NSString *userDirPath = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:userDir length:strlen(userDir)];
2090+
dataVaultURL = [NSURL fileURLWithPath:userDirPath isDirectory:YES];
2091+
dataVaultURL = [dataVaultURL URLByAppendingPathComponent:@"JavaScriptCore" isDirectory:YES];
2092+
rootless_mkdir_datavault(dataVaultURL.path.UTF8String, 0700, "JavaScriptCore");
2093+
});
2094+
2095+
return [dataVaultURL URLByAppendingPathComponent:name isDirectory:NO];
2096+
#else
2097+
return tempFile(name);
2098+
#endif
2099+
}
2100+
20792101
static void testModuleBytecodeCache()
20802102
{
20812103
@autoreleasepool {
@@ -2087,9 +2109,9 @@ static void testModuleBytecodeCache()
20872109
NSURL *barPath = tempFile(@"bar.js");
20882110
NSURL *bazPath = tempFile(@"baz.js");
20892111

2090-
NSURL *fooCachePath = tempFile(@"foo.js.cache");
2091-
NSURL *barCachePath = tempFile(@"bar.js.cache");
2092-
NSURL *bazCachePath = tempFile(@"baz.js.cache");
2112+
NSURL *fooCachePath = cacheFileInDataVault(@"foo.js.cache");
2113+
NSURL *barCachePath = cacheFileInDataVault(@"bar.js.cache");
2114+
NSURL *bazCachePath = cacheFileInDataVault(@"baz.js.cache");
20932115

20942116
NSURL *fooFakePath = [NSURL fileURLWithPath:@"/foo.js"];
20952117
NSURL *barFakePath = [NSURL fileURLWithPath:@"/directory/bar.js"];
@@ -2110,7 +2132,8 @@ static void testModuleBytecodeCache()
21102132
script = [JSScript scriptOfType:kJSScriptTypeModule memoryMappedFromASCIIFile:bazPath withSourceURL:bazFakePath andBytecodeCache:bazCachePath inVirtualMachine:context.virtualMachine error:nil];
21112133

21122134
if (script) {
2113-
if (![script cacheBytecodeWithError:nil])
2135+
NSError *error = nil;
2136+
if (![script cacheBytecodeWithError:&error])
21142137
CRASH();
21152138
[resolve callWithArguments:@[script]];
21162139
} else
@@ -2142,7 +2165,7 @@ static void testProgramBytecodeCache()
21422165
{
21432166
@autoreleasepool {
21442167
NSString *fooSource = @"function foo() { return 42; }; function bar() { return 40; }; foo() + bar();";
2145-
NSURL *fooCachePath = tempFile(@"foo.js.cache");
2168+
NSURL *fooCachePath = cacheFileInDataVault(@"foo.js.cache");
21462169
JSContext *context = [[JSContext alloc] init];
21472170
JSScript *script = [JSScript scriptOfType:kJSScriptTypeProgram withSource:fooSource andSourceURL:[NSURL URLWithString:@"my-path"] andBytecodeCache:fooCachePath inVirtualMachine:context.virtualMachine error:nil];
21482171
RELEASE_ASSERT(script);
@@ -2166,7 +2189,7 @@ static void testBytecodeCacheWithSyntaxError(JSScriptType type)
21662189
{
21672190
@autoreleasepool {
21682191
NSString *fooSource = @"this is a syntax error";
2169-
NSURL *fooCachePath = tempFile(@"foo.js.cache");
2192+
NSURL *fooCachePath = cacheFileInDataVault(@"foo.js.cache");
21702193
JSContext *context = [[JSContext alloc] init];
21712194
JSScript *script = [JSScript scriptOfType:type withSource:fooSource andSourceURL:[NSURL URLWithString:@"my-path"] andBytecodeCache:fooCachePath inVirtualMachine:context.virtualMachine error:nil];
21722195
RELEASE_ASSERT(script);
@@ -2180,7 +2203,8 @@ static void testBytecodeCacheWithSyntaxError(JSScriptType type)
21802203

21812204
static void testBytecodeCacheWithSameCacheFileAndDifferentScript(bool forceDiskCache)
21822205
{
2183-
NSURL *cachePath = tempFile(@"cachePath.cache");
2206+
2207+
NSURL *cachePath = cacheFileInDataVault(@"cachePath.cache");
21842208
NSURL *sourceURL = [NSURL URLWithString:@"my-path"];
21852209

21862210
@autoreleasepool {
@@ -2220,6 +2244,7 @@ static void testBytecodeCacheWithSameCacheFileAndDifferentScript(bool forceDiskC
22202244
NSFileManager* fileManager = [NSFileManager defaultManager];
22212245
BOOL removedAll = [fileManager removeItemAtURL:cachePath error:nil];
22222246
checkResult(@"Removed all temp files created", removedAll);
2247+
22232248
}
22242249

22252250
static void testProgramJSScriptException()
@@ -2245,7 +2270,7 @@ static void testProgramJSScriptException()
22452270

22462271
static void testCacheFileFailsWhenItsAlreadyCached()
22472272
{
2248-
NSURL* cachePath = tempFile(@"foo.program.cache");
2273+
NSURL* cachePath = cacheFileInDataVault(@"foo.program.cache");
22492274
NSURL* sourceURL = [NSURL URLWithString:@"my-path"];
22502275
NSString *source = @"function foo() { return 42; } foo();";
22512276

@@ -2285,7 +2310,7 @@ static void testCanCacheManyFilesWithTheSameVM()
22852310
NSMutableArray *scripts = [[NSMutableArray alloc] init];
22862311

22872312
for (unsigned i = 0; i < 10000; ++i)
2288-
[cachePaths addObject:tempFile([NSString stringWithFormat:@"cache-%d.cache", i])];
2313+
[cachePaths addObject:cacheFileInDataVault([NSString stringWithFormat:@"cache-%d.cache", i])];
22892314

22902315
JSVirtualMachine *vm = [[JSVirtualMachine alloc] init];
22912316
bool cachedAll = true;
@@ -2323,7 +2348,7 @@ static void testCanCacheManyFilesWithTheSameVM()
23232348

23242349
static void testIsUsingBytecodeCacheAccessor()
23252350
{
2326-
NSURL* cachePath = tempFile(@"foo.program.cache");
2351+
NSURL* cachePath = cacheFileInDataVault(@"foo.program.cache");
23272352
NSURL* sourceURL = [NSURL URLWithString:@"my-path"];
23282353
NSString *source = @"function foo() { return 1337; } foo();";
23292354

@@ -2356,6 +2381,44 @@ static void testIsUsingBytecodeCacheAccessor()
23562381
checkResult(@"Successfully removed cache file", removedAll);
23572382
}
23582383

2384+
static void testBytecodeCacheValidation()
2385+
{
2386+
@autoreleasepool {
2387+
JSContext *context = [[JSContext alloc] init];
2388+
2389+
auto testInvalidCacheURL = [&](NSURL* cacheURL, NSString* expectedErrorMessage)
2390+
{
2391+
NSError* error;
2392+
JSScript *script = [JSScript scriptOfType:kJSScriptTypeProgram withSource:@"" andSourceURL:[NSURL URLWithString:@"my-path"] andBytecodeCache:cacheURL inVirtualMachine:context.virtualMachine error:&error];
2393+
RELEASE_ASSERT(!script);
2394+
RELEASE_ASSERT(error);
2395+
NSString* testDesciption = [NSString stringWithFormat:@"Cache path validation for `%@` fails with message `%@`", cacheURL.absoluteString, expectedErrorMessage];
2396+
checkResult(testDesciption, [error.description containsString:expectedErrorMessage]);
2397+
};
2398+
2399+
testInvalidCacheURL([NSURL URLWithString:@""], @"Cache path `` is not a local file");
2400+
testInvalidCacheURL([NSURL URLWithString:@"file:///"], @"Cache path `/` already exists and is not a file");
2401+
testInvalidCacheURL([NSURL URLWithString:@"file:///a/b/c/d/e"], @"Cache directory `/a/b/c/d` is not a directory or does not exist");
2402+
testInvalidCacheURL([NSURL URLWithString:@"file:///private/tmp/file.cache"], @"Cache directory `/private/tmp` is not a data vault");
2403+
}
2404+
2405+
#if USE(APPLE_INTERNAL_SDK)
2406+
@autoreleasepool {
2407+
JSContext *context = [[JSContext alloc] init];
2408+
2409+
auto testValidCacheURL = [&](NSURL* cacheURL)
2410+
{
2411+
NSError* error;
2412+
JSScript *script = [JSScript scriptOfType:kJSScriptTypeProgram withSource:@"" andSourceURL:[NSURL URLWithString:@"my-path"] andBytecodeCache:cacheURL inVirtualMachine:context.virtualMachine error:&error];
2413+
NSString* testDesciption = [NSString stringWithFormat:@"Cache path validation for `%@` passed", cacheURL.absoluteString];
2414+
checkResult(testDesciption, script && !error);
2415+
};
2416+
2417+
testValidCacheURL(cacheFileInDataVault(@"file.cache"));
2418+
}
2419+
#endif
2420+
}
2421+
23592422
@interface JSContextFileLoaderDelegate : JSContext <JSModuleLoaderDelegate>
23602423

23612424
+ (instancetype)newContext;
@@ -2628,6 +2691,7 @@ void testObjectiveCAPI(const char* filter)
26282691
RUN(testCacheFileFailsWhenItsAlreadyCached());
26292692
RUN(testCanCacheManyFilesWithTheSameVM());
26302693
RUN(testIsUsingBytecodeCacheAccessor());
2694+
RUN(testBytecodeCacheValidation());
26312695

26322696
RUN(testLoaderRejectsNilScriptURL());
26332697
RUN(testLoaderRejectsFailedFetch());

Source/JavaScriptCore/ChangeLog

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,33 @@
1+
2019-05-20 Tadeu Zagallo <[email protected]>
2+
3+
Only cache bytecode for API clients in data vaults
4+
https://bugs.webkit.org/show_bug.cgi?id=197898
5+
<rdar://problem/45945449>
6+
7+
Reviewed by Keith Miller.
8+
9+
Enforce that API clients only store cached bytecode in data vaults. This prevents
10+
another process from compromising the current one by tampering with the bytecode.
11+
12+
* API/JSScript.mm:
13+
(validateBytecodeCachePath):
14+
(+[JSScript scriptOfType:withSource:andSourceURL:andBytecodeCache:inVirtualMachine:error:]):
15+
(+[JSScript scriptOfType:memoryMappedFromASCIIFile:withSourceURL:andBytecodeCache:inVirtualMachine:error:]):
16+
* API/tests/testapi.mm:
17+
(cacheFileInDataVault):
18+
(testModuleBytecodeCache):
19+
(testProgramBytecodeCache):
20+
(testBytecodeCacheWithSyntaxError):
21+
(testBytecodeCacheWithSameCacheFileAndDifferentScript):
22+
(testCacheFileFailsWhenItsAlreadyCached):
23+
(testCanCacheManyFilesWithTheSameVM):
24+
(testIsUsingBytecodeCacheAccessor):
25+
(testBytecodeCacheValidation):
26+
(testObjectiveCAPI):
27+
* Configurations/ToolExecutable.xcconfig:
28+
* JavaScriptCore.xcodeproj/project.pbxproj:
29+
* testapi.entitlements: Added.
30+
131
2019-05-20 Tadeu Zagallo <[email protected]>
232

333
Fix 32-bit btyecode cache crashes

Source/JavaScriptCore/Configurations/ToolExecutable.xcconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,27 @@
2121
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2222
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2323

24+
#include? "../../../../Internal/Configurations/HaveInternalSDK.xcconfig"
2425
#include "FeatureDefines.xcconfig"
2526
#include "Version.xcconfig"
2627

2728
INSTALL_PATH = $(JAVASCRIPTCORE_FRAMEWORKS_DIR)/$(JAVASCRIPTCORE_RESOURCES_DIR);
2829
PRODUCT_NAME = $(TARGET_NAME);
30+
31+
USE_INTERNAL_SDK = $(USE_INTERNAL_SDK_$(CONFIGURATION));
32+
USE_INTERNAL_SDK_Production = YES;
33+
USE_INTERNAL_SDK_Debug = $(HAVE_INTERNAL_SDK);
34+
USE_INTERNAL_SDK_Release = $(HAVE_INTERNAL_SDK);
35+
36+
CODE_SIGN_IDENTITY[sdk=macosx*] = $(CODE_SIGN_IDENTITY_$(USE_INTERNAL_SDK))
37+
38+
CODE_SIGN_IDENTITY_ = $(CODE_SIGN_IDENTITY_NO);
39+
CODE_SIGN_IDENTITY_NO = -;
40+
CODE_SIGN_IDENTITY_YES = $(WK_ENGINEERING_CODE_SIGN_IDENTITY);
41+
42+
CODE_SIGN_ENTITLEMENTS[sdk=macosx*] = $(CODE_SIGN_ENTITLEMENTS_macosx_$(TARGET_NAME));
43+
CODE_SIGN_ENTITLEMENTS_macosx_testapi = testapi.entitlements;
44+
2945
CODE_SIGN_ENTITLEMENTS[sdk=iphone*] = $(CODE_SIGN_ENTITLEMENTS_ios_$(TARGET_NAME));
3046
CODE_SIGN_ENTITLEMENTS_ios_minidom = entitlements.plist;
3147
CODE_SIGN_ENTITLEMENTS_ios_testair = entitlements.plist;

Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3212,6 +3212,7 @@
32123212
1442565F15EDE98D0066A49B /* JSWithScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWithScope.cpp; sourceTree = "<group>"; };
32133213
1442566015EDE98D0066A49B /* JSWithScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWithScope.h; sourceTree = "<group>"; };
32143214
144CA34F221F037900817789 /* CachedBytecode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedBytecode.h; sourceTree = "<group>"; };
3215+
145348572291737F00B1C2EB /* testapi.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = testapi.entitlements; sourceTree = "<group>"; };
32153216
145722851437E140005FDE26 /* StrongInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StrongInlines.h; sourceTree = "<group>"; };
32163217
145C507F0D9DF63B0088F6B9 /* CallData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallData.h; sourceTree = "<group>"; };
32173218
146AAB2A0B66A84900E55F16 /* JSStringRefCF.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSStringRefCF.h; sourceTree = "<group>"; };
@@ -5177,6 +5178,7 @@
51775178
A7C225CC139981F100FF1662 /* KeywordLookupGenerator.py */,
51785179
79D7B0E221152FD300FE7C64 /* allow-jit-macOS.entitlements */,
51795180
79D7B0E121152FD200FE7C64 /* entitlements.plist */,
5181+
145348572291737F00B1C2EB /* testapi.entitlements */,
51805182
1432EBD70A34CAD400717B9F /* API */,
51815183
9688CB120ED12B4E001D649F /* assembler */,
51825184
0FEC84B21BDACD5E0080FF74 /* b3 */,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>com.apple.security.cs.allow-jit</key>
6+
<true/>
7+
<key>com.apple.rootless.storage.JavaScriptCore</key>
8+
<true/>
9+
</dict>
10+
</plist>

Source/WTF/ChangeLog

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
2019-05-20 Tadeu Zagallo <[email protected]>
2+
3+
Only cache bytecode for API clients in data vaults
4+
https://bugs.webkit.org/show_bug.cgi?id=197898
5+
6+
Reviewed by Keith Miller.
7+
8+
Add SPI to check if a filesystem path is restricted as a data vault.
9+
10+
* WTF.xcodeproj/project.pbxproj:
11+
* wtf/spi/darwin/DataVaultSPI.h: Added.
12+
113
2019-05-20 Carlos Garcia Campos <[email protected]>
214

315
[GLIB] Repeating timer is not stopped when stop is called from the callback

Source/WTF/WTF.xcodeproj/project.pbxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@
288288
1469419416EAAFF80024E146 /* SchedulePair.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SchedulePair.h; sourceTree = "<group>"; };
289289
1469419A16EAB10A0024E146 /* AutodrainedPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutodrainedPool.h; sourceTree = "<group>"; };
290290
1469419B16EAB10A0024E146 /* AutodrainedPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AutodrainedPool.cpp; sourceTree = "<group>"; };
291+
14933E21228C22DF00F79E46 /* DataVaultSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataVaultSPI.h; sourceTree = "<group>"; };
291292
149EF16216BBFE0D000A4331 /* TriState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TriState.h; sourceTree = "<group>"; };
292293
14E785E71DFB330100209BD1 /* OrdinalNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OrdinalNumber.h; sourceTree = "<group>"; };
293294
14F3B0F615E45E4600210069 /* SaturatedArithmetic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaturatedArithmetic.h; sourceTree = "<group>"; };
@@ -1363,6 +1364,7 @@
13631364
CE73E02319DCB7AB00580D5C /* darwin */ = {
13641365
isa = PBXGroup;
13651366
children = (
1367+
14933E21228C22DF00F79E46 /* DataVaultSPI.h */,
13661368
E431CC4A21187ADB000C8A07 /* DispatchSPI.h */,
13671369
93DDE9311CDC052D00FD3491 /* dyldSPI.h */,
13681370
A5098AFF1C169E0700087797 /* SandboxSPI.h */,

0 commit comments

Comments
 (0)