Home | History | Annotate | Download | only in validation_tests
      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 // This file contains the validation tests for the sandbox.
      6 // It includes the tests that need to be performed inside the
      7 // sandbox.
      8 
      9 #include <shlwapi.h>
     10 
     11 #include "base/win/windows_version.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 #include "sandbox/win/tests/common/controller.h"
     14 
     15 #pragma comment(lib, "shlwapi.lib")
     16 
     17 namespace {
     18 
     19 void TestProcessAccess(sandbox::TestRunner* runner, DWORD target) {
     20   const wchar_t *kCommandTemplate = L"OpenProcessCmd %d %d";
     21   wchar_t command[1024] = {0};
     22 
     23   // Test all the scary process permissions.
     24   wsprintf(command, kCommandTemplate, target, PROCESS_CREATE_THREAD);
     25   EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command));
     26   wsprintf(command, kCommandTemplate, target, PROCESS_DUP_HANDLE);
     27   EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command));
     28   wsprintf(command, kCommandTemplate, target, PROCESS_SET_INFORMATION);
     29   EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command));
     30   wsprintf(command, kCommandTemplate, target, PROCESS_VM_OPERATION);
     31   EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command));
     32   wsprintf(command, kCommandTemplate, target, PROCESS_VM_READ);
     33   EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command));
     34   wsprintf(command, kCommandTemplate, target, PROCESS_VM_WRITE);
     35   EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command));
     36   wsprintf(command, kCommandTemplate, target, PROCESS_QUERY_INFORMATION);
     37   EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command));
     38   wsprintf(command, kCommandTemplate, target, WRITE_DAC);
     39   EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command));
     40   wsprintf(command, kCommandTemplate, target, WRITE_OWNER);
     41   EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command));
     42   wsprintf(command, kCommandTemplate, target, READ_CONTROL);
     43   EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command));
     44 }
     45 
     46 }  // namespace
     47 
     48 namespace sandbox {
     49 
     50 // Returns true if the volume that contains any_path supports ACL security. The
     51 // input path can contain unexpanded environment strings. Returns false on any
     52 // failure or if the file system does not support file security (such as FAT).
     53 bool VolumeSupportsACLs(const wchar_t* any_path) {
     54   wchar_t expand[MAX_PATH +1];
     55   DWORD len =::ExpandEnvironmentStringsW(any_path, expand, _countof(expand));
     56   if (0 == len) return false;
     57   if (len >  _countof(expand)) return false;
     58   if (!::PathStripToRootW(expand)) return false;
     59   DWORD fs_flags = 0;
     60   if (!::GetVolumeInformationW(expand, NULL, 0, 0, NULL, &fs_flags, NULL, 0))
     61     return false;
     62   if (fs_flags & FILE_PERSISTENT_ACLS) return true;
     63   return false;
     64 }
     65 
     66 // Tests if the suite is working properly.
     67 TEST(ValidationSuite, TestSuite) {
     68   TestRunner runner;
     69   ASSERT_EQ(SBOX_TEST_PING_OK, runner.RunTest(L"ping"));
     70 }
     71 
     72 // Tests if the file system is correctly protected by the sandbox.
     73 TEST(ValidationSuite, TestFileSystem) {
     74   // Do not perform the test if the system is using FAT or any other
     75   // file system that does not have file security.
     76   ASSERT_TRUE(VolumeSupportsACLs(L"%SystemDrive%\\"));
     77   ASSERT_TRUE(VolumeSupportsACLs(L"%SystemRoot%\\"));
     78   ASSERT_TRUE(VolumeSupportsACLs(L"%ProgramFiles%\\"));
     79   ASSERT_TRUE(VolumeSupportsACLs(L"%Temp%\\"));
     80   ASSERT_TRUE(VolumeSupportsACLs(L"%AppData%\\"));
     81 
     82   TestRunner runner;
     83   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFile %SystemDrive%"));
     84   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFile %SystemRoot%"));
     85   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFile %ProgramFiles%"));
     86   EXPECT_EQ(SBOX_TEST_DENIED,
     87       runner.RunTest(L"OpenFile %SystemRoot%\\System32"));
     88   EXPECT_EQ(SBOX_TEST_DENIED,
     89       runner.RunTest(L"OpenFile %SystemRoot%\\explorer.exe"));
     90   EXPECT_EQ(SBOX_TEST_DENIED,
     91       runner.RunTest(L"OpenFile %SystemRoot%\\Cursors\\arrow_i.cur"));
     92   EXPECT_EQ(SBOX_TEST_DENIED,
     93       runner.RunTest(L"OpenFile %AllUsersProfile%"));
     94   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFile %Temp%"));
     95   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFile %AppData%"));
     96 }
     97 
     98 // Tests if the registry is correctly protected by the sandbox.
     99 TEST(ValidationSuite, TestRegistry) {
    100   TestRunner runner;
    101   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenKey HKLM"));
    102   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenKey HKCU"));
    103   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenKey HKU"));
    104   EXPECT_EQ(SBOX_TEST_DENIED,
    105       runner.RunTest(
    106           L"OpenKey HKLM "
    107           L"\"Software\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon\""));
    108 }
    109 
    110 // Tests that the permissions on the Windowstation does not allow the sandbox
    111 // to get to the interactive desktop or to make the sbox desktop interactive.
    112 TEST(ValidationSuite, TestDesktop) {
    113   TestRunner runner;
    114   runner.GetPolicy()->SetAlternateDesktop(true);
    115   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenInteractiveDesktop NULL"));
    116   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"SwitchToSboxDesktop NULL"));
    117 }
    118 
    119 // Tests that the permissions on the Windowstation does not allow the sandbox
    120 // to get to the interactive desktop or to make the sbox desktop interactive.
    121 TEST(ValidationSuite, TestAlternateDesktop) {
    122   base::win::Version version = base::win::GetVersion();
    123   if (version < base::win::VERSION_WIN7)
    124     return;
    125 
    126   TestRunner runner;
    127   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"EnumAlternateWinsta NULL"));
    128 
    129   wchar_t command[1024] = {0};
    130   runner.SetTimeout(3600000);
    131   runner.GetPolicy()->SetAlternateDesktop(true);
    132   runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_UNTRUSTED);
    133   base::string16 desktop_name = runner.GetPolicy()->GetAlternateDesktop();
    134   desktop_name = desktop_name.substr(desktop_name.find('\\') + 1);
    135   wsprintf(command, L"OpenAlternateDesktop %lS", desktop_name.c_str());
    136   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command));
    137 }
    138 
    139 // Tests if the windows are correctly protected by the sandbox.
    140 TEST(ValidationSuite, TestWindows) {
    141   TestRunner runner;
    142   wchar_t command[1024] = {0};
    143 
    144   wsprintf(command, L"ValidWindow %d", ::GetDesktopWindow());
    145   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command));
    146 
    147   wsprintf(command, L"ValidWindow %d", ::FindWindow(NULL, NULL));
    148   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command));
    149 }
    150 
    151 // Tests that a locked-down process cannot open another locked-down process.
    152 TEST(ValidationSuite, TestProcessDenyLockdown) {
    153   TestRunner runner;
    154   TestRunner target;
    155   wchar_t command[1024] = {0};
    156 
    157   target.SetAsynchronous(true);
    158 
    159   EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"SleepCmd 30000"));
    160 
    161   TestProcessAccess(&runner, target.process_id());
    162 }
    163 
    164 // Tests that a low-integrity process cannot open a locked-down process (due
    165 // to the integrity label changing after startup via SetDelayedIntegrityLevel).
    166 TEST(ValidationSuite, TestProcessDenyLowIntegrity) {
    167   // This test applies only to Vista and above.
    168   if (base::win::Version() < base::win::VERSION_VISTA)
    169     return;
    170 
    171   TestRunner runner;
    172   TestRunner target;
    173   wchar_t command[1024] = {0};
    174 
    175   target.SetAsynchronous(true);
    176   target.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW);
    177 
    178   runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
    179   runner.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS,
    180                                     USER_INTERACTIVE);
    181 
    182   EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"SleepCmd 30000"));
    183 
    184   TestProcessAccess(&runner, target.process_id());
    185 }
    186 
    187 // Tests that a locked-down process cannot open a low-integrity process.
    188 TEST(ValidationSuite, TestProcessDenyBelowLowIntegrity) {
    189   //  This test applies only to Vista and above.
    190   if (base::win::Version() < base::win::VERSION_VISTA)
    191     return;
    192 
    193   TestRunner runner;
    194   TestRunner target;
    195   wchar_t command[1024] = {0};
    196 
    197   target.SetAsynchronous(true);
    198   target.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
    199   target.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS,
    200                                     USER_INTERACTIVE);
    201 
    202   runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_UNTRUSTED);
    203   runner.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS,
    204                                     USER_INTERACTIVE);
    205 
    206   EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"SleepCmd 30000"));
    207 
    208   TestProcessAccess(&runner, target.process_id());
    209 }
    210 
    211 // Tests if the threads are correctly protected by the sandbox.
    212 TEST(ValidationSuite, TestThread) {
    213   TestRunner runner;
    214   wchar_t command[1024] = {0};
    215 
    216   wsprintf(command, L"OpenThreadCmd %d", ::GetCurrentThreadId());
    217   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command));
    218 }
    219 
    220 // Tests if an over-limit allocation will be denied.
    221 TEST(ValidationSuite, TestMemoryLimit) {
    222   TestRunner runner;
    223   wchar_t command[1024] = {0};
    224   const int kAllocationSize = 256 * 1024 * 1024;
    225 
    226   wsprintf(command, L"AllocateCmd %d", kAllocationSize);
    227   runner.GetPolicy()->SetJobMemoryLimit(kAllocationSize);
    228   EXPECT_EQ(SBOX_FATAL_MEMORY_EXCEEDED, runner.RunTest(command));
    229 }
    230 
    231 // Tests a large allocation will succeed absent limits.
    232 TEST(ValidationSuite, TestMemoryNoLimit) {
    233   TestRunner runner;
    234   wchar_t command[1024] = {0};
    235   const int kAllocationSize = 256 * 1024 * 1024;
    236 
    237   wsprintf(command, L"AllocateCmd %d", kAllocationSize);
    238   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command));
    239 }
    240 
    241 }  // namespace sandbox
    242