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: content/common/sandbox_mac.mm

Issue 2919963003: Update sandbox profiles and remove regular expressions. (Closed)
Patch Set: Remove string quoting Created 3 years, 6 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
« no previous file with comments | « content/common/sandbox_mac.h ('k') | content/common/sandbox_mac_diraccess_unittest.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/common/sandbox_mac.h" 5 #include "content/common/sandbox_mac.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 { SANDBOX_TYPE_RENDERER, IDR_RENDERER_SANDBOX_PROFILE }, 64 { SANDBOX_TYPE_RENDERER, IDR_RENDERER_SANDBOX_PROFILE },
65 { SANDBOX_TYPE_UTILITY, IDR_UTILITY_SANDBOX_PROFILE }, 65 { SANDBOX_TYPE_UTILITY, IDR_UTILITY_SANDBOX_PROFILE },
66 { SANDBOX_TYPE_GPU, IDR_GPU_SANDBOX_PROFILE }, 66 { SANDBOX_TYPE_GPU, IDR_GPU_SANDBOX_PROFILE },
67 { SANDBOX_TYPE_PPAPI, IDR_PPAPI_SANDBOX_PROFILE }, 67 { SANDBOX_TYPE_PPAPI, IDR_PPAPI_SANDBOX_PROFILE },
68 }; 68 };
69 69
70 static_assert(arraysize(kDefaultSandboxTypeToResourceIDMapping) == \ 70 static_assert(arraysize(kDefaultSandboxTypeToResourceIDMapping) == \
71 size_t(SANDBOX_TYPE_AFTER_LAST_TYPE), \ 71 size_t(SANDBOX_TYPE_AFTER_LAST_TYPE), \
72 "sandbox type to resource id mapping incorrect"); 72 "sandbox type to resource id mapping incorrect");
73 73
74 // Try to escape |c| as a "SingleEscapeCharacter" (\n, etc). If successful,
75 // returns true and appends the escape sequence to |dst|.
76 bool EscapeSingleChar(char c, std::string* dst) {
77 const char *append = NULL;
78 switch (c) {
79 case '\b':
80 append = "\\b";
81 break;
82 case '\f':
83 append = "\\f";
84 break;
85 case '\n':
86 append = "\\n";
87 break;
88 case '\r':
89 append = "\\r";
90 break;
91 case '\t':
92 append = "\\t";
93 break;
94 case '\\':
95 append = "\\\\";
96 break;
97 case '"':
98 append = "\\\"";
99 break;
100 }
101
102 if (!append) {
103 return false;
104 }
105
106 dst->append(append);
107 return true;
108 }
109
110 // Errors quoting strings for the Sandbox profile are always fatal, report them
111 // in a central place.
112 NOINLINE void FatalStringQuoteException(const std::string& str) {
113 // Copy bad string to the stack so it's recorded in the crash dump.
114 char bad_string[256] = {0};
115 base::strlcpy(bad_string, str.c_str(), arraysize(bad_string));
116 DLOG(FATAL) << "String quoting failed " << bad_string;
117 }
118
119 } // namespace 74 } // namespace
120 75
121 // static
122 bool Sandbox::QuotePlainString(const std::string& src_utf8, std::string* dst) {
123 dst->clear();
124
125 const char* src = src_utf8.c_str();
126 int32_t length = src_utf8.length();
127 int32_t position = 0;
128 while (position < length) {
129 UChar32 c;
130 U8_NEXT(src, position, length, c); // Macro increments |position|.
131 DCHECK_GE(c, 0);
132 if (c < 0)
133 return false;
134
135 if (c < 128) { // EscapeSingleChar only handles ASCII.
136 char as_char = static_cast<char>(c);
137 if (EscapeSingleChar(as_char, dst)) {
138 continue;
139 }
140 }
141
142 if (c < 32 || c > 126) {
143 // Any characters that aren't printable ASCII get the \u treatment.
144 unsigned int as_uint = static_cast<unsigned int>(c);
145 base::StringAppendF(dst, "\\u%04X", as_uint);
146 continue;
147 }
148
149 // If we got here we know that the character in question is strictly
150 // in the ASCII range so there's no need to do any kind of encoding
151 // conversion.
152 dst->push_back(static_cast<char>(c));
153 }
154 return true;
155 }
156
157 // static
158 bool Sandbox::QuoteStringForRegex(const std::string& str_utf8,
159 std::string* dst) {
160 // Characters with special meanings in sandbox profile syntax.
161 const char regex_special_chars[] = {
162 '\\',
163
164 // Metacharacters
165 '^',
166 '.',
167 '[',
168 ']',
169 '$',
170 '(',
171 ')',
172 '|',
173
174 // Quantifiers
175 '*',
176 '+',
177 '?',
178 '{',
179 '}',
180 };
181
182 // Anchor regex at start of path.
183 dst->assign("^");
184
185 const char* src = str_utf8.c_str();
186 int32_t length = str_utf8.length();
187 int32_t position = 0;
188 while (position < length) {
189 UChar32 c;
190 U8_NEXT(src, position, length, c); // Macro increments |position|.
191 DCHECK_GE(c, 0);
192 if (c < 0)
193 return false;
194
195 // The Mac sandbox regex parser only handles printable ASCII characters.
196 // 33 >= c <= 126
197 if (c < 32 || c > 125) {
198 return false;
199 }
200
201 for (size_t i = 0; i < arraysize(regex_special_chars); ++i) {
202 if (c == regex_special_chars[i]) {
203 dst->push_back('\\');
204 break;
205 }
206 }
207
208 dst->push_back(static_cast<char>(c));
209 }
210
211 // Make sure last element of path is interpreted as a directory. Leaving this
212 // off would allow access to files if they start with the same name as the
213 // directory.
214 dst->append("(/|$)");
215
216 return true;
217 }
218
219 // Warm up System APIs that empirically need to be accessed before the Sandbox 76 // Warm up System APIs that empirically need to be accessed before the Sandbox
220 // is turned on. 77 // is turned on.
221 // This method is layed out in blocks, each one containing a separate function 78 // This method is layed out in blocks, each one containing a separate function
222 // that needs to be warmed up. The OS version on which we found the need to 79 // that needs to be warmed up. The OS version on which we found the need to
223 // enable the function is also noted. 80 // enable the function is also noted.
224 // This function is tested on the following OS versions: 81 // This function is tested on the following OS versions:
225 // 10.5.6, 10.6.0 82 // 10.5.6, 10.6.0
226 83
227 // static 84 // static
228 void Sandbox::SandboxWarmup(int sandbox_type) { 85 void Sandbox::SandboxWarmup(int sandbox_type) {
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 std::string sandbox_data = LoadSandboxTemplate(sandbox_type); 243 std::string sandbox_data = LoadSandboxTemplate(sandbox_type);
387 if (sandbox_data.empty()) { 244 if (sandbox_data.empty()) {
388 return false; 245 return false;
389 } 246 }
390 247
391 sandbox::SandboxCompiler compiler(sandbox_data); 248 sandbox::SandboxCompiler compiler(sandbox_data);
392 249
393 if (!allowed_dir.empty()) { 250 if (!allowed_dir.empty()) {
394 // Add the sandbox parameters necessary to access the given directory. 251 // Add the sandbox parameters necessary to access the given directory.
395 base::FilePath allowed_dir_canonical = GetCanonicalSandboxPath(allowed_dir); 252 base::FilePath allowed_dir_canonical = GetCanonicalSandboxPath(allowed_dir);
396 std::string regex; 253 if (!compiler.InsertStringParam("PERMITTED_DIR",
397 if (!QuoteStringForRegex(allowed_dir_canonical.value(), &regex)) { 254 allowed_dir_canonical.value()))
398 FatalStringQuoteException(allowed_dir_canonical.value());
399 return false;
400 }
401 if (!compiler.InsertStringParam("PERMITTED_DIR", regex))
402 return false; 255 return false;
403 } 256 }
404 257
405 // Enable verbose logging if enabled on the command line. (See common.sb 258 // Enable verbose logging if enabled on the command line. (See common.sb
406 // for details). 259 // for details).
407 const base::CommandLine* command_line = 260 const base::CommandLine* command_line =
408 base::CommandLine::ForCurrentProcess(); 261 base::CommandLine::ForCurrentProcess();
409 bool enable_logging = 262 bool enable_logging =
410 command_line->HasSwitch(switches::kEnableSandboxLogging);; 263 command_line->HasSwitch(switches::kEnableSandboxLogging);;
411 if (!compiler.InsertBooleanParam("ENABLE_LOGGING", enable_logging)) 264 if (!compiler.InsertBooleanParam("ENABLE_LOGGING", enable_logging))
412 return false; 265 return false;
413 266
414 // Without this, the sandbox will print a message to the system log every 267 // Without this, the sandbox will print a message to the system log every
415 // time it denies a request. This floods the console with useless spew. 268 // time it denies a request. This floods the console with useless spew.
416 if (!compiler.InsertBooleanParam("DISABLE_SANDBOX_DENIAL_LOGGING", 269 if (!compiler.InsertBooleanParam("DISABLE_SANDBOX_DENIAL_LOGGING",
417 !enable_logging)) 270 !enable_logging))
418 return false; 271 return false;
419 272
420 // Splice the path of the user's home directory into the sandbox profile 273 // Splice the path of the user's home directory into the sandbox profile
421 // (see renderer.sb for details). 274 // (see renderer.sb for details).
422 std::string home_dir = [NSHomeDirectory() fileSystemRepresentation]; 275 std::string home_dir = [NSHomeDirectory() fileSystemRepresentation];
423 276
424 base::FilePath home_dir_canonical = 277 base::FilePath home_dir_canonical =
425 GetCanonicalSandboxPath(base::FilePath(home_dir)); 278 GetCanonicalSandboxPath(base::FilePath(home_dir));
426 279
427 std::string quoted_home_dir; 280 if (!compiler.InsertStringParam("USER_HOMEDIR_AS_LITERAL",
428 if (!QuotePlainString(home_dir_canonical.value(), &quoted_home_dir)) { 281 home_dir_canonical.value()))
429 FatalStringQuoteException(home_dir_canonical.value());
430 return false;
431 }
432
433 if (!compiler.InsertStringParam("USER_HOMEDIR_AS_LITERAL", quoted_home_dir))
434 return false; 282 return false;
435 283
436 bool elcap_or_later = base::mac::IsAtLeastOS10_11(); 284 bool elcap_or_later = base::mac::IsAtLeastOS10_11();
437 if (!compiler.InsertBooleanParam("ELCAP_OR_LATER", elcap_or_later)) 285 if (!compiler.InsertBooleanParam("ELCAP_OR_LATER", elcap_or_later))
438 return false; 286 return false;
439 287
440 // Initialize sandbox. 288 // Initialize sandbox.
441 std::string error_str; 289 std::string error_str;
442 bool success = compiler.CompileAndApplyProfile(&error_str); 290 bool success = compiler.CompileAndApplyProfile(&error_str);
443 DLOG_IF(FATAL, !success) << "Failed to initialize sandbox: " << error_str; 291 DLOG_IF(FATAL, !success) << "Failed to initialize sandbox: " << error_str;
(...skipping 19 matching lines...) Expand all
463 if (HANDLE_EINTR(fcntl(fd.get(), F_GETPATH, canonical_path)) != 0) { 311 if (HANDLE_EINTR(fcntl(fd.get(), F_GETPATH, canonical_path)) != 0) {
464 DPLOG(FATAL) << "GetCanonicalSandboxPath() failed for: " 312 DPLOG(FATAL) << "GetCanonicalSandboxPath() failed for: "
465 << path.value(); 313 << path.value();
466 return path; 314 return path;
467 } 315 }
468 316
469 return base::FilePath(canonical_path); 317 return base::FilePath(canonical_path);
470 } 318 }
471 319
472 } // namespace content 320 } // namespace content
OLDNEW
« no previous file with comments | « content/common/sandbox_mac.h ('k') | content/common/sandbox_mac_diraccess_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698