Changeset 244597 in webkit


Ignore:
Timestamp:
Apr 24, 2019 10:46:28 AM (5 years ago)
Author:
achristensen@apple.com
Message:

WKContentRuleLists should have a maximum FileProtection of CompleteUnlessOpen
https://bugs.webkit.org/show_bug.cgi?id=197078
<rdar://problem/49564348>

Reviewed by Geoff Garen.

Source/WebKit:

r242735 was a fix for crashes when using mmap'd memory in apps with default FileProtection of NSFileProtectionComplete.
It is more memory efficient and just as secure to reduce the FileProtection of these files to NSFileProtectionCompleteUnlessOpen.

  • NetworkProcess/cache/NetworkCacheFileSystem.cpp:

(WebKit::NetworkCache::isSafeToUseMemoryMapForPath):
(WebKit::NetworkCache::makeSafeToUseMemoryMapForPath):
(WebKit::NetworkCache::pathRegisteredAsUnsafeToMemoryMapForTesting): Deleted.
(WebKit::NetworkCache::registerPathAsUnsafeToMemoryMapForTesting): Deleted.

  • NetworkProcess/cache/NetworkCacheFileSystem.h:
  • NetworkProcess/cache/NetworkCacheFileSystemCocoa.mm: Added.

(WebKit::NetworkCache::isSafeToUseMemoryMapForPath):
(WebKit::NetworkCache::makeSafeToUseMemoryMapForPath):

  • Shared/WebCompiledContentRuleList.cpp:

(WebKit::WebCompiledContentRuleList::conditionsApplyOnlyToDomain const):
(WebKit::WebCompiledContentRuleList::filtersWithoutConditionsBytecode const):
(WebKit::WebCompiledContentRuleList::filtersWithConditionsBytecode const):
(WebKit::WebCompiledContentRuleList::topURLFiltersBytecode const):
(WebKit::WebCompiledContentRuleList::actions const):
(WebKit::WebCompiledContentRuleList::usesCopiedMemory const): Deleted.

  • Shared/WebCompiledContentRuleList.h:
  • Shared/WebCompiledContentRuleListData.cpp:

(WebKit::WebCompiledContentRuleListData::encode const):
(WebKit::WebCompiledContentRuleListData::decode):
(WebKit::WebCompiledContentRuleListData::size const): Deleted.
(WebKit::WebCompiledContentRuleListData::dataPointer const): Deleted.

  • Shared/WebCompiledContentRuleListData.h:

(WebKit::WebCompiledContentRuleListData::WebCompiledContentRuleListData):

  • SourcesCocoa.txt:
  • UIProcess/API/APIContentRuleList.cpp:

(API::ContentRuleList::usesCopiedMemory const): Deleted.

  • UIProcess/API/APIContentRuleList.h:
  • UIProcess/API/APIContentRuleListStore.cpp:

(API::openAndMapOrCopyContentRuleList):
(API::compiledToFile):
(API::createExtension):
(API::ContentRuleListStore::getContentRuleListSource):
(API::ContentRuleListStore::readContentsOfFile): Deleted.
(API::MappedOrCopiedData::dataPointer const): Deleted.

  • UIProcess/API/APIContentRuleListStore.h:
  • UIProcess/API/Cocoa/APIContentRuleListStoreCocoa.mm:

(API::ContentRuleListStore::readContentsOfFile): Deleted.

  • UIProcess/API/Cocoa/WKContentRuleListStore.mm:

(+[WKContentRuleListStore _registerPathAsUnsafeToMemoryMapForTesting:]): Deleted.

  • UIProcess/API/Cocoa/WKContentRuleListStorePrivate.h:
  • UIProcess/API/Cocoa/_WKUserContentFilter.mm:

(-[_WKUserContentFilter usesCopiedMemory]): Deleted.

  • UIProcess/API/Cocoa/_WKUserContentFilterPrivate.h:
  • WebKit.xcodeproj/project.pbxproj:

Tools:

  • TestWebKitAPI/Tests/WebKitCocoa/WKContentExtensionStore.mm:

(TEST_F):
(-[TestSchemeHandlerSubresourceShouldBeBlocked webView:startURLSchemeTask:]): Deleted.
(-[TestSchemeHandlerSubresourceShouldBeBlocked webView:stopURLSchemeTask:]): Deleted.
Unfortunately, setting the NSFileProtectionKey attribute is only supported on iOS devices.

Location:
trunk
Files:
1 added
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r244596 r244597  
     12019-04-24  Alex Christensen  <achristensen@webkit.org>
     2
     3        WKContentRuleLists should have a maximum FileProtection of CompleteUnlessOpen
     4        https://bugs.webkit.org/show_bug.cgi?id=197078
     5        <rdar://problem/49564348>
     6
     7        Reviewed by Geoff Garen.
     8
     9        r242735 was a fix for crashes when using mmap'd memory in apps with default FileProtection of NSFileProtectionComplete.
     10        It is more memory efficient and just as secure to reduce the FileProtection of these files to NSFileProtectionCompleteUnlessOpen.
     11
     12        * NetworkProcess/cache/NetworkCacheFileSystem.cpp:
     13        (WebKit::NetworkCache::isSafeToUseMemoryMapForPath):
     14        (WebKit::NetworkCache::makeSafeToUseMemoryMapForPath):
     15        (WebKit::NetworkCache::pathRegisteredAsUnsafeToMemoryMapForTesting): Deleted.
     16        (WebKit::NetworkCache::registerPathAsUnsafeToMemoryMapForTesting): Deleted.
     17        * NetworkProcess/cache/NetworkCacheFileSystem.h:
     18        * NetworkProcess/cache/NetworkCacheFileSystemCocoa.mm: Added.
     19        (WebKit::NetworkCache::isSafeToUseMemoryMapForPath):
     20        (WebKit::NetworkCache::makeSafeToUseMemoryMapForPath):
     21        * Shared/WebCompiledContentRuleList.cpp:
     22        (WebKit::WebCompiledContentRuleList::conditionsApplyOnlyToDomain const):
     23        (WebKit::WebCompiledContentRuleList::filtersWithoutConditionsBytecode const):
     24        (WebKit::WebCompiledContentRuleList::filtersWithConditionsBytecode const):
     25        (WebKit::WebCompiledContentRuleList::topURLFiltersBytecode const):
     26        (WebKit::WebCompiledContentRuleList::actions const):
     27        (WebKit::WebCompiledContentRuleList::usesCopiedMemory const): Deleted.
     28        * Shared/WebCompiledContentRuleList.h:
     29        * Shared/WebCompiledContentRuleListData.cpp:
     30        (WebKit::WebCompiledContentRuleListData::encode const):
     31        (WebKit::WebCompiledContentRuleListData::decode):
     32        (WebKit::WebCompiledContentRuleListData::size const): Deleted.
     33        (WebKit::WebCompiledContentRuleListData::dataPointer const): Deleted.
     34        * Shared/WebCompiledContentRuleListData.h:
     35        (WebKit::WebCompiledContentRuleListData::WebCompiledContentRuleListData):
     36        * SourcesCocoa.txt:
     37        * UIProcess/API/APIContentRuleList.cpp:
     38        (API::ContentRuleList::usesCopiedMemory const): Deleted.
     39        * UIProcess/API/APIContentRuleList.h:
     40        * UIProcess/API/APIContentRuleListStore.cpp:
     41        (API::openAndMapOrCopyContentRuleList):
     42        (API::compiledToFile):
     43        (API::createExtension):
     44        (API::ContentRuleListStore::getContentRuleListSource):
     45        (API::ContentRuleListStore::readContentsOfFile): Deleted.
     46        (API::MappedOrCopiedData::dataPointer const): Deleted.
     47        * UIProcess/API/APIContentRuleListStore.h:
     48        * UIProcess/API/Cocoa/APIContentRuleListStoreCocoa.mm:
     49        (API::ContentRuleListStore::readContentsOfFile): Deleted.
     50        * UIProcess/API/Cocoa/WKContentRuleListStore.mm:
     51        (+[WKContentRuleListStore _registerPathAsUnsafeToMemoryMapForTesting:]): Deleted.
     52        * UIProcess/API/Cocoa/WKContentRuleListStorePrivate.h:
     53        * UIProcess/API/Cocoa/_WKUserContentFilter.mm:
     54        (-[_WKUserContentFilter usesCopiedMemory]): Deleted.
     55        * UIProcess/API/Cocoa/_WKUserContentFilterPrivate.h:
     56        * WebKit.xcodeproj/project.pbxproj:
     57
    1582019-04-24  David Kilzer  <ddkilzer@apple.com>
    259
  • trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheFileSystem.cpp

    r242735 r244597  
    146146}
    147147
    148 static String& pathRegisteredAsUnsafeToMemoryMapForTesting()
     148#if !PLATFORM(IOS_FAMILY)
     149bool isSafeToUseMemoryMapForPath(const String&)
    149150{
    150     static NeverDestroyed<String> path;
    151     return path.get();
     151    return true;
    152152}
    153 
    154 void registerPathAsUnsafeToMemoryMapForTesting(const String& path)
     153void makeSafeToUseMemoryMapForPath(const String&)
    155154{
    156     pathRegisteredAsUnsafeToMemoryMapForTesting() = path;
    157155}
    158 
    159    
    160 bool isSafeToUseMemoryMapForPath(const String& path)
    161 {
    162     if (path == pathRegisteredAsUnsafeToMemoryMapForTesting())
    163         return false;
    164 
    165 #if PLATFORM(IOS_FAMILY) && !PLATFORM(IOS_FAMILY_SIMULATOR)
    166     struct {
    167         uint32_t length;
    168         uint32_t protectionClass;
    169     } attrBuffer;
    170 
    171     attrlist attrList = { };
    172     attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
    173     attrList.commonattr = ATTR_CMN_DATA_PROTECT_FLAGS;
    174     int32_t error = getattrlist(FileSystem::fileSystemRepresentation(path).data(), &attrList, &attrBuffer, sizeof(attrBuffer), FSOPT_NOFOLLOW);
    175     if (error) {
    176         RELEASE_LOG_ERROR(Network, "Unable to get cache directory protection class, disabling use of shared mapped memory");
    177         return false;
    178     }
    179 
    180     // For stricter protection classes shared maps could disappear when device is locked.
    181     const uint32_t fileProtectionCompleteUntilFirstUserAuthentication = 3;
    182     bool isSafe = attrBuffer.protectionClass >= fileProtectionCompleteUntilFirstUserAuthentication;
    183 
    184     if (!isSafe)
    185         RELEASE_LOG(Network, "Disallowing use of shared mapped memory due to container protection class %u", attrBuffer.protectionClass);
    186 
    187     return isSafe;
    188 #else
    189     UNUSED_PARAM(path);
    190     return true;
    191156#endif
    192 }
    193157
    194158}
  • trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheFileSystem.h

    r242735 r244597  
    4343void updateFileModificationTimeIfNeeded(const String& path);
    4444
    45 bool isSafeToUseMemoryMapForPath(const String& path);
    46 void registerPathAsUnsafeToMemoryMapForTesting(const String&);
     45bool isSafeToUseMemoryMapForPath(const String&);
     46void makeSafeToUseMemoryMapForPath(const String&);
    4747
    4848}
  • trunk/Source/WebKit/Shared/WebCompiledContentRuleList.cpp

    r242735 r244597  
    4545}
    4646
    47 bool WebCompiledContentRuleList::usesCopiedMemory() const
    48 {
    49     return WTF::holds_alternative<RefPtr<WebCore::SharedBuffer>>(m_data.data);
    50 }
    51 
    5247bool WebCompiledContentRuleList::conditionsApplyOnlyToDomain() const
    5348{
    54     return *reinterpret_cast<const uint32_t*>(reinterpret_cast<const uint8_t*>(m_data.dataPointer()) + m_data.conditionsApplyOnlyToDomainOffset);
     49    return *reinterpret_cast<const uint32_t*>(reinterpret_cast<const uint8_t*>(m_data.data->data()) + m_data.conditionsApplyOnlyToDomainOffset);
    5550}
    5651
    5752const WebCore::ContentExtensions::DFABytecode* WebCompiledContentRuleList::filtersWithoutConditionsBytecode() const
    5853{
    59     return static_cast<const WebCore::ContentExtensions::DFABytecode*>(m_data.dataPointer()) + m_data.filtersWithoutConditionsBytecodeOffset;
     54    return static_cast<const WebCore::ContentExtensions::DFABytecode*>(m_data.data->data()) + m_data.filtersWithoutConditionsBytecodeOffset;
    6055}
    6156
     
    6762const WebCore::ContentExtensions::DFABytecode* WebCompiledContentRuleList::filtersWithConditionsBytecode() const
    6863{
    69     return static_cast<const WebCore::ContentExtensions::DFABytecode*>(m_data.dataPointer()) + m_data.filtersWithConditionsBytecodeOffset;
     64    return static_cast<const WebCore::ContentExtensions::DFABytecode*>(m_data.data->data()) + m_data.filtersWithConditionsBytecodeOffset;
    7065}
    7166
     
    7772const WebCore::ContentExtensions::DFABytecode* WebCompiledContentRuleList::topURLFiltersBytecode() const
    7873{
    79     return static_cast<const WebCore::ContentExtensions::DFABytecode*>(m_data.dataPointer()) + m_data.topURLFiltersBytecodeOffset;
     74    return static_cast<const WebCore::ContentExtensions::DFABytecode*>(m_data.data->data()) + m_data.topURLFiltersBytecodeOffset;
    8075}
    8176
     
    8782const WebCore::ContentExtensions::SerializedActionByte* WebCompiledContentRuleList::actions() const
    8883{
    89     return static_cast<const WebCore::ContentExtensions::SerializedActionByte*>(m_data.dataPointer()) + m_data.actionsOffset;
     84    return static_cast<const WebCore::ContentExtensions::SerializedActionByte*>(m_data.data->data()) + m_data.actionsOffset;
    9085}
    9186
  • trunk/Source/WebKit/Shared/WebCompiledContentRuleList.h

    r242735 r244597  
    4141    const WebCompiledContentRuleListData& data() const { return m_data; }
    4242
    43     bool usesCopiedMemory() const;
    44    
    4543private:
    4644    WebCompiledContentRuleList(WebCompiledContentRuleListData&&);
  • trunk/Source/WebKit/Shared/WebCompiledContentRuleListData.cpp

    r244403 r244597  
    3535namespace WebKit {
    3636
    37 size_t WebCompiledContentRuleListData::size() const
    38 {
    39     return WTF::switchOn(data, [] (const auto& sharedMemoryOrBuffer) {
    40         return sharedMemoryOrBuffer->size();
    41     });
    42 }
    43 
    44 const void* WebCompiledContentRuleListData::dataPointer() const
    45 {
    46     return WTF::switchOn(data, [] (const auto& sharedMemoryOrBuffer) -> const void* {
    47         return sharedMemoryOrBuffer->data();
    48     });
    49 }
    50 
    5137void WebCompiledContentRuleListData::encode(IPC::Encoder& encoder) const
    5238{
    53     if (auto sharedMemory = WTF::get_if<RefPtr<SharedMemory>>(data)) {
    54         encoder << true;
    55         SharedMemory::Handle handle;
    56         sharedMemory->get()->createHandle(handle, SharedMemory::Protection::ReadOnly);
    57         encoder << handle;
    58     } else {
    59         encoder << false;
    60         encoder << IPC::SharedBufferDataReference { *WTF::get<RefPtr<WebCore::SharedBuffer>>(data) };
    61     }
     39    SharedMemory::Handle handle;
     40    data->createHandle(handle, SharedMemory::Protection::ReadOnly);
     41    encoder << handle;
    6242
    6343    encoder << conditionsApplyOnlyToDomainOffset;
     
    7454Optional<WebCompiledContentRuleListData> WebCompiledContentRuleListData::decode(IPC::Decoder& decoder)
    7555{
    76     Variant<RefPtr<SharedMemory>, RefPtr<WebCore::SharedBuffer>> data;
    77 
    78     Optional<bool> hasSharedMemory;
    79     decoder >> hasSharedMemory;
    80     if (!hasSharedMemory)
     56    SharedMemory::Handle handle;
     57    if (!decoder.decode(handle))
    8158        return WTF::nullopt;
    82 
    83     if (*hasSharedMemory) {
    84         SharedMemory::Handle handle;
    85         if (!decoder.decode(handle))
    86             return WTF::nullopt;
    87         data = { SharedMemory::map(handle, SharedMemory::Protection::ReadOnly) };
    88     } else {
    89         IPC::DataReference dataReference;
    90         if (!decoder.decode(dataReference))
    91             return WTF::nullopt;
    92         data = { RefPtr<WebCore::SharedBuffer>(WebCore::SharedBuffer::create(dataReference.data(), dataReference.size())) };
    93     }
     59    RefPtr<SharedMemory> data = SharedMemory::map(handle, SharedMemory::Protection::ReadOnly);
    9460
    9561    Optional<unsigned> conditionsApplyOnlyToDomainOffset;
  • trunk/Source/WebKit/Shared/WebCompiledContentRuleListData.h

    r244403 r244597  
    4242class WebCompiledContentRuleListData {
    4343public:
    44     WebCompiledContentRuleListData(Variant<RefPtr<SharedMemory>, RefPtr<WebCore::SharedBuffer>>&& data, unsigned conditionsApplyOnlyToDomainOffset, unsigned actionsOffset, unsigned actionsSize, unsigned filtersWithoutConditionsBytecodeOffset, unsigned filtersWithoutConditionsBytecodeSize, unsigned filtersWithConditionsBytecodeOffset, unsigned filtersWithConditionsBytecodeSize, unsigned topURLFiltersBytecodeOffset, unsigned topURLFiltersBytecodeSize)
     44    WebCompiledContentRuleListData(RefPtr<SharedMemory>&& data, unsigned conditionsApplyOnlyToDomainOffset, unsigned actionsOffset, unsigned actionsSize, unsigned filtersWithoutConditionsBytecodeOffset, unsigned filtersWithoutConditionsBytecodeSize, unsigned filtersWithConditionsBytecodeOffset, unsigned filtersWithConditionsBytecodeSize, unsigned topURLFiltersBytecodeOffset, unsigned topURLFiltersBytecodeSize)
    4545        : data(WTFMove(data))
    4646        , conditionsApplyOnlyToDomainOffset(conditionsApplyOnlyToDomainOffset)
     
    5959    static Optional<WebCompiledContentRuleListData> decode(IPC::Decoder&);
    6060
    61     size_t size() const;
    62     const void* dataPointer() const;
    63    
    64     Variant<RefPtr<SharedMemory>, RefPtr<WebCore::SharedBuffer>> data;
     61    RefPtr<SharedMemory> data;
    6562    unsigned conditionsApplyOnlyToDomainOffset { 0 };
    6663    unsigned actionsOffset { 0 };
  • trunk/Source/WebKit/SourcesCocoa.txt

    r243808 r244597  
    2323
    2424NetworkProcess/cache/NetworkCacheDataCocoa.mm
     25NetworkProcess/cache/NetworkCacheFileSystemCocoa.mm
    2526NetworkProcess/cache/NetworkCacheIOChannelCocoa.mm
    2627
  • trunk/Source/WebKit/UIProcess/API/APIContentRuleList.cpp

    r244403 r244597  
    4444}
    4545
    46 bool ContentRuleList::usesCopiedMemory() const
    47 {
    48     return m_compiledRuleList->usesCopiedMemory();
    49 }
    50 
    5146} // namespace API
    5247
  • trunk/Source/WebKit/UIProcess/API/APIContentRuleList.h

    r244403 r244597  
    5050    const WebKit::WebCompiledContentRuleList& compiledRuleList() const { return m_compiledRuleList.get(); }
    5151
    52     bool usesCopiedMemory() const;
    53 
    5452private:
    5553    WTF::String m_name;
  • trunk/Source/WebKit/UIProcess/API/APIContentRuleListStore.cpp

    r244403 r244597  
    202202}
    203203
    204 #if !PLATFORM(COCOA)
    205 RefPtr<WebCore::SharedBuffer> ContentRuleListStore::readContentsOfFile(const WTF::String& filePath)
    206 {
    207     ASSERT_NOT_REACHED();
    208     return nullptr;
    209 }
    210 #endif
    211 
    212 struct MappedOrCopiedData {
     204struct MappedData {
    213205    ContentRuleListMetaData metaData;
    214     Variant<WebKit::NetworkCache::Data, RefPtr<WebCore::SharedBuffer>> data;
    215    
    216     const uint8_t* dataPointer() const
    217     {
    218         return WTF::switchOn(data, [] (const WebKit::NetworkCache::Data& data) {
    219             return data.data();
    220         }, [] (const RefPtr<WebCore::SharedBuffer>& sharedBuffer) {
    221             return reinterpret_cast<const uint8_t*>(sharedBuffer->data());
    222         });
    223     }
     206    WebKit::NetworkCache::Data data;
    224207};
    225208
    226 static Optional<MappedOrCopiedData> openAndMapOrCopyContentRuleList(const WTF::String& path)
    227 {
    228     if (!WebKit::NetworkCache::isSafeToUseMemoryMapForPath(path)) {
    229         RefPtr<WebCore::SharedBuffer> buffer = ContentRuleListStore::readContentsOfFile(path);
    230         if (!buffer)
    231             return WTF::nullopt;
    232         auto metaData = decodeContentRuleListMetaData(*buffer);
    233         if (!metaData)
    234             return WTF::nullopt;
    235         return {{ WTFMove(*metaData), { buffer.releaseNonNull() }}};
    236     }
    237 
     209static Optional<MappedData> openAndMapOrCopyContentRuleList(const WTF::String& path)
     210{
     211    WebKit::NetworkCache::makeSafeToUseMemoryMapForPath(path);
    238212    WebKit::NetworkCache::Data fileData = mapFile(fileSystemRepresentation(path).data());
    239213    if (fileData.isNull())
     
    259233}
    260234
    261 static Expected<MappedOrCopiedData, std::error_code> compiledToFile(WTF::String&& json, Vector<WebCore::ContentExtensions::ContentExtensionRule>&& parsedRules, const WTF::String& finalFilePath)
     235static Expected<MappedData, std::error_code> compiledToFile(WTF::String&& json, Vector<WebCore::ContentExtensions::ContentExtensionRule>&& parsedRules, const WTF::String& finalFilePath)
    262236{
    263237    using namespace WebCore::ContentExtensions;
     
    412386        return makeUnexpected(ContentRuleListStore::Error::CompileFailed);
    413387    }
    414 
    415     if (!isSafeToUseMemoryMapForPath(finalFilePath)) {
    416         auto contents = ContentRuleListStore::readContentsOfFile(finalFilePath);
    417         if (!contents)
    418             return makeUnexpected(ContentRuleListStore::Error::CompileFailed);
    419         return {{ WTFMove(metaData), WTFMove(contents) }};
    420     }
     388   
     389    makeSafeToUseMemoryMapForPath(finalFilePath);
    421390   
    422391    return {{ WTFMove(metaData), WTFMove(mappedData) }};
    423392}
    424393
    425 static Ref<API::ContentRuleList> createExtension(const WTF::String& identifier, MappedOrCopiedData&& data)
    426 {
    427     RefPtr<WebKit::SharedMemory> sharedMemory;
    428     if (auto mappedFileData = WTF::get_if<WebKit::NetworkCache::Data>(data.data)) {
    429         sharedMemory = mappedFileData->tryCreateSharedMemory();
    430 
    431         // Content extensions are always compiled to files, and at this point the file
    432         // has been already mapped, therefore tryCreateSharedMemory() cannot fail.
    433         ASSERT(sharedMemory);
    434     }
    435     auto mappedOrCopiedFileData = sharedMemory ?
    436         Variant<RefPtr<WebKit::SharedMemory>, RefPtr<WebCore::SharedBuffer>> { sharedMemory }
    437         : Variant<RefPtr<WebKit::SharedMemory>, RefPtr<WebCore::SharedBuffer>> { WTFMove(WTF::get<RefPtr<WebCore::SharedBuffer>>(data.data)) };
     394static Ref<API::ContentRuleList> createExtension(const WTF::String& identifier, MappedData&& data)
     395{
     396    auto sharedMemory = data.data.tryCreateSharedMemory();
     397
     398    // Content extensions are always compiled to files, and at this point the file
     399    // has been already mapped, therefore tryCreateSharedMemory() cannot fail.
     400    ASSERT(sharedMemory);
    438401
    439402    const size_t headerAndSourceSize = ContentRuleListFileHeaderSize + data.metaData.sourceSize;
    440403    auto compiledContentRuleListData = WebKit::WebCompiledContentRuleListData(
    441         WTFMove(mappedOrCopiedFileData),
     404        WTFMove(sharedMemory),
    442405        ConditionsApplyOnlyToDomainOffset,
    443406        headerAndSourceSize,
     
    457420    );
    458421    auto compiledContentRuleList = WebKit::WebCompiledContentRuleList::create(WTFMove(compiledContentRuleListData));
    459     return API::ContentRuleList::create(identifier, WTFMove(compiledContentRuleList), WTF::holds_alternative<WebKit::NetworkCache::Data>(data.data) ? WTF::get<WebKit::NetworkCache::Data>(data.data) : WebKit::NetworkCache::Data { });
     422    return API::ContentRuleList::create(identifier, WTFMove(compiledContentRuleList), WTFMove(data.data));
    460423}
    461424
     
    589552                return;
    590553            }
    591             bool is8Bit = contentRuleList->dataPointer()[ContentRuleListFileHeaderSize];
     554            bool is8Bit = contentRuleList->data.data()[ContentRuleListFileHeaderSize];
    592555            size_t start = ContentRuleListFileHeaderSize + sizeof(bool);
    593556            size_t length = contentRuleList->metaData.sourceSize - sizeof(bool);
    594557            if (is8Bit)
    595                 complete(WTF::String(contentRuleList->dataPointer() + start, length));
     558                complete(WTF::String(contentRuleList->data.data() + start, length));
    596559            else {
    597560                ASSERT(!(length % sizeof(UChar)));
    598                 complete(WTF::String(reinterpret_cast<const UChar*>(contentRuleList->dataPointer() + start), length / sizeof(UChar)));
     561                complete(WTF::String(reinterpret_cast<const UChar*>(contentRuleList->data.data() + start), length / sizeof(UChar)));
    599562            }
    600563            return;
  • trunk/Source/WebKit/UIProcess/API/APIContentRuleListStore.h

    r242735 r244597  
    7777    void getContentRuleListSource(const WTF::String& identifier, CompletionHandler<void(WTF::String)>);
    7878
    79     static RefPtr<WebCore::SharedBuffer> readContentsOfFile(const WTF::String& path);
    80 
    8179private:
    8280    WTF::String defaultStorePath(bool legacyFilename);
  • trunk/Source/WebKit/UIProcess/API/Cocoa/APIContentRuleListStoreCocoa.mm

    r242735 r244597  
    6565}
    6666
    67 RefPtr<WebCore::SharedBuffer> ContentRuleListStore::readContentsOfFile(const String& filePath)
    68 {
    69     ASSERT(!isMainThread());
    70     NSData *data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:filePath isDirectory:NO]];
    71     if (!data)
    72         return nullptr;
    73     return WebCore::SharedBuffer::create(data);
    74 }
    75 
    7667} // namespace API
    7768
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKContentRuleListStore.mm

    r242735 r244597  
    127127// For testing only.
    128128
    129 + (void)_registerPathAsUnsafeToMemoryMapForTesting:(NSString *)filename
    130 {
    131     WebKit::NetworkCache::registerPathAsUnsafeToMemoryMapForTesting(filename);
    132 }
    133 
    134129- (void)_removeAllContentRuleLists
    135130{
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKContentRuleListStorePrivate.h

    r242735 r244597  
    3232- (void)_invalidateContentRuleListVersionForIdentifier:(NSString *)identifier;
    3333- (void)_getContentRuleListSourceForIdentifier:(NSString *)identifier completionHandler:(void (^)(NSString*))completionHandler;
    34 + (void)_registerPathAsUnsafeToMemoryMapForTesting:(NSString *)filename;
    3534
    3635// NS_RELEASES_ARGUMENT to keep peak memory usage low.
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKUserContentFilter.mm

    r242735 r244597  
    5757}
    5858
    59 - (BOOL)usesCopiedMemory
    60 {
    61     return _contentRuleList->_contentRuleList->usesCopiedMemory();
    62 }
    63 
    6459@end
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKUserContentFilterPrivate.h

    r243376 r244597  
    3131
    3232- (id)_initWithWKContentRuleList:(WKContentRuleList*)contentRuleList WK_API_AVAILABLE(macos(10.13), ios(11.0));
    33 @property (nonatomic, readonly) BOOL usesCopiedMemory;
    3433
    3534@end
  • trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj

    r244575 r244597  
    35613561                5CBC9B8B1C65257300A8FDCF /* NetworkDataTaskCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NetworkDataTaskCocoa.mm; sourceTree = "<group>"; };
    35623562                5CC5DB9121488E16006CB8A8 /* SharedBufferDataReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedBufferDataReference.h; sourceTree = "<group>"; };
     3563                5CD150762268F7F0006FB4AF /* NetworkCacheFileSystemCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NetworkCacheFileSystemCocoa.mm; sourceTree = "<group>"; };
    35633564                5CD286491E722F440094FDC8 /* _WKUserContentFilterPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKUserContentFilterPrivate.h; sourceTree = "<group>"; };
    35643565                5CD2864A1E722F440094FDC8 /* WKContentRuleList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKContentRuleList.h; sourceTree = "<group>"; };
     
    89458946                                E4697CCC1B25EB8F001B0A6C /* NetworkCacheFileSystem.cpp */,
    89468947                                834B250E1A831A8D00CFB150 /* NetworkCacheFileSystem.h */,
     8948                                5CD150762268F7F0006FB4AF /* NetworkCacheFileSystemCocoa.mm */,
    89478949                                E42E060B1AA7440D00B11699 /* NetworkCacheIOChannel.h */,
    89488950                                E42E060D1AA750E500B11699 /* NetworkCacheIOChannelCocoa.mm */,
  • trunk/Tools/ChangeLog

    r244594 r244597  
     12019-04-24  Alex Christensen  <achristensen@webkit.org>
     2
     3        WKContentRuleLists should have a maximum FileProtection of CompleteUnlessOpen
     4        https://bugs.webkit.org/show_bug.cgi?id=197078
     5        <rdar://problem/49564348>
     6
     7        Reviewed by Geoff Garen.
     8
     9        * TestWebKitAPI/Tests/WebKitCocoa/WKContentExtensionStore.mm:
     10        (TEST_F):
     11        (-[TestSchemeHandlerSubresourceShouldBeBlocked webView:startURLSchemeTask:]): Deleted.
     12        (-[TestSchemeHandlerSubresourceShouldBeBlocked webView:stopURLSchemeTask:]): Deleted.
     13        Unfortunately, setting the NSFileProtectionKey attribute is only supported on iOS devices.
     14
    1152019-04-24  Alex Christensen  <achristensen@webkit.org>
    216
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKContentExtensionStore.mm

    r242735 r244597  
    2929#import "PlatformUtilities.h"
    3030#import "Test.h"
    31 #import "TestWKWebView.h"
    3231#import <WebKit/WKContentRuleList.h>
    3332#import <WebKit/WKContentRuleListStorePrivate.h>
    34 #import <WebKit/_WKUserContentFilterPrivate.h>
    3533#import <wtf/RetainPtr.h>
    36 #import <wtf/text/StringBuilder.h>
    37 #import <wtf/text/StringConcatenate.h>
    38 #import <wtf/text/StringConcatenateNumbers.h>
    3934
    4035class WKContentRuleListStoreTest : public testing::Test {
     
    384379}
    385380
    386 @interface TestSchemeHandlerSubresourceShouldBeBlocked : NSObject <WKURLSchemeHandler>
    387 @end
    388 @implementation TestSchemeHandlerSubresourceShouldBeBlocked
    389 - (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)task
    390 {
    391     EXPECT_TRUE([task.request.URL.path isEqualToString:@"/shouldload"]);
    392     [task didReceiveResponse:[[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:0 textEncodingName:nil] autorelease]];
    393     [task didFinish];
    394 }
    395 - (void)webView:(WKWebView *)webView stopURLSchemeTask:(id <WKURLSchemeTask>)task
    396 {
    397     EXPECT_TRUE(false);
    398 }
    399 @end
    400 
     381#if PLATFORM(IOS_FAMILY)
    401382TEST_F(WKContentRuleListStoreTest, UnsafeMMap)
    402383{
    403384    RetainPtr<NSString> tempDir = [NSTemporaryDirectory() stringByAppendingPathComponent:@"UnsafeMMapTest"];
    404385    RetainPtr<WKContentRuleListStore> store = [WKContentRuleListStore storeWithURL:[NSURL fileURLWithPath:tempDir.get() isDirectory:YES]];
    405     static NSString *identifier = @"TestRuleList";
    406     static NSString *fileName = @"ContentRuleList-TestRuleList";
     386    static NSString *compiledIdentifier = @"CompiledRuleList";
     387    static NSString *copiedIdentifier = @"CopiedRuleList";
    407388    static NSString *ruleListSourceString = @"[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"blockedsubresource\"}}]";
    408     RetainPtr<NSString> filePath = [tempDir stringByAppendingPathComponent:fileName];
    409 
    410     auto runTest = [&] (bool shouldUseCopiedMemory) {
    411         EXPECT_FALSE([[NSFileManager defaultManager] fileExistsAtPath:filePath.get()]);
    412        
    413         __block bool doneCompiling = false;
    414         __block RetainPtr<WKContentRuleList> ruleList;
    415         [store compileContentRuleListForIdentifier:identifier encodedContentRuleList:ruleListSourceString completionHandler:^(WKContentRuleList *filter, NSError *error) {
    416             EXPECT_NOT_NULL(filter);
    417             EXPECT_NULL(error);
    418             doneCompiling = true;
    419             ruleList = filter;
    420             EXPECT_TRUE([[[[_WKUserContentFilter alloc] _initWithWKContentRuleList:filter] autorelease] usesCopiedMemory] == shouldUseCopiedMemory);
    421         }];
    422         TestWebKitAPI::Util::run(&doneCompiling);
    423        
    424         EXPECT_TRUE([[NSFileManager defaultManager] fileExistsAtPath:filePath.get()]);
    425 
    426         auto handler = adoptNS([TestSchemeHandlerSubresourceShouldBeBlocked new]);
    427         auto configuration = adoptNS([WKWebViewConfiguration new]);
    428         [configuration setURLSchemeHandler:handler.get() forURLScheme:@"testmmap"];
    429         [[configuration userContentController] addContentRuleList:ruleList.get()];
    430         auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    431         [webView synchronouslyLoadHTMLString:@"<html>main resource content</html>" baseURL:[NSURL URLWithString:@"testmmap://webkit.org/mainresource"]];
    432 
    433         auto loadingShouldSucceed = [&] (NSString *resourcePath, NSString *shouldSucceed) {
    434             __block bool doneEvaluating = false;
    435             [webView evaluateJavaScript:[NSString stringWithFormat:@"var caught = false; var xhr = new XMLHttpRequest(); xhr.open('GET', '%@', false); try{ xhr.send() } catch(e) { caught = true; }; caught != %@ ? 'success' : 'failure'", resourcePath, shouldSucceed] completionHandler:^(id result, NSError *error) {
    436                 EXPECT_NULL(error);
    437                 EXPECT_TRUE([@"success" isEqualToString:result]);
    438                 doneEvaluating = true;
    439             }];
    440             TestWebKitAPI::Util::run(&doneEvaluating);
    441         };
    442         loadingShouldSucceed(@"/shouldload", @"true");
    443         loadingShouldSucceed(@"/blockedsubresource", @"false");
    444 
    445         [[configuration userContentController] removeContentRuleList:ruleList.get()];
    446        
    447         __block bool doneLookingUp = false;
    448         [store lookUpContentRuleListForIdentifier:identifier completionHandler:^(WKContentRuleList *filter, NSError *error) {
    449             EXPECT_NOT_NULL(filter);
    450             EXPECT_NULL(error);
    451            
    452             doneLookingUp = true;
    453            
    454             EXPECT_TRUE([[[[_WKUserContentFilter alloc] _initWithWKContentRuleList:filter] autorelease] usesCopiedMemory] == shouldUseCopiedMemory);
    455             ruleList = filter;
    456         }];
    457         TestWebKitAPI::Util::run(&doneLookingUp);
    458 
    459         [[configuration userContentController] addContentRuleList:ruleList.get()];
    460         loadingShouldSucceed(@"/shouldload", @"true");
    461         loadingShouldSucceed(@"/blockedsubresource", @"false");
    462 
    463         __block bool doneCheckingSource = false;
    464         [store _getContentRuleListSourceForIdentifier:identifier completionHandler:^(NSString *source) {
    465             EXPECT_TRUE([source isEqualToString:ruleListSourceString]);
    466             doneCheckingSource = true;
    467         }];
    468         TestWebKitAPI::Util::run(&doneCheckingSource);
    469        
    470         __block bool doneRemoving = false;
    471         [store removeContentRuleListForIdentifier:identifier completionHandler:^(NSError *error) {
     389    RetainPtr<NSString> compiledFilePath = [tempDir stringByAppendingPathComponent:@"ContentRuleList-CompiledRuleList"];
     390    RetainPtr<NSString> copiedFilePath = [tempDir stringByAppendingPathComponent:@"ContentRuleList-CopiedRuleList"];
     391
     392    __block bool doneCompiling = false;
     393    [store compileContentRuleListForIdentifier:compiledIdentifier encodedContentRuleList:ruleListSourceString completionHandler:^(WKContentRuleList *filter, NSError *error) {
     394        EXPECT_NOT_NULL(filter);
     395        EXPECT_NULL(error);
     396        doneCompiling = true;
     397    }];
     398    TestWebKitAPI::Util::run(&doneCompiling);
     399
     400    auto hasCompleteProtection = [] (const RetainPtr<NSString>& path) {
     401        NSError *error = nil;
     402        NSDictionary<NSFileAttributeKey, id> *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path.get() error:&error];
     403        EXPECT_NULL(error);
     404        return [[attributes objectForKey:NSFileProtectionKey] isEqualToString:NSFileProtectionComplete];
     405    };
     406   
     407    NSError *error = nil;
     408    [[NSFileManager defaultManager] copyItemAtPath:compiledFilePath.get() toPath:copiedFilePath.get() error:&error];
     409    EXPECT_NULL(error);
     410    EXPECT_FALSE(hasCompleteProtection(copiedFilePath));
     411    [[NSFileManager defaultManager] setAttributes:@{ NSFileProtectionKey: NSFileProtectionComplete } ofItemAtPath:copiedFilePath.get() error:&error];
     412    EXPECT_NULL(error);
     413#if !PLATFORM(IOS_FAMILY_SIMULATOR)
     414    EXPECT_TRUE(hasCompleteProtection(copiedFilePath));
     415#endif
     416
     417    __block bool doneLookingUp = false;
     418    [store lookUpContentRuleListForIdentifier:copiedIdentifier completionHandler:^(WKContentRuleList *filter, NSError *error) {
     419        EXPECT_NOT_NULL(filter);
     420        EXPECT_NULL(error);
     421        doneLookingUp = true;
     422    }];
     423    TestWebKitAPI::Util::run(&doneLookingUp);
     424    EXPECT_FALSE(hasCompleteProtection(copiedFilePath));
     425   
     426    __block bool doneRemoving = false;
     427    [store removeContentRuleListForIdentifier:compiledIdentifier completionHandler:^(NSError *error) {
     428        EXPECT_NULL(error);
     429        [store removeContentRuleListForIdentifier:copiedIdentifier completionHandler:^(NSError *error) {
    472430            EXPECT_NULL(error);
    473431            doneRemoving = true;
    474432        }];
    475         TestWebKitAPI::Util::run(&doneRemoving);
    476 
    477         EXPECT_FALSE([[NSFileManager defaultManager] fileExistsAtPath:filePath.get()]);
    478     };
    479    
    480     runTest(false);
    481     [WKContentRuleListStore _registerPathAsUnsafeToMemoryMapForTesting:filePath.get()];
    482     runTest(true);
    483 }
     433    }];
     434    TestWebKitAPI::Util::run(&doneRemoving);
     435}
     436#endif // PLATFORM(IOS_FAMILY)
Note: See TracChangeset for help on using the changeset viewer.