Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <set> | 5 #include <set> |
| 6 #include <string> | 6 #include <string> |
| 7 | 7 |
| 8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
| 9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
| 10 #include "base/platform_file.h" | 10 #include "base/platform_file.h" |
| 11 #include "content/browser/child_process_security_policy_impl.h" | 11 #include "content/browser/child_process_security_policy_impl.h" |
| 12 #include "content/public/common/url_constants.h" | 12 #include "content/public/common/url_constants.h" |
| 13 #include "content/test/test_content_browser_client.h" | 13 #include "content/test/test_content_browser_client.h" |
| 14 #include "googleurl/src/gurl.h" | 14 #include "googleurl/src/gurl.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 16 |
| 17 namespace content { | 17 namespace content { |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 const int kRendererID = 42; | 20 const int kRendererID = 42; |
| 21 const int kWorkerRendererID = kRendererID + 1; | 21 const int kWorkerRendererID = kRendererID + 1; |
| 22 | 22 |
| 23 #if defined(FILE_PATH_USES_DRIVE_LETTERS) | |
| 24 #define TEST_PATH(x) FILE_PATH_LITERAL("c:") FILE_PATH_LITERAL(x) | |
| 25 #else | |
| 26 #define TEST_PATH(x) FILE_PATH_LITERAL(x) | |
| 27 #endif | |
| 28 | |
| 23 class ChildProcessSecurityPolicyTestBrowserClient | 29 class ChildProcessSecurityPolicyTestBrowserClient |
| 24 : public TestContentBrowserClient { | 30 : public TestContentBrowserClient { |
| 25 public: | 31 public: |
| 26 ChildProcessSecurityPolicyTestBrowserClient() {} | 32 ChildProcessSecurityPolicyTestBrowserClient() {} |
| 27 | 33 |
| 28 virtual bool IsHandledURL(const GURL& url) { | 34 virtual bool IsHandledURL(const GURL& url) { |
| 29 return schemes_.find(url.scheme()) != schemes_.end(); | 35 return schemes_.find(url.scheme()) != schemes_.end(); |
| 30 } | 36 } |
| 31 | 37 |
| 32 void ClearSchemes() { | 38 void ClearSchemes() { |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 287 | 293 |
| 288 p->Remove(kRendererID); | 294 p->Remove(kRendererID); |
| 289 } | 295 } |
| 290 | 296 |
| 291 TEST_F(ChildProcessSecurityPolicyTest, CanReadFiles) { | 297 TEST_F(ChildProcessSecurityPolicyTest, CanReadFiles) { |
| 292 ChildProcessSecurityPolicyImpl* p = | 298 ChildProcessSecurityPolicyImpl* p = |
| 293 ChildProcessSecurityPolicyImpl::GetInstance(); | 299 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 294 | 300 |
| 295 p->Add(kRendererID); | 301 p->Add(kRendererID); |
| 296 | 302 |
| 297 EXPECT_FALSE(p->CanReadFile(kRendererID, | 303 EXPECT_FALSE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/passwd")))); |
| 298 FilePath(FILE_PATH_LITERAL("/etc/passwd")))); | 304 p->GrantReadFile(kRendererID, FilePath(TEST_PATH("/etc/passwd"))); |
| 299 p->GrantReadFile(kRendererID, FilePath(FILE_PATH_LITERAL("/etc/passwd"))); | 305 EXPECT_TRUE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/passwd")))); |
| 300 EXPECT_TRUE(p->CanReadFile(kRendererID, | 306 EXPECT_FALSE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/shadow")))); |
| 301 FilePath(FILE_PATH_LITERAL("/etc/passwd")))); | |
| 302 EXPECT_FALSE(p->CanReadFile(kRendererID, | |
| 303 FilePath(FILE_PATH_LITERAL("/etc/shadow")))); | |
| 304 | 307 |
| 305 p->Remove(kRendererID); | 308 p->Remove(kRendererID); |
| 306 p->Add(kRendererID); | 309 p->Add(kRendererID); |
| 307 | 310 |
| 308 EXPECT_FALSE(p->CanReadFile(kRendererID, | 311 EXPECT_FALSE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/passwd")))); |
| 309 FilePath(FILE_PATH_LITERAL("/etc/passwd")))); | 312 EXPECT_FALSE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/shadow")))); |
| 310 EXPECT_FALSE(p->CanReadFile(kRendererID, | |
| 311 FilePath(FILE_PATH_LITERAL("/etc/shadow")))); | |
| 312 | 313 |
| 313 p->Remove(kRendererID); | 314 p->Remove(kRendererID); |
| 314 } | 315 } |
| 315 | 316 |
| 316 TEST_F(ChildProcessSecurityPolicyTest, CanReadDirectories) { | 317 TEST_F(ChildProcessSecurityPolicyTest, CanReadDirectories) { |
| 317 ChildProcessSecurityPolicyImpl* p = | 318 ChildProcessSecurityPolicyImpl* p = |
| 318 ChildProcessSecurityPolicyImpl::GetInstance(); | 319 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 319 | 320 |
| 320 p->Add(kRendererID); | 321 p->Add(kRendererID); |
| 321 | 322 |
| 322 EXPECT_FALSE(p->CanReadDirectory(kRendererID, | 323 EXPECT_FALSE(p->CanReadDirectory(kRendererID, FilePath(TEST_PATH("/etc/")))); |
| 323 FilePath(FILE_PATH_LITERAL("/etc/")))); | 324 p->GrantReadDirectory(kRendererID, FilePath(TEST_PATH("/etc/"))); |
| 324 p->GrantReadDirectory(kRendererID, FilePath(FILE_PATH_LITERAL("/etc/"))); | 325 EXPECT_TRUE(p->CanReadDirectory(kRendererID, FilePath(TEST_PATH("/etc/")))); |
| 325 EXPECT_TRUE(p->CanReadDirectory(kRendererID, | 326 EXPECT_TRUE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/passwd")))); |
| 326 FilePath(FILE_PATH_LITERAL("/etc/")))); | |
| 327 EXPECT_TRUE(p->CanReadFile(kRendererID, | |
| 328 FilePath(FILE_PATH_LITERAL("/etc/passwd")))); | |
| 329 | 327 |
| 330 p->Remove(kRendererID); | 328 p->Remove(kRendererID); |
| 331 p->Add(kRendererID); | 329 p->Add(kRendererID); |
| 332 | 330 |
| 333 EXPECT_FALSE(p->CanReadDirectory(kRendererID, | 331 EXPECT_FALSE(p->CanReadDirectory(kRendererID, FilePath(TEST_PATH("/etc/")))); |
| 334 FilePath(FILE_PATH_LITERAL("/etc/")))); | 332 EXPECT_FALSE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/passwd")))); |
| 335 EXPECT_FALSE(p->CanReadFile(kRendererID, | |
| 336 FilePath(FILE_PATH_LITERAL("/etc/passwd")))); | |
| 337 | 333 |
| 338 // Just granting read permission as a file doesn't imply reading as a | 334 // Just granting read permission as a file doesn't imply reading as a |
| 339 // directory. | 335 // directory. |
| 340 p->GrantReadFile(kRendererID, FilePath(FILE_PATH_LITERAL("/etc/"))); | 336 p->GrantReadFile(kRendererID, FilePath(TEST_PATH("/etc/"))); |
| 341 EXPECT_TRUE(p->CanReadFile(kRendererID, | 337 EXPECT_TRUE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/passwd")))); |
| 342 FilePath(FILE_PATH_LITERAL("/etc/passwd")))); | 338 EXPECT_FALSE(p->CanReadDirectory(kRendererID, FilePath(TEST_PATH("/etc/")))); |
| 343 EXPECT_FALSE(p->CanReadDirectory(kRendererID, | |
| 344 FilePath(FILE_PATH_LITERAL("/etc/")))); | |
| 345 | 339 |
| 346 p->Remove(kRendererID); | 340 p->Remove(kRendererID); |
| 347 } | 341 } |
| 348 | 342 |
| 349 TEST_F(ChildProcessSecurityPolicyTest, FilePermissions) { | 343 TEST_F(ChildProcessSecurityPolicyTest, FilePermissions) { |
| 350 FilePath granted_file = FilePath(FILE_PATH_LITERAL("/home/joe")); | 344 FilePath granted_file = FilePath(TEST_PATH("/home/joe")); |
| 351 FilePath sibling_file = FilePath(FILE_PATH_LITERAL("/home/bob")); | 345 FilePath sibling_file = FilePath(TEST_PATH("/home/bob")); |
| 352 FilePath child_file = FilePath(FILE_PATH_LITERAL("/home/joe/file")); | 346 FilePath child_file = FilePath(TEST_PATH("/home/joe/file")); |
| 353 FilePath parent_file = FilePath(FILE_PATH_LITERAL("/home")); | 347 FilePath parent_file = FilePath(TEST_PATH("/home")); |
| 354 FilePath parent_slash_file = FilePath(FILE_PATH_LITERAL("/home/")); | 348 FilePath parent_slash_file = FilePath(TEST_PATH("/home/")); |
| 355 FilePath child_traversal1 = FilePath( | 349 FilePath child_traversal1 = FilePath(TEST_PATH("/home/joe/././file")); |
| 356 FILE_PATH_LITERAL("/home/joe/././file")); | |
| 357 FilePath child_traversal2 = FilePath( | 350 FilePath child_traversal2 = FilePath( |
| 358 FILE_PATH_LITERAL("/home/joe/file/../otherfile")); | 351 TEST_PATH("/home/joe/file/../otherfile")); |
| 359 FilePath evil_traversal1 = FilePath( | 352 FilePath evil_traversal1 = FilePath(TEST_PATH("/home/joe/../../etc/passwd")); |
| 360 FILE_PATH_LITERAL("/home/joe/../../etc/passwd")); | |
| 361 FilePath evil_traversal2 = FilePath( | 353 FilePath evil_traversal2 = FilePath( |
| 362 FILE_PATH_LITERAL("/home/joe/./.././../etc/passwd")); | 354 TEST_PATH("/home/joe/./.././../etc/passwd")); |
| 363 FilePath self_traversal = FilePath( | 355 FilePath self_traversal = FilePath(TEST_PATH("/home/joe/../joe/file")); |
| 364 FILE_PATH_LITERAL("/home/joe/../joe/file")); | 356 FilePath relative_file = FilePath(TEST_PATH("home/joe")); |
|
Charlie Reis
2013/01/04 20:59:34
Isn't this going to result in c:home/joe? I suppo
| |
| 365 | 357 |
| 366 ChildProcessSecurityPolicyImpl* p = | 358 ChildProcessSecurityPolicyImpl* p = |
| 367 ChildProcessSecurityPolicyImpl::GetInstance(); | 359 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 368 | 360 |
| 369 // Grant permissions for a file. | 361 // Grant permissions for a file. |
| 370 p->Add(kRendererID); | 362 p->Add(kRendererID); |
| 371 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, | 363 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, |
| 372 base::PLATFORM_FILE_OPEN)); | 364 base::PLATFORM_FILE_OPEN)); |
| 373 | 365 |
| 374 p->GrantPermissionsForFile(kRendererID, granted_file, | 366 p->GrantPermissionsForFile(kRendererID, granted_file, |
| 375 base::PLATFORM_FILE_OPEN | | 367 base::PLATFORM_FILE_OPEN | |
| 376 base::PLATFORM_FILE_OPEN_TRUNCATED | | 368 base::PLATFORM_FILE_OPEN_TRUNCATED | |
| 377 base::PLATFORM_FILE_READ | | 369 base::PLATFORM_FILE_READ | |
| 378 base::PLATFORM_FILE_WRITE); | 370 base::PLATFORM_FILE_WRITE); |
| 379 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, | 371 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, |
| 380 base::PLATFORM_FILE_OPEN | | 372 base::PLATFORM_FILE_OPEN | |
| 381 base::PLATFORM_FILE_OPEN_TRUNCATED | | 373 base::PLATFORM_FILE_OPEN_TRUNCATED | |
| 382 base::PLATFORM_FILE_READ | | 374 base::PLATFORM_FILE_READ | |
| 383 base::PLATFORM_FILE_WRITE)); | 375 base::PLATFORM_FILE_WRITE)); |
| 384 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, | 376 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, |
| 385 base::PLATFORM_FILE_OPEN | | 377 base::PLATFORM_FILE_OPEN | |
| 386 base::PLATFORM_FILE_READ)); | 378 base::PLATFORM_FILE_READ)); |
| 387 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, | 379 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, |
| 388 base::PLATFORM_FILE_CREATE)); | 380 base::PLATFORM_FILE_CREATE)); |
| 381 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 0)); | |
| 389 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, | 382 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, |
| 390 base::PLATFORM_FILE_CREATE | | 383 base::PLATFORM_FILE_CREATE | |
| 391 base::PLATFORM_FILE_OPEN_TRUNCATED | | 384 base::PLATFORM_FILE_OPEN_TRUNCATED | |
| 392 base::PLATFORM_FILE_READ | | 385 base::PLATFORM_FILE_READ | |
| 393 base::PLATFORM_FILE_WRITE)); | 386 base::PLATFORM_FILE_WRITE)); |
| 394 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, sibling_file, | 387 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, sibling_file, |
| 395 base::PLATFORM_FILE_OPEN | | 388 base::PLATFORM_FILE_OPEN | |
| 396 base::PLATFORM_FILE_READ)); | 389 base::PLATFORM_FILE_READ)); |
| 397 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, parent_file, | 390 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, parent_file, |
| 398 base::PLATFORM_FILE_OPEN | | 391 base::PLATFORM_FILE_OPEN | |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 479 EXPECT_TRUE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, | 472 EXPECT_TRUE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, |
| 480 base::PLATFORM_FILE_OPEN | | 473 base::PLATFORM_FILE_OPEN | |
| 481 base::PLATFORM_FILE_READ)); | 474 base::PLATFORM_FILE_READ)); |
| 482 EXPECT_FALSE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, | 475 EXPECT_FALSE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, |
| 483 base::PLATFORM_FILE_WRITE)); | 476 base::PLATFORM_FILE_WRITE)); |
| 484 p->Remove(kRendererID); | 477 p->Remove(kRendererID); |
| 485 EXPECT_FALSE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, | 478 EXPECT_FALSE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, |
| 486 base::PLATFORM_FILE_OPEN | | 479 base::PLATFORM_FILE_OPEN | |
| 487 base::PLATFORM_FILE_READ)); | 480 base::PLATFORM_FILE_READ)); |
| 488 p->Remove(kWorkerRendererID); | 481 p->Remove(kWorkerRendererID); |
| 482 | |
| 483 p->Add(kRendererID); | |
| 484 p->GrantPermissionsForFile(kRendererID, relative_file, | |
| 485 base::PLATFORM_FILE_OPEN); | |
| 486 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, relative_file, | |
| 487 base::PLATFORM_FILE_OPEN)); | |
| 488 p->Remove(kRendererID); | |
| 489 } | 489 } |
| 490 | 490 |
| 491 TEST_F(ChildProcessSecurityPolicyTest, CanServiceWebUIBindings) { | 491 TEST_F(ChildProcessSecurityPolicyTest, CanServiceWebUIBindings) { |
| 492 ChildProcessSecurityPolicyImpl* p = | 492 ChildProcessSecurityPolicyImpl* p = |
| 493 ChildProcessSecurityPolicyImpl::GetInstance(); | 493 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 494 | 494 |
| 495 GURL url("chrome://thumb/http://www.google.com/"); | 495 GURL url("chrome://thumb/http://www.google.com/"); |
| 496 | 496 |
| 497 p->Add(kRendererID); | 497 p->Add(kRendererID); |
| 498 | 498 |
| 499 EXPECT_FALSE(p->HasWebUIBindings(kRendererID)); | 499 EXPECT_FALSE(p->HasWebUIBindings(kRendererID)); |
| 500 EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); | 500 EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); |
| 501 p->GrantWebUIBindings(kRendererID); | 501 p->GrantWebUIBindings(kRendererID); |
| 502 EXPECT_TRUE(p->HasWebUIBindings(kRendererID)); | 502 EXPECT_TRUE(p->HasWebUIBindings(kRendererID)); |
| 503 EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); | 503 EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); |
| 504 | 504 |
| 505 p->Remove(kRendererID); | 505 p->Remove(kRendererID); |
| 506 } | 506 } |
| 507 | 507 |
| 508 TEST_F(ChildProcessSecurityPolicyTest, RemoveRace) { | 508 TEST_F(ChildProcessSecurityPolicyTest, RemoveRace) { |
| 509 ChildProcessSecurityPolicyImpl* p = | 509 ChildProcessSecurityPolicyImpl* p = |
| 510 ChildProcessSecurityPolicyImpl::GetInstance(); | 510 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 511 | 511 |
| 512 GURL url("file:///etc/passwd"); | 512 GURL url("file:///etc/passwd"); |
| 513 FilePath file(FILE_PATH_LITERAL("/etc/passwd")); | 513 FilePath file(TEST_PATH("/etc/passwd")); |
| 514 | 514 |
| 515 p->Add(kRendererID); | 515 p->Add(kRendererID); |
| 516 | 516 |
| 517 p->GrantRequestURL(kRendererID, url); | 517 p->GrantRequestURL(kRendererID, url); |
| 518 p->GrantReadFile(kRendererID, file); | 518 p->GrantReadFile(kRendererID, file); |
| 519 p->GrantWebUIBindings(kRendererID); | 519 p->GrantWebUIBindings(kRendererID); |
| 520 | 520 |
| 521 EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); | 521 EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); |
| 522 EXPECT_TRUE(p->CanReadFile(kRendererID, file)); | 522 EXPECT_TRUE(p->CanReadFile(kRendererID, file)); |
| 523 EXPECT_TRUE(p->HasWebUIBindings(kRendererID)); | 523 EXPECT_TRUE(p->HasWebUIBindings(kRendererID)); |
| 524 | 524 |
| 525 p->Remove(kRendererID); | 525 p->Remove(kRendererID); |
| 526 | 526 |
| 527 // Renderers are added and removed on the UI thread, but the policy can be | 527 // Renderers are added and removed on the UI thread, but the policy can be |
| 528 // queried on the IO thread. The ChildProcessSecurityPolicy needs to be | 528 // queried on the IO thread. The ChildProcessSecurityPolicy needs to be |
| 529 // prepared to answer policy questions about renderers who no longer exist. | 529 // prepared to answer policy questions about renderers who no longer exist. |
| 530 | 530 |
| 531 // In this case, we default to secure behavior. | 531 // In this case, we default to secure behavior. |
| 532 EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); | 532 EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); |
| 533 EXPECT_FALSE(p->CanReadFile(kRendererID, file)); | 533 EXPECT_FALSE(p->CanReadFile(kRendererID, file)); |
| 534 EXPECT_FALSE(p->HasWebUIBindings(kRendererID)); | 534 EXPECT_FALSE(p->HasWebUIBindings(kRendererID)); |
| 535 } | 535 } |
| 536 | 536 |
| 537 } // namespace content | 537 } // namespace content |
| OLD | NEW |