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

Side by Side Diff: components/policy/core/common/cloud/resource_cache.cc

Issue 2889683003: Rename TaskRunner::RunsTasksOnCurrentThread() in //components (Closed)
Patch Set: rebase Created 3 years, 5 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 (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "components/policy/core/common/cloud/resource_cache.h" 5 #include "components/policy/core/common/cloud/resource_cache.h"
6 6
7 #include "base/base64url.h" 7 #include "base/base64url.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/files/file_enumerator.h" 9 #include "base/files/file_enumerator.h"
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
(...skipping 29 matching lines...) Expand all
40 } // namespace 40 } // namespace
41 41
42 ResourceCache::ResourceCache( 42 ResourceCache::ResourceCache(
43 const base::FilePath& cache_dir, 43 const base::FilePath& cache_dir,
44 scoped_refptr<base::SequencedTaskRunner> task_runner) 44 scoped_refptr<base::SequencedTaskRunner> task_runner)
45 : cache_dir_(cache_dir), 45 : cache_dir_(cache_dir),
46 task_runner_(task_runner) { 46 task_runner_(task_runner) {
47 } 47 }
48 48
49 ResourceCache::~ResourceCache() { 49 ResourceCache::~ResourceCache() {
50 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 50 DCHECK(task_runner_->RunsTasksInCurrentSequence());
51 } 51 }
52 52
53 bool ResourceCache::Store(const std::string& key, 53 bool ResourceCache::Store(const std::string& key,
54 const std::string& subkey, 54 const std::string& subkey,
55 const std::string& data) { 55 const std::string& data) {
56 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 56 DCHECK(task_runner_->RunsTasksInCurrentSequence());
57 base::FilePath subkey_path; 57 base::FilePath subkey_path;
58 // Delete the file before writing to it. This ensures that the write does not 58 // Delete the file before writing to it. This ensures that the write does not
59 // follow a symlink planted at |subkey_path|, clobbering a file outside the 59 // follow a symlink planted at |subkey_path|, clobbering a file outside the
60 // cache directory. The mechanism is meant to foil file-system-level attacks 60 // cache directory. The mechanism is meant to foil file-system-level attacks
61 // where a symlink is planted in the cache directory before Chrome has 61 // where a symlink is planted in the cache directory before Chrome has
62 // started. An attacker controlling a process running concurrently with Chrome 62 // started. An attacker controlling a process running concurrently with Chrome
63 // would be able to race against the protection by re-creating the symlink 63 // would be able to race against the protection by re-creating the symlink
64 // between these two calls. There is nothing in file_util that could be used 64 // between these two calls. There is nothing in file_util that could be used
65 // to protect against such races, especially as the cache is cross-platform 65 // to protect against such races, especially as the cache is cross-platform
66 // and therefore cannot use any POSIX-only tricks. 66 // and therefore cannot use any POSIX-only tricks.
67 int size = base::checked_cast<int>(data.size()); 67 int size = base::checked_cast<int>(data.size());
68 return VerifyKeyPathAndGetSubkeyPath(key, true, subkey, &subkey_path) && 68 return VerifyKeyPathAndGetSubkeyPath(key, true, subkey, &subkey_path) &&
69 base::DeleteFile(subkey_path, false) && 69 base::DeleteFile(subkey_path, false) &&
70 (base::WriteFile(subkey_path, data.data(), size) == size); 70 (base::WriteFile(subkey_path, data.data(), size) == size);
71 } 71 }
72 72
73 bool ResourceCache::Load(const std::string& key, 73 bool ResourceCache::Load(const std::string& key,
74 const std::string& subkey, 74 const std::string& subkey,
75 std::string* data) { 75 std::string* data) {
76 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 76 DCHECK(task_runner_->RunsTasksInCurrentSequence());
77 base::FilePath subkey_path; 77 base::FilePath subkey_path;
78 // Only read from |subkey_path| if it is not a symlink. 78 // Only read from |subkey_path| if it is not a symlink.
79 if (!VerifyKeyPathAndGetSubkeyPath(key, false, subkey, &subkey_path) || 79 if (!VerifyKeyPathAndGetSubkeyPath(key, false, subkey, &subkey_path) ||
80 base::IsLink(subkey_path)) { 80 base::IsLink(subkey_path)) {
81 return false; 81 return false;
82 } 82 }
83 data->clear(); 83 data->clear();
84 return base::ReadFileToString(subkey_path, data); 84 return base::ReadFileToString(subkey_path, data);
85 } 85 }
86 86
87 void ResourceCache::LoadAllSubkeys( 87 void ResourceCache::LoadAllSubkeys(
88 const std::string& key, 88 const std::string& key,
89 std::map<std::string, std::string>* contents) { 89 std::map<std::string, std::string>* contents) {
90 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 90 DCHECK(task_runner_->RunsTasksInCurrentSequence());
91 contents->clear(); 91 contents->clear();
92 base::FilePath key_path; 92 base::FilePath key_path;
93 if (!VerifyKeyPath(key, false, &key_path)) 93 if (!VerifyKeyPath(key, false, &key_path))
94 return; 94 return;
95 95
96 base::FileEnumerator enumerator(key_path, false, base::FileEnumerator::FILES); 96 base::FileEnumerator enumerator(key_path, false, base::FileEnumerator::FILES);
97 for (base::FilePath path = enumerator.Next(); !path.empty(); 97 for (base::FilePath path = enumerator.Next(); !path.empty();
98 path = enumerator.Next()) { 98 path = enumerator.Next()) {
99 const std::string encoded_subkey = path.BaseName().MaybeAsASCII(); 99 const std::string encoded_subkey = path.BaseName().MaybeAsASCII();
100 std::string subkey; 100 std::string subkey;
101 std::string data; 101 std::string data;
102 // Only read from |subkey_path| if it is not a symlink and its name is 102 // Only read from |subkey_path| if it is not a symlink and its name is
103 // a base64-encoded string. 103 // a base64-encoded string.
104 if (!base::IsLink(path) && 104 if (!base::IsLink(path) &&
105 base::Base64UrlDecode(encoded_subkey, 105 base::Base64UrlDecode(encoded_subkey,
106 base::Base64UrlDecodePolicy::REQUIRE_PADDING, 106 base::Base64UrlDecodePolicy::REQUIRE_PADDING,
107 &subkey) && 107 &subkey) &&
108 !subkey.empty() && base::ReadFileToString(path, &data)) { 108 !subkey.empty() && base::ReadFileToString(path, &data)) {
109 (*contents)[subkey].swap(data); 109 (*contents)[subkey].swap(data);
110 } 110 }
111 } 111 }
112 } 112 }
113 113
114 void ResourceCache::Delete(const std::string& key, const std::string& subkey) { 114 void ResourceCache::Delete(const std::string& key, const std::string& subkey) {
115 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 115 DCHECK(task_runner_->RunsTasksInCurrentSequence());
116 base::FilePath subkey_path; 116 base::FilePath subkey_path;
117 if (VerifyKeyPathAndGetSubkeyPath(key, false, subkey, &subkey_path)) 117 if (VerifyKeyPathAndGetSubkeyPath(key, false, subkey, &subkey_path))
118 base::DeleteFile(subkey_path, false); 118 base::DeleteFile(subkey_path, false);
119 // Delete() does nothing if the directory given to it is not empty. Hence, the 119 // Delete() does nothing if the directory given to it is not empty. Hence, the
120 // call below deletes the directory representing |key| if its last subkey was 120 // call below deletes the directory representing |key| if its last subkey was
121 // just removed and does nothing otherwise. 121 // just removed and does nothing otherwise.
122 base::DeleteFile(subkey_path.DirName(), false); 122 base::DeleteFile(subkey_path.DirName(), false);
123 } 123 }
124 124
125 void ResourceCache::Clear(const std::string& key) { 125 void ResourceCache::Clear(const std::string& key) {
126 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 126 DCHECK(task_runner_->RunsTasksInCurrentSequence());
127 base::FilePath key_path; 127 base::FilePath key_path;
128 if (VerifyKeyPath(key, false, &key_path)) 128 if (VerifyKeyPath(key, false, &key_path))
129 base::DeleteFile(key_path, true); 129 base::DeleteFile(key_path, true);
130 } 130 }
131 131
132 void ResourceCache::FilterSubkeys(const std::string& key, 132 void ResourceCache::FilterSubkeys(const std::string& key,
133 const SubkeyFilter& test) { 133 const SubkeyFilter& test) {
134 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 134 DCHECK(task_runner_->RunsTasksInCurrentSequence());
135 135
136 base::FilePath key_path; 136 base::FilePath key_path;
137 if (!VerifyKeyPath(key, false, &key_path)) 137 if (!VerifyKeyPath(key, false, &key_path))
138 return; 138 return;
139 139
140 base::FileEnumerator enumerator(key_path, false, base::FileEnumerator::FILES); 140 base::FileEnumerator enumerator(key_path, false, base::FileEnumerator::FILES);
141 for (base::FilePath subkey_path = enumerator.Next(); 141 for (base::FilePath subkey_path = enumerator.Next();
142 !subkey_path.empty(); subkey_path = enumerator.Next()) { 142 !subkey_path.empty(); subkey_path = enumerator.Next()) {
143 std::string subkey; 143 std::string subkey;
144 // Delete files with invalid names, and files whose subkey doesn't pass the 144 // Delete files with invalid names, and files whose subkey doesn't pass the
145 // filter. 145 // filter.
146 if (!base::Base64UrlDecode(subkey_path.BaseName().MaybeAsASCII(), 146 if (!base::Base64UrlDecode(subkey_path.BaseName().MaybeAsASCII(),
147 base::Base64UrlDecodePolicy::REQUIRE_PADDING, 147 base::Base64UrlDecodePolicy::REQUIRE_PADDING,
148 &subkey) || 148 &subkey) ||
149 subkey.empty() || test.Run(subkey)) { 149 subkey.empty() || test.Run(subkey)) {
150 base::DeleteFile(subkey_path, true); 150 base::DeleteFile(subkey_path, true);
151 } 151 }
152 } 152 }
153 153
154 // Delete() does nothing if the directory given to it is not empty. Hence, the 154 // Delete() does nothing if the directory given to it is not empty. Hence, the
155 // call below deletes the directory representing |key| if all of its subkeys 155 // call below deletes the directory representing |key| if all of its subkeys
156 // were just removed and does nothing otherwise. 156 // were just removed and does nothing otherwise.
157 base::DeleteFile(key_path, false); 157 base::DeleteFile(key_path, false);
158 } 158 }
159 159
160 void ResourceCache::PurgeOtherKeys(const std::set<std::string>& keys_to_keep) { 160 void ResourceCache::PurgeOtherKeys(const std::set<std::string>& keys_to_keep) {
161 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 161 DCHECK(task_runner_->RunsTasksInCurrentSequence());
162 std::set<std::string> encoded_keys_to_keep; 162 std::set<std::string> encoded_keys_to_keep;
163 if (!Base64UrlEncode(keys_to_keep, &encoded_keys_to_keep)) 163 if (!Base64UrlEncode(keys_to_keep, &encoded_keys_to_keep))
164 return; 164 return;
165 165
166 base::FileEnumerator enumerator( 166 base::FileEnumerator enumerator(
167 cache_dir_, false, base::FileEnumerator::DIRECTORIES); 167 cache_dir_, false, base::FileEnumerator::DIRECTORIES);
168 for (base::FilePath path = enumerator.Next(); !path.empty(); 168 for (base::FilePath path = enumerator.Next(); !path.empty();
169 path = enumerator.Next()) { 169 path = enumerator.Next()) {
170 const std::string name(path.BaseName().MaybeAsASCII()); 170 const std::string name(path.BaseName().MaybeAsASCII());
171 if (encoded_keys_to_keep.find(name) == encoded_keys_to_keep.end()) 171 if (encoded_keys_to_keep.find(name) == encoded_keys_to_keep.end())
172 base::DeleteFile(path, true); 172 base::DeleteFile(path, true);
173 } 173 }
174 } 174 }
175 175
176 void ResourceCache::PurgeOtherSubkeys( 176 void ResourceCache::PurgeOtherSubkeys(
177 const std::string& key, 177 const std::string& key,
178 const std::set<std::string>& subkeys_to_keep) { 178 const std::set<std::string>& subkeys_to_keep) {
179 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 179 DCHECK(task_runner_->RunsTasksInCurrentSequence());
180 base::FilePath key_path; 180 base::FilePath key_path;
181 if (!VerifyKeyPath(key, false, &key_path)) 181 if (!VerifyKeyPath(key, false, &key_path))
182 return; 182 return;
183 183
184 std::set<std::string> encoded_subkeys_to_keep; 184 std::set<std::string> encoded_subkeys_to_keep;
185 if (!Base64UrlEncode(subkeys_to_keep, &encoded_subkeys_to_keep)) 185 if (!Base64UrlEncode(subkeys_to_keep, &encoded_subkeys_to_keep))
186 return; 186 return;
187 187
188 base::FileEnumerator enumerator(key_path, false, base::FileEnumerator::FILES); 188 base::FileEnumerator enumerator(key_path, false, base::FileEnumerator::FILES);
189 for (base::FilePath path = enumerator.Next(); !path.empty(); 189 for (base::FilePath path = enumerator.Next(); !path.empty();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 std::string encoded; 231 std::string encoded;
232 base::Base64UrlEncode(subkey, base::Base64UrlEncodePolicy::INCLUDE_PADDING, 232 base::Base64UrlEncode(subkey, base::Base64UrlEncodePolicy::INCLUDE_PADDING,
233 &encoded); 233 &encoded);
234 234
235 *path = key_path.AppendASCII(encoded); 235 *path = key_path.AppendASCII(encoded);
236 return true; 236 return true;
237 } 237 }
238 238
239 239
240 } // namespace policy 240 } // namespace policy
OLDNEW
« no previous file with comments | « components/policy/core/common/cloud/policy_header_io_helper.cc ('k') | components/policy/core/common/policy_loader_ios.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698