- add sources.
[platform/framework/web/crosswalk.git] / src / sandbox / win / src / process_mitigations_test.cc
1 // Copyright (c) 2011 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 "base/win/scoped_handle.h"
7
8 #include "base/win/windows_version.h"
9 #include "sandbox/win/src/nt_internals.h"
10 #include "sandbox/win/src/process_mitigations.h"
11 #include "sandbox/win/src/sandbox.h"
12 #include "sandbox/win/src/sandbox_factory.h"
13 #include "sandbox/win/src/sandbox_utils.h"
14 #include "sandbox/win/src/target_services.h"
15 #include "sandbox/win/src/win_utils.h"
16 #include "sandbox/win/tests/common/controller.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace {
20
21 typedef BOOL (WINAPI *GetProcessDEPPolicyFunction)(
22     HANDLE process,
23     LPDWORD flags,
24     PBOOL permanent);
25
26 typedef BOOL (WINAPI *GetProcessMitigationPolicyFunction)(
27     HANDLE process,
28     PROCESS_MITIGATION_POLICY mitigation_policy,
29     PVOID buffer,
30     SIZE_T length);
31
32 GetProcessMitigationPolicyFunction get_process_mitigation_policy;
33
34 bool CheckWin8DepPolicy() {
35   PROCESS_MITIGATION_DEP_POLICY policy;
36   if (!get_process_mitigation_policy(::GetCurrentProcess(), ProcessDEPPolicy,
37                                      &policy, sizeof(policy))) {
38     return false;
39   }
40   return policy.Enable && policy.Permanent;
41 }
42
43 bool CheckWin8AslrPolicy() {
44   PROCESS_MITIGATION_ASLR_POLICY policy;
45   if (!get_process_mitigation_policy(::GetCurrentProcess(), ProcessASLRPolicy,
46                                      &policy, sizeof(policy))) {
47      return false;
48   }
49   return policy.EnableForceRelocateImages && policy.DisallowStrippedImages;
50 }
51
52 bool CheckWin8StrictHandlePolicy() {
53   PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY policy;
54   if (!get_process_mitigation_policy(::GetCurrentProcess(),
55                                      ProcessStrictHandleCheckPolicy,
56                                      &policy, sizeof(policy))) {
57      return false;
58   }
59   return policy.RaiseExceptionOnInvalidHandleReference &&
60          policy.HandleExceptionsPermanentlyEnabled;
61 }
62
63 bool CheckWin8Win32CallPolicy() {
64   PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY policy;
65   if (!get_process_mitigation_policy(::GetCurrentProcess(),
66                                      ProcessSystemCallDisablePolicy,
67                                      &policy, sizeof(policy))) {
68      return false;
69   }
70   return policy.DisallowWin32kSystemCalls;
71 }
72
73 bool CheckWin8DllExtensionPolicy() {
74   PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY policy;
75   if (!get_process_mitigation_policy(::GetCurrentProcess(),
76                                      ProcessExtensionPointDisablePolicy,
77                                      &policy, sizeof(policy))) {
78      return false;
79   }
80   return policy.DisableExtensionPoints;
81 }
82
83 }  // namespace
84
85 namespace sandbox {
86
87 SBOX_TESTS_COMMAND int CheckWin8(int argc, wchar_t **argv) {
88   get_process_mitigation_policy =
89       reinterpret_cast<GetProcessMitigationPolicyFunction>(
90           ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"),
91                            "GetProcessMitigationPolicy"));
92
93   if (!get_process_mitigation_policy)
94     return SBOX_TEST_NOT_FOUND;
95
96   if (!CheckWin8DepPolicy())
97     return SBOX_TEST_FIRST_ERROR;
98
99 #if defined(NDEBUG)  // ASLR cannot be forced in debug builds.
100   if (!CheckWin8AslrPolicy())
101     return SBOX_TEST_SECOND_ERROR;
102 #endif
103
104   if (!CheckWin8StrictHandlePolicy())
105     return SBOX_TEST_THIRD_ERROR;
106
107   if (!CheckWin8Win32CallPolicy())
108     return SBOX_TEST_FOURTH_ERROR;
109
110   if (!CheckWin8DllExtensionPolicy())
111     return SBOX_TEST_FIFTH_ERROR;
112
113   return SBOX_TEST_SUCCEEDED;
114 }
115
116 TEST(ProcessMitigationsTest, CheckWin8) {
117   if (base::win::GetVersion() < base::win::VERSION_WIN8)
118     return;
119
120   TestRunner runner;
121   sandbox::TargetPolicy* policy = runner.GetPolicy();
122
123   sandbox::MitigationFlags mitigations = MITIGATION_DEP |
124                                          MITIGATION_DEP_NO_ATL_THUNK |
125                                          MITIGATION_EXTENSION_DLL_DISABLE;
126 #if defined(NDEBUG)  // ASLR cannot be forced in debug builds.
127   mitigations |= MITIGATION_RELOCATE_IMAGE |
128                  MITIGATION_RELOCATE_IMAGE_REQUIRED;
129 #endif
130
131   EXPECT_EQ(policy->SetProcessMitigations(mitigations), SBOX_ALL_OK);
132
133   mitigations |= MITIGATION_STRICT_HANDLE_CHECKS |
134                  MITIGATION_WIN32K_DISABLE;
135
136   EXPECT_EQ(policy->SetDelayedProcessMitigations(mitigations), SBOX_ALL_OK);
137
138   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8"));
139 }
140
141
142 SBOX_TESTS_COMMAND int CheckDep(int argc, wchar_t **argv) {
143   GetProcessDEPPolicyFunction get_process_dep_policy =
144       reinterpret_cast<GetProcessDEPPolicyFunction>(
145           ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"),
146                            "GetProcessDEPPolicy"));
147   if (get_process_dep_policy) {
148     BOOL is_permanent = FALSE;
149     DWORD dep_flags = 0;
150
151     if (!get_process_dep_policy(::GetCurrentProcess(), &dep_flags,
152         &is_permanent)) {
153       return SBOX_TEST_FIRST_ERROR;
154     }
155
156     if (!(dep_flags & PROCESS_DEP_ENABLE) || !is_permanent)
157       return SBOX_TEST_SECOND_ERROR;
158
159   } else {
160     NtQueryInformationProcessFunction query_information_process = NULL;
161     ResolveNTFunctionPtr("NtQueryInformationProcess",
162                           &query_information_process);
163     if (!query_information_process)
164       return SBOX_TEST_NOT_FOUND;
165
166     ULONG size = 0;
167     ULONG dep_flags = 0;
168     if (!SUCCEEDED(query_information_process(::GetCurrentProcess(),
169                                              ProcessExecuteFlags, &dep_flags,
170                                              sizeof(dep_flags), &size))) {
171       return SBOX_TEST_THIRD_ERROR;
172     }
173
174     const int MEM_EXECUTE_OPTION_ENABLE = 1;
175     const int MEM_EXECUTE_OPTION_DISABLE = 2;
176     const int MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION = 4;
177     const int MEM_EXECUTE_OPTION_PERMANENT = 8;
178     dep_flags &= 0xff;
179
180     if (dep_flags != (MEM_EXECUTE_OPTION_DISABLE |
181                       MEM_EXECUTE_OPTION_PERMANENT)) {
182       return SBOX_TEST_FOURTH_ERROR;
183     }
184   }
185
186   return SBOX_TEST_SUCCEEDED;
187 }
188
189 #if !defined(_WIN64)  // DEP is always enabled on 64-bit.
190 TEST(ProcessMitigationsTest, CheckDep) {
191   if (!IsXPSP2OrLater() || base::win::GetVersion() > base::win::VERSION_WIN7)
192     return;
193
194   TestRunner runner;
195   sandbox::TargetPolicy* policy = runner.GetPolicy();
196
197   EXPECT_EQ(policy->SetProcessMitigations(
198                 MITIGATION_DEP |
199                 MITIGATION_DEP_NO_ATL_THUNK |
200                 MITIGATION_SEHOP),
201             SBOX_ALL_OK);
202   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckDep"));
203 }
204 #endif
205
206 }  // namespace sandbox
207