Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: extensions/browser/content_verifier.cc

Issue 1315713009: Fix content verification failures on unusual content script paths (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/browser/content_verifier.h" 5 #include "extensions/browser/content_verifier.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 void ContentVerifier::Shutdown() { 55 void ContentVerifier::Shutdown() {
56 shutdown_ = true; 56 shutdown_ = true;
57 content::BrowserThread::PostTask( 57 content::BrowserThread::PostTask(
58 content::BrowserThread::IO, 58 content::BrowserThread::IO,
59 FROM_HERE, 59 FROM_HERE,
60 base::Bind(&ContentVerifierIOData::Clear, io_data_)); 60 base::Bind(&ContentVerifierIOData::Clear, io_data_));
61 observer_.RemoveAll(); 61 observer_.RemoveAll();
62 fetcher_.reset(); 62 fetcher_.reset();
63 } 63 }
64 64
65 static base::FilePath MakePathRelative(const base::FilePath& path) {
Ken Rockot(use gerrit already) 2015/09/09 16:56:10 nit since you're moving this, might as well nix th
asargent_no_longer_on_chrome 2015/09/09 17:42:39 Done. Renamed to "NormalizeRelativePath" also.
66 if (path.ReferencesParent())
67 return base::FilePath();
68
69 std::vector<base::FilePath::StringType> parts;
70 path.GetComponents(&parts);
71 if (parts.empty())
72 return base::FilePath();
73
74 // Remove the first component if it is '.' or '/' or '//'.
75 const base::FilePath::StringType separators(
76 base::FilePath::kSeparators, base::FilePath::kSeparatorsLength);
77 if (!parts[0].empty() &&
78 (parts[0] == base::FilePath::kCurrentDirectory ||
79 parts[0].find_first_not_of(separators) == std::string::npos))
80 parts.erase(parts.begin());
81
82 // Note that elsewhere we always normalize path separators to '/' so this
83 // should work for all platforms.
84 return base::FilePath(base::JoinString(parts, "/"));
85 }
86
65 ContentVerifyJob* ContentVerifier::CreateJobFor( 87 ContentVerifyJob* ContentVerifier::CreateJobFor(
66 const std::string& extension_id, 88 const std::string& extension_id,
67 const base::FilePath& extension_root, 89 const base::FilePath& extension_root,
68 const base::FilePath& relative_path) { 90 const base::FilePath& relative_path) {
Ken Rockot(use gerrit already) 2015/09/09 16:56:10 nit: Maybe instead of calling this |relative_path|
asargent_no_longer_on_chrome 2015/09/09 17:42:39 I sort of like calling the argument relative_path
69 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 91 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
70 92
71 const ContentVerifierIOData::ExtensionData* data = 93 const ContentVerifierIOData::ExtensionData* data =
72 io_data_->GetData(extension_id); 94 io_data_->GetData(extension_id);
73 if (!data) 95 if (!data)
74 return NULL; 96 return NULL;
75 97
98 base::FilePath actual_relative_path = MakePathRelative(relative_path);
99
76 std::set<base::FilePath> paths; 100 std::set<base::FilePath> paths;
77 paths.insert(relative_path); 101 paths.insert(actual_relative_path);
78 if (!ShouldVerifyAnyPaths(extension_id, extension_root, paths)) 102 if (!ShouldVerifyAnyPaths(extension_id, extension_root, paths))
79 return NULL; 103 return NULL;
80 104
81 // TODO(asargent) - we can probably get some good performance wins by having 105 // TODO(asargent) - we can probably get some good performance wins by having
82 // a cache of ContentHashReader's that we hold onto past the end of each job. 106 // a cache of ContentHashReader's that we hold onto past the end of each job.
83 return new ContentVerifyJob( 107 return new ContentVerifyJob(
84 new ContentHashReader(extension_id, data->version, extension_root, 108 new ContentHashReader(extension_id, data->version, extension_root,
85 relative_path, delegate_->GetPublicKey()), 109 actual_relative_path, delegate_->GetPublicKey()),
86 base::Bind(&ContentVerifier::VerifyFailed, this, extension_id)); 110 base::Bind(&ContentVerifier::VerifyFailed, this, extension_id));
87 } 111 }
88 112
89 void ContentVerifier::VerifyFailed(const std::string& extension_id, 113 void ContentVerifier::VerifyFailed(const std::string& extension_id,
90 ContentVerifyJob::FailureReason reason) { 114 ContentVerifyJob::FailureReason reason) {
91 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { 115 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
92 content::BrowserThread::PostTask( 116 content::BrowserThread::PostTask(
93 content::BrowserThread::UI, 117 content::BrowserThread::UI,
94 FROM_HERE, 118 FROM_HERE,
95 base::Bind(&ContentVerifier::VerifyFailed, this, extension_id, reason)); 119 base::Bind(&ContentVerifier::VerifyFailed, this, extension_id, reason));
(...skipping 13 matching lines...) Expand all
109 133
110 if (reason == ContentVerifyJob::MISSING_ALL_HASHES) { 134 if (reason == ContentVerifyJob::MISSING_ALL_HASHES) {
111 // If we failed because there were no hashes yet for this extension, just 135 // If we failed because there were no hashes yet for this extension, just
112 // request some. 136 // request some.
113 fetcher_->DoFetch(extension, true /* force */); 137 fetcher_->DoFetch(extension, true /* force */);
114 } else { 138 } else {
115 delegate_->VerifyFailed(extension_id, reason); 139 delegate_->VerifyFailed(extension_id, reason);
116 } 140 }
117 } 141 }
118 142
119 static base::FilePath MakeImagePathRelative(const base::FilePath& path) {
120 if (path.ReferencesParent())
121 return base::FilePath();
122
123 std::vector<base::FilePath::StringType> parts;
124 path.GetComponents(&parts);
125 if (parts.empty())
126 return base::FilePath();
127
128 // Remove the first component if it is '.' or '/' or '//'.
129 const base::FilePath::StringType separators(
130 base::FilePath::kSeparators, base::FilePath::kSeparatorsLength);
131 if (!parts[0].empty() &&
132 (parts[0] == base::FilePath::kCurrentDirectory ||
133 parts[0].find_first_not_of(separators) == std::string::npos))
134 parts.erase(parts.begin());
135
136 // Note that elsewhere we always normalize path separators to '/' so this
137 // should work for all platforms.
138 return base::FilePath(
139 base::JoinString(parts, base::FilePath::StringType(1, '/')));
140 }
141
142 void ContentVerifier::OnExtensionLoaded( 143 void ContentVerifier::OnExtensionLoaded(
143 content::BrowserContext* browser_context, 144 content::BrowserContext* browser_context,
144 const Extension* extension) { 145 const Extension* extension) {
145 if (shutdown_) 146 if (shutdown_)
146 return; 147 return;
147 148
148 ContentVerifierDelegate::Mode mode = delegate_->ShouldBeVerified(*extension); 149 ContentVerifierDelegate::Mode mode = delegate_->ShouldBeVerified(*extension);
149 if (mode != ContentVerifierDelegate::NONE) { 150 if (mode != ContentVerifierDelegate::NONE) {
150 // The browser image paths from the extension may not be relative (eg 151 // The browser image paths from the extension may not be relative (eg
151 // they might have leading '/' or './'), so we strip those to make 152 // they might have leading '/' or './'), so we strip those to make
152 // comparing to actual relative paths work later on. 153 // comparing to actual relative paths work later on.
153 std::set<base::FilePath> original_image_paths = 154 std::set<base::FilePath> original_image_paths =
154 delegate_->GetBrowserImagePaths(extension); 155 delegate_->GetBrowserImagePaths(extension);
155 156
156 scoped_ptr<std::set<base::FilePath>> image_paths( 157 scoped_ptr<std::set<base::FilePath>> image_paths(
157 new std::set<base::FilePath>); 158 new std::set<base::FilePath>);
158 for (const auto& path : original_image_paths) { 159 for (const auto& path : original_image_paths) {
159 image_paths->insert(MakeImagePathRelative(path)); 160 image_paths->insert(MakePathRelative(path));
160 } 161 }
161 162
162 scoped_ptr<ContentVerifierIOData::ExtensionData> data( 163 scoped_ptr<ContentVerifierIOData::ExtensionData> data(
163 new ContentVerifierIOData::ExtensionData( 164 new ContentVerifierIOData::ExtensionData(
164 image_paths.Pass(), 165 image_paths.Pass(),
165 extension->version() ? *extension->version() : base::Version())); 166 extension->version() ? *extension->version() : base::Version()));
166 content::BrowserThread::PostTask(content::BrowserThread::IO, 167 content::BrowserThread::PostTask(content::BrowserThread::IO,
167 FROM_HERE, 168 FROM_HERE,
168 base::Bind(&ContentVerifierIOData::AddData, 169 base::Bind(&ContentVerifierIOData::AddData,
169 io_data_, 170 io_data_,
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 !extension_l10n_util::ShouldSkipValidation( 277 !extension_l10n_util::ShouldSkipValidation(
277 locales_dir, full_path.DirName(), *all_locales)) 278 locales_dir, full_path.DirName(), *all_locales))
278 continue; 279 continue;
279 } 280 }
280 return true; 281 return true;
281 } 282 }
282 return false; 283 return false;
283 } 284 }
284 285
285 } // namespace extensions 286 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698