Home | History | Annotate | Download | only in browser
      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
      3 // found in the LICENSE file.
      4 
      5 #include <set>
      6 #include <string>
      7 
      8 #include "base/basictypes.h"
      9 #include "base/files/file_path.h"
     10 #include "base/platform_file.h"
     11 #include "content/browser/child_process_security_policy_impl.h"
     12 #include "content/public/common/url_constants.h"
     13 #include "content/test/test_content_browser_client.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 #include "url/gurl.h"
     16 #include "webkit/browser/fileapi/file_permission_policy.h"
     17 #include "webkit/browser/fileapi/file_system_url.h"
     18 #include "webkit/browser/fileapi/isolated_context.h"
     19 #include "webkit/common/fileapi/file_system_types.h"
     20 
     21 namespace content {
     22 namespace {
     23 
     24 const int kRendererID = 42;
     25 const int kWorkerRendererID = kRendererID + 1;
     26 
     27 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
     28 #define TEST_PATH(x) FILE_PATH_LITERAL("c:") FILE_PATH_LITERAL(x)
     29 #else
     30 #define TEST_PATH(x) FILE_PATH_LITERAL(x)
     31 #endif
     32 
     33 class ChildProcessSecurityPolicyTestBrowserClient
     34     : public TestContentBrowserClient {
     35  public:
     36   ChildProcessSecurityPolicyTestBrowserClient() {}
     37 
     38   virtual bool IsHandledURL(const GURL& url) OVERRIDE {
     39     return schemes_.find(url.scheme()) != schemes_.end();
     40   }
     41 
     42   void ClearSchemes() {
     43     schemes_.clear();
     44   }
     45 
     46   void AddScheme(const std::string& scheme) {
     47     schemes_.insert(scheme);
     48   }
     49 
     50  private:
     51   std::set<std::string> schemes_;
     52 };
     53 
     54 }  // namespace
     55 
     56 class ChildProcessSecurityPolicyTest : public testing::Test {
     57  public:
     58   ChildProcessSecurityPolicyTest() : old_browser_client_(NULL) {
     59   }
     60 
     61   virtual void SetUp() {
     62     old_browser_client_ = SetBrowserClientForTesting(&test_browser_client_);
     63 
     64     // Claim to always handle chrome:// URLs because the CPSP's notion of
     65     // allowing WebUI bindings is hard-wired to this particular scheme.
     66     test_browser_client_.AddScheme(chrome::kChromeUIScheme);
     67 
     68     // Claim to always handle file:// URLs like the browser would.
     69     // net::URLRequest::IsHandledURL() no longer claims support for default
     70     // protocols as this is the responsibility of the browser (which is
     71     // responsible for adding the appropriate ProtocolHandler).
     72     test_browser_client_.AddScheme(chrome::kFileScheme);
     73   }
     74 
     75   virtual void TearDown() {
     76     test_browser_client_.ClearSchemes();
     77     SetBrowserClientForTesting(old_browser_client_);
     78   }
     79 
     80  protected:
     81   void RegisterTestScheme(const std::string& scheme) {
     82     test_browser_client_.AddScheme(scheme);
     83   }
     84 
     85   void GrantPermissionsForFile(ChildProcessSecurityPolicyImpl* p,
     86                                int child_id,
     87                                const base::FilePath& file,
     88                                int permissions) {
     89     p->GrantPermissionsForFile(child_id, file, permissions);
     90   }
     91 
     92  private:
     93   ChildProcessSecurityPolicyTestBrowserClient test_browser_client_;
     94   ContentBrowserClient* old_browser_client_;
     95 };
     96 
     97 
     98 TEST_F(ChildProcessSecurityPolicyTest, IsWebSafeSchemeTest) {
     99   ChildProcessSecurityPolicyImpl* p =
    100       ChildProcessSecurityPolicyImpl::GetInstance();
    101 
    102   EXPECT_TRUE(p->IsWebSafeScheme(chrome::kHttpScheme));
    103   EXPECT_TRUE(p->IsWebSafeScheme(chrome::kHttpsScheme));
    104   EXPECT_TRUE(p->IsWebSafeScheme(chrome::kFtpScheme));
    105   EXPECT_TRUE(p->IsWebSafeScheme(chrome::kDataScheme));
    106   EXPECT_TRUE(p->IsWebSafeScheme("feed"));
    107   EXPECT_TRUE(p->IsWebSafeScheme(chrome::kBlobScheme));
    108   EXPECT_TRUE(p->IsWebSafeScheme(chrome::kFileSystemScheme));
    109 
    110   EXPECT_FALSE(p->IsWebSafeScheme("registered-web-safe-scheme"));
    111   p->RegisterWebSafeScheme("registered-web-safe-scheme");
    112   EXPECT_TRUE(p->IsWebSafeScheme("registered-web-safe-scheme"));
    113 
    114   EXPECT_FALSE(p->IsWebSafeScheme(chrome::kChromeUIScheme));
    115 }
    116 
    117 TEST_F(ChildProcessSecurityPolicyTest, IsPseudoSchemeTest) {
    118   ChildProcessSecurityPolicyImpl* p =
    119       ChildProcessSecurityPolicyImpl::GetInstance();
    120 
    121   EXPECT_TRUE(p->IsPseudoScheme(chrome::kAboutScheme));
    122   EXPECT_TRUE(p->IsPseudoScheme(chrome::kJavaScriptScheme));
    123   EXPECT_TRUE(p->IsPseudoScheme(kViewSourceScheme));
    124 
    125   EXPECT_FALSE(p->IsPseudoScheme("registered-pseudo-scheme"));
    126   p->RegisterPseudoScheme("registered-pseudo-scheme");
    127   EXPECT_TRUE(p->IsPseudoScheme("registered-pseudo-scheme"));
    128 
    129   EXPECT_FALSE(p->IsPseudoScheme(chrome::kChromeUIScheme));
    130 }
    131 
    132 TEST_F(ChildProcessSecurityPolicyTest, StandardSchemesTest) {
    133   ChildProcessSecurityPolicyImpl* p =
    134       ChildProcessSecurityPolicyImpl::GetInstance();
    135 
    136   p->Add(kRendererID);
    137 
    138   // Safe
    139   EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("http://www.google.com/")));
    140   EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("https://www.paypal.com/")));
    141   EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("ftp://ftp.gnu.org/")));
    142   EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("data:text/html,<b>Hi</b>")));
    143   EXPECT_TRUE(p->CanRequestURL(kRendererID,
    144                                GURL("view-source:http://www.google.com/")));
    145   EXPECT_TRUE(p->CanRequestURL(
    146       kRendererID, GURL("filesystem:http://localhost/temporary/a.gif")));
    147 
    148   // Dangerous
    149   EXPECT_FALSE(p->CanRequestURL(kRendererID,
    150                                 GURL("file:///etc/passwd")));
    151   EXPECT_FALSE(p->CanRequestURL(kRendererID,
    152                                 GURL("chrome://foo/bar")));
    153 
    154   p->Remove(kRendererID);
    155 }
    156 
    157 TEST_F(ChildProcessSecurityPolicyTest, AboutTest) {
    158   ChildProcessSecurityPolicyImpl* p =
    159       ChildProcessSecurityPolicyImpl::GetInstance();
    160 
    161   p->Add(kRendererID);
    162 
    163   EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:blank")));
    164   EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:BlAnK")));
    165   EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("aBouT:BlAnK")));
    166   EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("aBouT:blank")));
    167 
    168   EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:memory")));
    169   EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:crash")));
    170   EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:cache")));
    171   EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:hang")));
    172 
    173   EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("aBoUt:memory")));
    174   EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:CrASh")));
    175   EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("abOuT:cAChe")));
    176 
    177   // Requests for about: pages should be denied.
    178   p->GrantRequestURL(kRendererID, GURL("about:crash"));
    179   EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:crash")));
    180 
    181   // These requests for chrome:// pages should be granted.
    182   GURL chrome_url("chrome://foo");
    183   p->GrantRequestURL(kRendererID, chrome_url);
    184   EXPECT_TRUE(p->CanRequestURL(kRendererID, chrome_url));
    185 
    186   p->Remove(kRendererID);
    187 }
    188 
    189 TEST_F(ChildProcessSecurityPolicyTest, JavaScriptTest) {
    190   ChildProcessSecurityPolicyImpl* p =
    191       ChildProcessSecurityPolicyImpl::GetInstance();
    192 
    193   p->Add(kRendererID);
    194 
    195   EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')")));
    196   p->GrantRequestURL(kRendererID, GURL("javascript:alert('xss')"));
    197   EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')")));
    198 
    199   p->Remove(kRendererID);
    200 }
    201 
    202 TEST_F(ChildProcessSecurityPolicyTest, RegisterWebSafeSchemeTest) {
    203   ChildProcessSecurityPolicyImpl* p =
    204       ChildProcessSecurityPolicyImpl::GetInstance();
    205 
    206   p->Add(kRendererID);
    207 
    208   // Currently, "asdf" is destined for ShellExecute, so it is allowed.
    209   EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers")));
    210 
    211   // Once we register "asdf", we default to deny.
    212   RegisterTestScheme("asdf");
    213   EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("asdf:rockers")));
    214 
    215   // We can allow new schemes by adding them to the whitelist.
    216   p->RegisterWebSafeScheme("asdf");
    217   EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers")));
    218 
    219   // Cleanup.
    220   p->Remove(kRendererID);
    221 }
    222 
    223 TEST_F(ChildProcessSecurityPolicyTest, CanServiceCommandsTest) {
    224   ChildProcessSecurityPolicyImpl* p =
    225       ChildProcessSecurityPolicyImpl::GetInstance();
    226 
    227   p->Add(kRendererID);
    228 
    229   EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
    230   p->GrantRequestURL(kRendererID, GURL("file:///etc/passwd"));
    231   EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
    232 
    233   // We should forget our state if we repeat a renderer id.
    234   p->Remove(kRendererID);
    235   p->Add(kRendererID);
    236   EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
    237   p->Remove(kRendererID);
    238 }
    239 
    240 TEST_F(ChildProcessSecurityPolicyTest, ViewSource) {
    241   ChildProcessSecurityPolicyImpl* p =
    242       ChildProcessSecurityPolicyImpl::GetInstance();
    243 
    244   p->Add(kRendererID);
    245 
    246   // View source is determined by the embedded scheme.
    247   EXPECT_TRUE(p->CanRequestURL(kRendererID,
    248                                GURL("view-source:http://www.google.com/")));
    249   EXPECT_FALSE(p->CanRequestURL(kRendererID,
    250                                 GURL("view-source:file:///etc/passwd")));
    251   EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
    252   EXPECT_FALSE(p->CanRequestURL(
    253       kRendererID, GURL("view-source:view-source:http://www.google.com/")));
    254 
    255   p->GrantRequestURL(kRendererID, GURL("view-source:file:///etc/passwd"));
    256   // View source needs to be able to request the embedded scheme.
    257   EXPECT_TRUE(p->CanRequestURL(kRendererID,
    258                                GURL("view-source:file:///etc/passwd")));
    259   EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
    260 
    261   p->Remove(kRendererID);
    262 }
    263 
    264 TEST_F(ChildProcessSecurityPolicyTest, SpecificFile) {
    265   ChildProcessSecurityPolicyImpl* p =
    266       ChildProcessSecurityPolicyImpl::GetInstance();
    267 
    268   p->Add(kRendererID);
    269 
    270   GURL icon_url("file:///tmp/foo.png");
    271   GURL sensitive_url("file:///etc/passwd");
    272   EXPECT_FALSE(p->CanRequestURL(kRendererID, icon_url));
    273   EXPECT_FALSE(p->CanRequestURL(kRendererID, sensitive_url));
    274 
    275   p->GrantRequestSpecificFileURL(kRendererID, icon_url);
    276   EXPECT_TRUE(p->CanRequestURL(kRendererID, icon_url));
    277   EXPECT_FALSE(p->CanRequestURL(kRendererID, sensitive_url));
    278 
    279   p->GrantRequestURL(kRendererID, icon_url);
    280   EXPECT_TRUE(p->CanRequestURL(kRendererID, icon_url));
    281   EXPECT_TRUE(p->CanRequestURL(kRendererID, sensitive_url));
    282 
    283   p->Remove(kRendererID);
    284 }
    285 
    286 TEST_F(ChildProcessSecurityPolicyTest, FileSystemGrantsTest) {
    287   ChildProcessSecurityPolicyImpl* p =
    288       ChildProcessSecurityPolicyImpl::GetInstance();
    289 
    290   p->Add(kRendererID);
    291   std::string read_id = fileapi::IsolatedContext::GetInstance()->
    292       RegisterFileSystemForVirtualPath(fileapi::kFileSystemTypeTest,
    293                                        "read_filesystem",
    294                                        base::FilePath());
    295   std::string read_write_id = fileapi::IsolatedContext::GetInstance()->
    296       RegisterFileSystemForVirtualPath(fileapi::kFileSystemTypeTest,
    297                                        "read_write_filesystem",
    298                                        base::FilePath());
    299   std::string copy_into_id = fileapi::IsolatedContext::GetInstance()->
    300       RegisterFileSystemForVirtualPath(fileapi::kFileSystemTypeTest,
    301                                        "copy_into_filesystem",
    302                                        base::FilePath());
    303 
    304   // Test initially having no permissions.
    305   EXPECT_FALSE(p->CanReadFileSystem(kRendererID, read_id));
    306   EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_id));
    307   EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_id));
    308 
    309   EXPECT_FALSE(p->CanReadFileSystem(kRendererID, read_write_id));
    310   EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_write_id));
    311   EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_write_id));
    312 
    313   EXPECT_FALSE(p->CanReadFileSystem(kRendererID, copy_into_id));
    314   EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, copy_into_id));
    315   EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, copy_into_id));
    316 
    317   // Testing varying combinations of grants and checks.
    318   p->GrantReadFileSystem(kRendererID, read_id);
    319   EXPECT_TRUE(p->CanReadFileSystem(kRendererID, read_id));
    320   EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_id));
    321   EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_id));
    322 
    323   p->GrantReadFileSystem(kRendererID, read_write_id);
    324   p->GrantWriteFileSystem(kRendererID, read_write_id);
    325   EXPECT_TRUE(p->CanReadFileSystem(kRendererID, read_write_id));
    326   EXPECT_TRUE(p->CanReadWriteFileSystem(kRendererID, read_write_id));
    327   EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_write_id));
    328 
    329   p->GrantCopyIntoFileSystem(kRendererID, copy_into_id);
    330   EXPECT_FALSE(p->CanReadFileSystem(kRendererID, copy_into_id));
    331   EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, copy_into_id));
    332   EXPECT_TRUE(p->CanCopyIntoFileSystem(kRendererID, copy_into_id));
    333 
    334   // Test revoke permissions on renderer ID removal.
    335   p->Remove(kRendererID);
    336   EXPECT_FALSE(p->CanReadFileSystem(kRendererID, read_id));
    337   EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_id));
    338   EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_id));
    339 
    340   EXPECT_FALSE(p->CanReadFileSystem(kRendererID, read_write_id));
    341   EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_write_id));
    342   EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_write_id));
    343 
    344   EXPECT_FALSE(p->CanReadFileSystem(kRendererID, copy_into_id));
    345   EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, copy_into_id));
    346   EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, copy_into_id));
    347 
    348   // Test having no permissions upon re-adding same renderer ID.
    349   p->Add(kRendererID);
    350   EXPECT_FALSE(p->CanReadFileSystem(kRendererID, read_id));
    351   EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_id));
    352   EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_id));
    353 
    354   EXPECT_FALSE(p->CanReadFileSystem(kRendererID, read_write_id));
    355   EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_write_id));
    356   EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_write_id));
    357 
    358   EXPECT_FALSE(p->CanReadFileSystem(kRendererID, copy_into_id));
    359   EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, copy_into_id));
    360   EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, copy_into_id));
    361 
    362   // Cleanup.
    363   p->Remove(kRendererID);
    364   fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(read_id);
    365   fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(read_write_id);
    366   fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(copy_into_id);
    367 }
    368 
    369 TEST_F(ChildProcessSecurityPolicyTest, FilePermissionGrantingAndRevoking) {
    370   ChildProcessSecurityPolicyImpl* p =
    371       ChildProcessSecurityPolicyImpl::GetInstance();
    372 
    373   p->RegisterFileSystemPermissionPolicy(
    374       fileapi::kFileSystemTypeTest,
    375       fileapi::FILE_PERMISSION_USE_FILE_PERMISSION);
    376 
    377   p->Add(kRendererID);
    378   base::FilePath file(TEST_PATH("/dir/testfile"));
    379   file = file.NormalizePathSeparators();
    380   fileapi::FileSystemURL url = fileapi::FileSystemURL::CreateForTest(
    381       GURL("http://foo/"), fileapi::kFileSystemTypeTest, file);
    382 
    383   // Test initially having no permissions.
    384   EXPECT_FALSE(p->CanReadFile(kRendererID, file));
    385   EXPECT_FALSE(p->CanWriteFile(kRendererID, file));
    386   EXPECT_FALSE(p->CanCreateFile(kRendererID, file));
    387   EXPECT_FALSE(p->CanCreateWriteFile(kRendererID, file));
    388   EXPECT_FALSE(p->CanReadFileSystemFile(kRendererID, url));
    389   EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url));
    390   EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url));
    391   EXPECT_FALSE(p->CanCreateWriteFileSystemFile(kRendererID, url));
    392 
    393   // Testing every combination of permissions granting and revoking.
    394   p->GrantReadFile(kRendererID, file);
    395   EXPECT_TRUE(p->CanReadFile(kRendererID, file));
    396   EXPECT_FALSE(p->CanWriteFile(kRendererID, file));
    397   EXPECT_FALSE(p->CanCreateFile(kRendererID, file));
    398   EXPECT_FALSE(p->CanCreateWriteFile(kRendererID, file));
    399   EXPECT_TRUE(p->CanReadFileSystemFile(kRendererID, url));
    400   EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url));
    401   EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url));
    402   EXPECT_FALSE(p->CanCreateWriteFileSystemFile(kRendererID, url));
    403   p->RevokeAllPermissionsForFile(kRendererID, file);
    404   EXPECT_FALSE(p->CanReadFile(kRendererID, file));
    405   EXPECT_FALSE(p->CanWriteFile(kRendererID, file));
    406   EXPECT_FALSE(p->CanCreateFile(kRendererID, file));
    407   EXPECT_FALSE(p->CanCreateWriteFile(kRendererID, file));
    408   EXPECT_FALSE(p->CanReadFileSystemFile(kRendererID, url));
    409   EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url));
    410   EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url));
    411   EXPECT_FALSE(p->CanCreateWriteFileSystemFile(kRendererID, url));
    412 
    413   p->GrantCreateReadWriteFile(kRendererID, file);
    414   EXPECT_TRUE(p->CanReadFile(kRendererID, file));
    415   EXPECT_TRUE(p->CanWriteFile(kRendererID, file));
    416   EXPECT_TRUE(p->CanCreateFile(kRendererID, file));
    417   EXPECT_TRUE(p->CanCreateWriteFile(kRendererID, file));
    418   EXPECT_TRUE(p->CanReadFileSystemFile(kRendererID, url));
    419   EXPECT_TRUE(p->CanWriteFileSystemFile(kRendererID, url));
    420   EXPECT_TRUE(p->CanCreateFileSystemFile(kRendererID, url));
    421   EXPECT_TRUE(p->CanCreateWriteFileSystemFile(kRendererID, url));
    422   p->RevokeAllPermissionsForFile(kRendererID, file);
    423   EXPECT_FALSE(p->CanReadFile(kRendererID, file));
    424   EXPECT_FALSE(p->CanWriteFile(kRendererID, file));
    425   EXPECT_FALSE(p->CanCreateFile(kRendererID, file));
    426   EXPECT_FALSE(p->CanCreateWriteFile(kRendererID, file));
    427   EXPECT_FALSE(p->CanReadFileSystemFile(kRendererID, url));
    428   EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url));
    429   EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url));
    430   EXPECT_FALSE(p->CanCreateWriteFileSystemFile(kRendererID, url));
    431 
    432   p->GrantCreateWriteFile(kRendererID, file);
    433   EXPECT_FALSE(p->CanReadFile(kRendererID, file));
    434   EXPECT_TRUE(p->CanWriteFile(kRendererID, file));
    435   EXPECT_TRUE(p->CanCreateFile(kRendererID, file));
    436   EXPECT_TRUE(p->CanCreateWriteFile(kRendererID, file));
    437   EXPECT_FALSE(p->CanReadFileSystemFile(kRendererID, url));
    438   EXPECT_TRUE(p->CanWriteFileSystemFile(kRendererID, url));
    439   EXPECT_TRUE(p->CanCreateFileSystemFile(kRendererID, url));
    440   EXPECT_TRUE(p->CanCreateWriteFileSystemFile(kRendererID, url));
    441   p->RevokeAllPermissionsForFile(kRendererID, file);
    442   EXPECT_FALSE(p->CanReadFile(kRendererID, file));
    443   EXPECT_FALSE(p->CanWriteFile(kRendererID, file));
    444   EXPECT_FALSE(p->CanCreateFile(kRendererID, file));
    445   EXPECT_FALSE(p->CanCreateWriteFile(kRendererID, file));
    446   EXPECT_FALSE(p->CanReadFileSystemFile(kRendererID, url));
    447   EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url));
    448   EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url));
    449   EXPECT_FALSE(p->CanCreateWriteFileSystemFile(kRendererID, url));
    450 
    451   // Test revoke permissions on renderer ID removal.
    452   p->GrantCreateReadWriteFile(kRendererID, file);
    453   EXPECT_TRUE(p->CanReadFile(kRendererID, file));
    454   EXPECT_TRUE(p->CanWriteFile(kRendererID, file));
    455   EXPECT_TRUE(p->CanCreateFile(kRendererID, file));
    456   EXPECT_TRUE(p->CanCreateWriteFile(kRendererID, file));
    457   EXPECT_TRUE(p->CanReadFileSystemFile(kRendererID, url));
    458   EXPECT_TRUE(p->CanWriteFileSystemFile(kRendererID, url));
    459   EXPECT_TRUE(p->CanCreateFileSystemFile(kRendererID, url));
    460   EXPECT_TRUE(p->CanCreateWriteFileSystemFile(kRendererID, url));
    461   p->Remove(kRendererID);
    462   EXPECT_FALSE(p->CanReadFile(kRendererID, file));
    463   EXPECT_FALSE(p->CanWriteFile(kRendererID, file));
    464   EXPECT_FALSE(p->CanCreateFile(kRendererID, file));
    465   EXPECT_FALSE(p->CanCreateWriteFile(kRendererID, file));
    466   EXPECT_FALSE(p->CanReadFileSystemFile(kRendererID, url));
    467   EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url));
    468   EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url));
    469   EXPECT_FALSE(p->CanCreateWriteFileSystemFile(kRendererID, url));
    470 
    471   // Test having no permissions upon re-adding same renderer ID.
    472   p->Add(kRendererID);
    473   EXPECT_FALSE(p->CanReadFile(kRendererID, file));
    474   EXPECT_FALSE(p->CanWriteFile(kRendererID, file));
    475   EXPECT_FALSE(p->CanCreateFile(kRendererID, file));
    476   EXPECT_FALSE(p->CanCreateWriteFile(kRendererID, file));
    477   EXPECT_FALSE(p->CanReadFileSystemFile(kRendererID, url));
    478   EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url));
    479   EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url));
    480   EXPECT_FALSE(p->CanCreateWriteFileSystemFile(kRendererID, url));
    481 
    482   // Cleanup.
    483   p->Remove(kRendererID);
    484 }
    485 
    486 TEST_F(ChildProcessSecurityPolicyTest, CanReadDirectories) {
    487   ChildProcessSecurityPolicyImpl* p =
    488       ChildProcessSecurityPolicyImpl::GetInstance();
    489 
    490   p->Add(kRendererID);
    491 
    492   EXPECT_FALSE(p->CanReadDirectory(kRendererID,
    493                                    base::FilePath(TEST_PATH("/etc/"))));
    494   p->GrantReadDirectory(kRendererID,
    495                         base::FilePath(TEST_PATH("/etc/")));
    496   EXPECT_TRUE(p->CanReadDirectory(kRendererID,
    497                                   base::FilePath(TEST_PATH("/etc/"))));
    498   EXPECT_TRUE(p->CanReadFile(kRendererID,
    499                              base::FilePath(TEST_PATH("/etc/passwd"))));
    500 
    501   p->Remove(kRendererID);
    502   p->Add(kRendererID);
    503 
    504   EXPECT_FALSE(p->CanReadDirectory(kRendererID,
    505                                    base::FilePath(TEST_PATH("/etc/"))));
    506   EXPECT_FALSE(p->CanReadFile(kRendererID,
    507                               base::FilePath(TEST_PATH("/etc/passwd"))));
    508 
    509   // Just granting read permission as a file doesn't imply reading as a
    510   // directory.
    511   p->GrantReadFile(kRendererID, base::FilePath(TEST_PATH("/etc/")));
    512   EXPECT_TRUE(p->CanReadFile(kRendererID,
    513                              base::FilePath(TEST_PATH("/etc/passwd"))));
    514   EXPECT_FALSE(p->CanReadDirectory(kRendererID,
    515                                    base::FilePath(TEST_PATH("/etc/"))));
    516 
    517   p->Remove(kRendererID);
    518 }
    519 
    520 TEST_F(ChildProcessSecurityPolicyTest, FilePermissions) {
    521   base::FilePath granted_file = base::FilePath(TEST_PATH("/home/joe"));
    522   base::FilePath sibling_file = base::FilePath(TEST_PATH("/home/bob"));
    523   base::FilePath child_file = base::FilePath(TEST_PATH("/home/joe/file"));
    524   base::FilePath parent_file = base::FilePath(TEST_PATH("/home"));
    525   base::FilePath parent_slash_file = base::FilePath(TEST_PATH("/home/"));
    526   base::FilePath child_traversal1 =
    527       base::FilePath(TEST_PATH("/home/joe/././file"));
    528   base::FilePath child_traversal2 = base::FilePath(
    529       TEST_PATH("/home/joe/file/../otherfile"));
    530   base::FilePath evil_traversal1 =
    531       base::FilePath(TEST_PATH("/home/joe/../../etc/passwd"));
    532   base::FilePath evil_traversal2 = base::FilePath(
    533       TEST_PATH("/home/joe/./.././../etc/passwd"));
    534   base::FilePath self_traversal =
    535       base::FilePath(TEST_PATH("/home/joe/../joe/file"));
    536   base::FilePath relative_file = base::FilePath(FILE_PATH_LITERAL("home/joe"));
    537 
    538   ChildProcessSecurityPolicyImpl* p =
    539       ChildProcessSecurityPolicyImpl::GetInstance();
    540 
    541   // Grant permissions for a file.
    542   p->Add(kRendererID);
    543   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
    544                                         base::PLATFORM_FILE_OPEN));
    545 
    546   GrantPermissionsForFile(p, kRendererID, granted_file,
    547                              base::PLATFORM_FILE_OPEN |
    548                              base::PLATFORM_FILE_OPEN_TRUNCATED |
    549                              base::PLATFORM_FILE_READ |
    550                              base::PLATFORM_FILE_WRITE);
    551   EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file,
    552                                        base::PLATFORM_FILE_OPEN |
    553                                        base::PLATFORM_FILE_OPEN_TRUNCATED |
    554                                        base::PLATFORM_FILE_READ |
    555                                        base::PLATFORM_FILE_WRITE));
    556   EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file,
    557                                        base::PLATFORM_FILE_OPEN |
    558                                        base::PLATFORM_FILE_READ));
    559   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
    560                                         base::PLATFORM_FILE_CREATE));
    561   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 0));
    562   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
    563                                         base::PLATFORM_FILE_CREATE |
    564                                         base::PLATFORM_FILE_OPEN_TRUNCATED |
    565                                         base::PLATFORM_FILE_READ |
    566                                         base::PLATFORM_FILE_WRITE));
    567   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, sibling_file,
    568                                         base::PLATFORM_FILE_OPEN |
    569                                         base::PLATFORM_FILE_READ));
    570   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, parent_file,
    571                                         base::PLATFORM_FILE_OPEN |
    572                                         base::PLATFORM_FILE_READ));
    573   EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, child_file,
    574                                         base::PLATFORM_FILE_OPEN |
    575                                         base::PLATFORM_FILE_READ));
    576   EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, child_traversal1,
    577                                         base::PLATFORM_FILE_OPEN |
    578                                         base::PLATFORM_FILE_READ));
    579   EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, child_traversal2,
    580                                         base::PLATFORM_FILE_OPEN |
    581                                         base::PLATFORM_FILE_READ));
    582   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, evil_traversal1,
    583                                         base::PLATFORM_FILE_OPEN |
    584                                         base::PLATFORM_FILE_READ));
    585   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, evil_traversal2,
    586                                         base::PLATFORM_FILE_OPEN |
    587                                         base::PLATFORM_FILE_READ));
    588   // CPSP doesn't allow this case for the sake of simplicity.
    589   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, self_traversal,
    590                                         base::PLATFORM_FILE_OPEN |
    591                                         base::PLATFORM_FILE_READ));
    592   p->Remove(kRendererID);
    593 
    594   // Grant permissions for the directory the file is in.
    595   p->Add(kRendererID);
    596   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
    597                                         base::PLATFORM_FILE_OPEN));
    598   GrantPermissionsForFile(p, kRendererID, parent_file,
    599                              base::PLATFORM_FILE_OPEN |
    600                              base::PLATFORM_FILE_READ);
    601   EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file,
    602                                         base::PLATFORM_FILE_OPEN));
    603   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
    604                                         base::PLATFORM_FILE_READ |
    605                                         base::PLATFORM_FILE_WRITE));
    606   p->Remove(kRendererID);
    607 
    608   // Grant permissions for the directory the file is in (with trailing '/').
    609   p->Add(kRendererID);
    610   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
    611                                         base::PLATFORM_FILE_OPEN));
    612   GrantPermissionsForFile(p, kRendererID, parent_slash_file,
    613                              base::PLATFORM_FILE_OPEN |
    614                              base::PLATFORM_FILE_READ);
    615   EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file,
    616                                         base::PLATFORM_FILE_OPEN));
    617   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
    618                                         base::PLATFORM_FILE_READ |
    619                                         base::PLATFORM_FILE_WRITE));
    620 
    621   // Grant permissions for the file (should overwrite the permissions granted
    622   // for the directory).
    623   GrantPermissionsForFile(p, kRendererID, granted_file,
    624                              base::PLATFORM_FILE_TEMPORARY);
    625   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
    626                                         base::PLATFORM_FILE_OPEN));
    627   EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file,
    628                                        base::PLATFORM_FILE_TEMPORARY));
    629 
    630   // Revoke all permissions for the file (it should inherit its permissions
    631   // from the directory again).
    632   p->RevokeAllPermissionsForFile(kRendererID, granted_file);
    633   EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file,
    634                                        base::PLATFORM_FILE_OPEN |
    635                                        base::PLATFORM_FILE_READ));
    636   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
    637                                         base::PLATFORM_FILE_TEMPORARY));
    638   p->Remove(kRendererID);
    639 
    640   // Grant file permissions for the file to main thread renderer process,
    641   // make sure its worker thread renderer process inherits those.
    642   p->Add(kRendererID);
    643   GrantPermissionsForFile(p, kRendererID, granted_file,
    644                              base::PLATFORM_FILE_OPEN |
    645                              base::PLATFORM_FILE_READ);
    646   EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file,
    647                                        base::PLATFORM_FILE_OPEN |
    648                                        base::PLATFORM_FILE_READ));
    649   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
    650                                        base::PLATFORM_FILE_WRITE));
    651   p->AddWorker(kWorkerRendererID, kRendererID);
    652   EXPECT_TRUE(p->HasPermissionsForFile(kWorkerRendererID, granted_file,
    653                                        base::PLATFORM_FILE_OPEN |
    654                                        base::PLATFORM_FILE_READ));
    655   EXPECT_FALSE(p->HasPermissionsForFile(kWorkerRendererID, granted_file,
    656                                         base::PLATFORM_FILE_WRITE));
    657   p->Remove(kRendererID);
    658   EXPECT_FALSE(p->HasPermissionsForFile(kWorkerRendererID, granted_file,
    659                                         base::PLATFORM_FILE_OPEN |
    660                                         base::PLATFORM_FILE_READ));
    661   p->Remove(kWorkerRendererID);
    662 
    663   p->Add(kRendererID);
    664   GrantPermissionsForFile(p, kRendererID, relative_file,
    665                              base::PLATFORM_FILE_OPEN);
    666   EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, relative_file,
    667                                         base::PLATFORM_FILE_OPEN));
    668   p->Remove(kRendererID);
    669 }
    670 
    671 TEST_F(ChildProcessSecurityPolicyTest, CanServiceWebUIBindings) {
    672   ChildProcessSecurityPolicyImpl* p =
    673       ChildProcessSecurityPolicyImpl::GetInstance();
    674 
    675   GURL url("chrome://thumb/http://www.google.com/");
    676 
    677   p->Add(kRendererID);
    678 
    679   EXPECT_FALSE(p->HasWebUIBindings(kRendererID));
    680   EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
    681   p->GrantWebUIBindings(kRendererID);
    682   EXPECT_TRUE(p->HasWebUIBindings(kRendererID));
    683   EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
    684 
    685   p->Remove(kRendererID);
    686 }
    687 
    688 TEST_F(ChildProcessSecurityPolicyTest, RemoveRace) {
    689   ChildProcessSecurityPolicyImpl* p =
    690       ChildProcessSecurityPolicyImpl::GetInstance();
    691 
    692   GURL url("file:///etc/passwd");
    693   base::FilePath file(TEST_PATH("/etc/passwd"));
    694 
    695   p->Add(kRendererID);
    696 
    697   p->GrantRequestURL(kRendererID, url);
    698   p->GrantReadFile(kRendererID, file);
    699   p->GrantWebUIBindings(kRendererID);
    700 
    701   EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
    702   EXPECT_TRUE(p->CanReadFile(kRendererID, file));
    703   EXPECT_TRUE(p->HasWebUIBindings(kRendererID));
    704 
    705   p->Remove(kRendererID);
    706 
    707   // Renderers are added and removed on the UI thread, but the policy can be
    708   // queried on the IO thread.  The ChildProcessSecurityPolicy needs to be
    709   // prepared to answer policy questions about renderers who no longer exist.
    710 
    711   // In this case, we default to secure behavior.
    712   EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
    713   EXPECT_FALSE(p->CanReadFile(kRendererID, file));
    714   EXPECT_FALSE(p->HasWebUIBindings(kRendererID));
    715 }
    716 
    717 }  // namespace content
    718