Commit b9e6a930 authored by Karan Bhatia's avatar Karan Bhatia Committed by Commit Bot

DNR: Load ruleset directly in memory instead of mmap-ing it.

This CL changes the ruleset file data to no longer be memory mapped. This was
not ideal since mmap-ing a file on the IO thread can cause it to get de-
scheduled in case of a page fault, which we do not want. This CL changes the
ruleset file data to be copied and available directly in memory.

BUG=774271, 696822

Change-Id: I1c8aae2c1d48a7bf68a2c878a227d15344588039
Reviewed-on: https://chromium-review.googlesource.com/874595Reviewed-by: default avatarIstiaque Ahmed <lazyboy@chromium.org>
Reviewed-by: default avatarIlya Sherman <isherman@chromium.org>
Commit-Queue: Karan Bhatia <karandeepb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#530703}
parent a375bb24
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
#include "base/timer/elapsed_timer.h" #include "base/timer/elapsed_timer.h"
#include "extensions/browser/api/declarative_net_request/flat/extension_ruleset_generated.h" #include "extensions/browser/api/declarative_net_request/flat/extension_ruleset_generated.h"
...@@ -23,9 +22,6 @@ namespace declarative_net_request { ...@@ -23,9 +22,6 @@ namespace declarative_net_request {
namespace flat_rule = url_pattern_index::flat; namespace flat_rule = url_pattern_index::flat;
namespace { namespace {
void DeleteRulesetHelper(std::unique_ptr<base::MemoryMappedFile> ruleset) {
base::AssertBlockingAllowed();
}
using FindRuleStrategy = using FindRuleStrategy =
url_pattern_index::UrlPatternIndexMatcher::FindRuleStrategy; url_pattern_index::UrlPatternIndexMatcher::FindRuleStrategy;
...@@ -46,16 +42,13 @@ RulesetMatcher::LoadRulesetResult RulesetMatcher::CreateVerifiedMatcher( ...@@ -46,16 +42,13 @@ RulesetMatcher::LoadRulesetResult RulesetMatcher::CreateVerifiedMatcher(
if (!base::PathExists(indexed_ruleset_path)) if (!base::PathExists(indexed_ruleset_path))
return kLoadErrorInvalidPath; return kLoadErrorInvalidPath;
// TODO(crbug.com/774271): Revisit mmap-ing the file. std::string ruleset_data;
auto ruleset = std::make_unique<base::MemoryMappedFile>(); if (!base::ReadFileToString(indexed_ruleset_path, &ruleset_data))
if (!ruleset->Initialize(indexed_ruleset_path, return kLoadErrorFileRead;
base::MemoryMappedFile::READ_ONLY)) {
return kLoadErrorMemoryMap;
}
// This guarantees that no memory access will end up outside the buffer. // This guarantees that no memory access will end up outside the buffer.
if (!IsValidRulesetData(ruleset->data(), ruleset->length(), if (!IsValidRulesetData(reinterpret_cast<const uint8_t*>(ruleset_data.data()),
expected_ruleset_checksum)) { ruleset_data.size(), expected_ruleset_checksum)) {
return kLoadErrorRulesetVerification; return kLoadErrorRulesetVerification;
} }
...@@ -65,18 +58,11 @@ RulesetMatcher::LoadRulesetResult RulesetMatcher::CreateVerifiedMatcher( ...@@ -65,18 +58,11 @@ RulesetMatcher::LoadRulesetResult RulesetMatcher::CreateVerifiedMatcher(
// Using WrapUnique instead of make_unique since this class has a private // Using WrapUnique instead of make_unique since this class has a private
// constructor. // constructor.
*matcher = base::WrapUnique(new RulesetMatcher(std::move(ruleset))); *matcher = base::WrapUnique(new RulesetMatcher(std::move(ruleset_data)));
return kLoadSuccess; return kLoadSuccess;
} }
RulesetMatcher::~RulesetMatcher() { RulesetMatcher::~RulesetMatcher() = default;
// |ruleset_| must be destroyed on a sequence which supports file IO.
// TODO(crbug.com/696822): Revisit this to ensure that this is safe and causes
// no resource leak even if this task fails.
base::PostTaskWithTraits(
FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
base::BindOnce(&DeleteRulesetHelper, std::move(ruleset_)));
}
bool RulesetMatcher::ShouldBlockRequest(const GURL& url, bool RulesetMatcher::ShouldBlockRequest(const GURL& url,
const url::Origin& first_party_origin, const url::Origin& first_party_origin,
...@@ -141,9 +127,9 @@ bool RulesetMatcher::ShouldRedirectRequest( ...@@ -141,9 +127,9 @@ bool RulesetMatcher::ShouldRedirectRequest(
return true; return true;
} }
RulesetMatcher::RulesetMatcher(std::unique_ptr<base::MemoryMappedFile> ruleset) RulesetMatcher::RulesetMatcher(std::string ruleset_data)
: ruleset_(std::move(ruleset)), : ruleset_data_(std::move(ruleset_data)),
root_(flat::GetExtensionIndexedRuleset(ruleset_->data())), root_(flat::GetExtensionIndexedRuleset(ruleset_data_.data())),
blacklist_matcher_(root_->blacklist_index()), blacklist_matcher_(root_->blacklist_index()),
whitelist_matcher_(root_->whitelist_index()), whitelist_matcher_(root_->whitelist_index()),
redirect_matcher_(root_->redirect_index()), redirect_matcher_(root_->redirect_index()),
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
#define EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_RULESET_MATCHER_H_ #define EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_RULESET_MATCHER_H_
#include <memory> #include <memory>
#include <string>
#include "base/files/memory_mapped_file.h"
#include "components/url_pattern_index/url_pattern_index.h" #include "components/url_pattern_index/url_pattern_index.h"
namespace base { namespace base {
...@@ -29,11 +29,10 @@ struct UrlRuleMetadata; ...@@ -29,11 +29,10 @@ struct UrlRuleMetadata;
} // namespace flat } // namespace flat
// RulesetMatcher encapsulates the Declarative Net Request API ruleset // RulesetMatcher encapsulates the Declarative Net Request API ruleset
// corresponding to a single extension. The ruleset file is memory mapped. This // corresponding to a single extension. This uses the url_pattern_index
// uses the url_pattern_index component to achieve fast matching of network // component to achieve fast matching of network requests against declarative
// requests against declarative rules. Since this class is immutable, it is // rules. Since this class is immutable, it is thread-safe. In practice it is
// thread-safe. In practice it is accessed on the IO thread but created on a // accessed on the IO thread but created on a sequence where file IO is allowed.
// sequence where file IO is allowed.
class RulesetMatcher { class RulesetMatcher {
public: public:
// Describes the result of creating a RulesetMatcher instance. // Describes the result of creating a RulesetMatcher instance.
...@@ -42,7 +41,7 @@ class RulesetMatcher { ...@@ -42,7 +41,7 @@ class RulesetMatcher {
enum LoadRulesetResult { enum LoadRulesetResult {
kLoadSuccess = 0, kLoadSuccess = 0,
kLoadErrorInvalidPath = 1, kLoadErrorInvalidPath = 1,
kLoadErrorMemoryMap = 2, kLoadErrorFileRead = 2,
kLoadErrorRulesetVerification = 3, kLoadErrorRulesetVerification = 3,
kLoadResultMax kLoadResultMax
}; };
...@@ -79,10 +78,9 @@ class RulesetMatcher { ...@@ -79,10 +78,9 @@ class RulesetMatcher {
using ExtensionMetadataList = using ExtensionMetadataList =
flatbuffers::Vector<flatbuffers::Offset<flat::UrlRuleMetadata>>; flatbuffers::Vector<flatbuffers::Offset<flat::UrlRuleMetadata>>;
explicit RulesetMatcher(std::unique_ptr<base::MemoryMappedFile> ruleset_file); explicit RulesetMatcher(std::string ruleset_data);
// The memory mapped ruleset file. const std::string ruleset_data_;
std::unique_ptr<base::MemoryMappedFile> ruleset_;
const flat::ExtensionIndexedRuleset* const root_; const flat::ExtensionIndexedRuleset* const root_;
const UrlPatternIndexMatcher blacklist_matcher_; const UrlPatternIndexMatcher blacklist_matcher_;
......
...@@ -25030,7 +25030,7 @@ Called by update_gpu_driver_bug_workaround_entries.py.--> ...@@ -25030,7 +25030,7 @@ Called by update_gpu_driver_bug_workaround_entries.py.-->
<enum name="LoadRulesetResult"> <enum name="LoadRulesetResult">
<int value="0" label="Load succeeded"/> <int value="0" label="Load succeeded"/>
<int value="1" label="Load failed - Invalid path"/> <int value="1" label="Load failed - Invalid path"/>
<int value="2" label="Load failed - Memory Map error"/> <int value="2" label="Load failed - File read error"/>
<int value="3" label="Load failed - Ruleset verification error"/> <int value="3" label="Load failed - Ruleset verification error"/>
</enum> </enum>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment