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 "base/strings/stringprintf.h" 6#include "sandbox/win/src/handle_policy.h" 7#include "sandbox/win/src/nt_internals.h" 8#include "sandbox/win/src/sandbox.h" 9#include "sandbox/win/src/sandbox_factory.h" 10#include "sandbox/win/src/sandbox_policy.h" 11#include "sandbox/win/src/win_utils.h" 12#include "sandbox/win/tests/common/controller.h" 13#include "testing/gtest/include/gtest/gtest.h" 14 15namespace sandbox { 16 17// Just waits for the supplied number of milliseconds. 18SBOX_TESTS_COMMAND int Handle_WaitProcess(int argc, wchar_t **argv) { 19 if (argc != 1) 20 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; 21 22 ::Sleep(::wcstoul(argv[0], NULL, 10)); 23 return SBOX_TEST_TIMED_OUT; 24} 25 26// Attempts to duplicate an event handle into the target process. 27SBOX_TESTS_COMMAND int Handle_DuplicateEvent(int argc, wchar_t **argv) { 28 if (argc != 1) 29 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; 30 31 // Create a test event to use as a handle. 32 base::win::ScopedHandle test_event; 33 test_event.Set(::CreateEvent(NULL, TRUE, TRUE, NULL)); 34 if (!test_event.IsValid()) 35 return SBOX_TEST_FIRST_ERROR; 36 37 // Get the target process ID. 38 DWORD target_process_id = ::wcstoul(argv[0], NULL, 10); 39 40 HANDLE handle = NULL; 41 ResultCode result = SandboxFactory::GetTargetServices()->DuplicateHandle( 42 test_event, target_process_id, &handle, 0, DUPLICATE_SAME_ACCESS); 43 44 return (result == SBOX_ALL_OK) ? SBOX_TEST_SUCCEEDED : SBOX_TEST_DENIED; 45} 46 47// Tests that duplicating an object works only when the policy allows it. 48TEST(HandlePolicyTest, DuplicateHandle) { 49 TestRunner target; 50 TestRunner runner; 51 52 // Kick off an asynchronous target process for testing. 53 target.SetAsynchronous(true); 54 EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"Handle_WaitProcess 30000")); 55 56 // First test that we fail to open the event. 57 base::string16 cmd_line = base::StringPrintf(L"Handle_DuplicateEvent %d", 58 target.process_id()); 59 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(cmd_line.c_str())); 60 61 // Now successfully open the event after adding a duplicate handle rule. 62 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_HANDLES, 63 TargetPolicy::HANDLES_DUP_ANY, 64 L"Event")); 65 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(cmd_line.c_str())); 66} 67 68// Tests that duplicating an object works only when the policy allows it. 69TEST(HandlePolicyTest, DuplicatePeerHandle) { 70 TestRunner target; 71 TestRunner runner; 72 73 // Kick off an asynchronous target process for testing. 74 target.SetAsynchronous(true); 75 target.SetUnsandboxed(true); 76 EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"Handle_WaitProcess 30000")); 77 78 // First test that we fail to open the event. 79 base::string16 cmd_line = base::StringPrintf(L"Handle_DuplicateEvent %d", 80 target.process_id()); 81 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(cmd_line.c_str())); 82 83 // Now successfully open the event after adding a duplicate handle rule. 84 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_HANDLES, 85 TargetPolicy::HANDLES_DUP_ANY, 86 L"Event")); 87 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(cmd_line.c_str())); 88} 89 90// Tests that duplicating an object works only when the policy allows it. 91TEST(HandlePolicyTest, DuplicateBrokerHandle) { 92 TestRunner runner; 93 94 // First test that we fail to open the event. 95 base::string16 cmd_line = base::StringPrintf(L"Handle_DuplicateEvent %d", 96 ::GetCurrentProcessId()); 97 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(cmd_line.c_str())); 98 99 // Add the peer rule and make sure we fail again. 100 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_HANDLES, 101 TargetPolicy::HANDLES_DUP_ANY, 102 L"Event")); 103 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(cmd_line.c_str())); 104 105 106 // Now successfully open the event after adding a broker handle rule. 107 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_HANDLES, 108 TargetPolicy::HANDLES_DUP_BROKER, 109 L"Event")); 110 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(cmd_line.c_str())); 111} 112 113} // namespace sandbox 114 115