Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(468)

Side by Side Diff: chrome_elf/blacklist/blacklist_interceptions.cc

Issue 1851213002: Remove sandbox on Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix nacl compile issues Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 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 // Implementation of NtMapViewOfSection intercept for 32 bit builds.
6 //
7 // TODO(robertshield): Implement the 64 bit intercept.
8
9 #include "chrome_elf/blacklist/blacklist_interceptions.h"
10
11 #include <stddef.h>
12 #include <stdint.h>
13
14 #include <string>
15 #include <vector>
16
17 // Note that only #includes from base that are either header-only or built into
18 // base_static (see base/base.gyp) are allowed here.
19 #include "base/strings/string16.h"
20 #include "base/win/pe_image.h"
21 #include "chrome_elf/blacklist/blacklist.h"
22 #include "chrome_elf/breakpad.h"
23 #include "sandbox/win/src/internal_types.h"
24 #include "sandbox/win/src/nt_internals.h"
25 #include "sandbox/win/src/sandbox_nt_util.h"
26 #include "sandbox/win/src/sandbox_types.h"
27
28 namespace {
29
30 NtQuerySectionFunction g_nt_query_section_func = NULL;
31 NtQueryVirtualMemoryFunction g_nt_query_virtual_memory_func = NULL;
32 NtUnmapViewOfSectionFunction g_nt_unmap_view_of_section_func = NULL;
33
34 // TODO(robertshield): Merge with ntdll exports cache.
35 FARPROC GetNtDllExportByName(const char* export_name) {
36 HMODULE ntdll = ::GetModuleHandle(sandbox::kNtdllName);
37 return ::GetProcAddress(ntdll, export_name);
38 }
39
40 int DllMatch(const base::string16& module_name) {
41 if (module_name.empty())
42 return -1;
43
44 for (int i = 0; blacklist::g_troublesome_dlls[i] != NULL; ++i) {
45 if (_wcsicmp(module_name.c_str(), blacklist::g_troublesome_dlls[i]) == 0)
46 return i;
47 }
48 return -1;
49 }
50
51 // TODO(robertshield): Some of the helper functions below overlap somewhat with
52 // code in sandbox_nt_util.cc. See if they can be unified.
53
54 // Native reimplementation of PSAPIs GetMappedFileName.
55 base::string16 GetBackingModuleFilePath(PVOID address) {
56 DCHECK_NT(g_nt_query_virtual_memory_func);
57
58 // We'll start with something close to max_path characters for the name.
59 SIZE_T buffer_bytes = MAX_PATH * 2;
60 std::vector<BYTE> buffer_data(buffer_bytes);
61
62 for (;;) {
63 MEMORY_SECTION_NAME* section_name =
64 reinterpret_cast<MEMORY_SECTION_NAME*>(&buffer_data[0]);
65
66 if (!section_name)
67 break;
68
69 SIZE_T returned_bytes;
70 NTSTATUS ret = g_nt_query_virtual_memory_func(
71 NtCurrentProcess, address, MemorySectionName, section_name,
72 buffer_bytes, &returned_bytes);
73
74 if (STATUS_BUFFER_OVERFLOW == ret) {
75 // Retry the call with the given buffer size.
76 buffer_bytes = returned_bytes + 1;
77 buffer_data.resize(buffer_bytes);
78 section_name = NULL;
79 continue;
80 }
81 if (!NT_SUCCESS(ret))
82 break;
83
84 UNICODE_STRING* section_string =
85 reinterpret_cast<UNICODE_STRING*>(section_name);
86 return base::string16(section_string->Buffer,
87 section_string->Length / sizeof(wchar_t));
88 }
89
90 return base::string16();
91 }
92
93 bool IsModuleValidImageSection(HANDLE section,
94 PVOID *base,
95 PLARGE_INTEGER offset,
96 PSIZE_T view_size) {
97 DCHECK_NT(g_nt_query_section_func);
98
99 if (!section || !base || !view_size || offset)
100 return false;
101
102 SECTION_BASIC_INFORMATION basic_info;
103 SIZE_T bytes_returned;
104 NTSTATUS ret = g_nt_query_section_func(section, SectionBasicInformation,
105 &basic_info, sizeof(basic_info),
106 &bytes_returned);
107
108 if (!NT_SUCCESS(ret) || sizeof(basic_info) != bytes_returned)
109 return false;
110
111 if (!(basic_info.Attributes & SEC_IMAGE))
112 return false;
113
114 return true;
115 }
116
117 base::string16 ExtractLoadedModuleName(const base::string16& module_path) {
118 if (module_path.empty() || module_path[module_path.size() - 1] == L'\\')
119 return base::string16();
120
121 size_t sep = module_path.find_last_of(L'\\');
122 if (sep == base::string16::npos)
123 return module_path;
124 else
125 return module_path.substr(sep+1);
126 }
127
128 // Fills |out_name| with the image name from the given |pe| image and |flags|
129 // with additional info about the image.
130 void SafeGetImageInfo(const base::win::PEImage& pe,
131 std::string* out_name,
132 uint32_t* flags) {
133 out_name->clear();
134 out_name->reserve(MAX_PATH);
135 *flags = 0;
136 __try {
137 if (pe.VerifyMagic()) {
138 *flags |= sandbox::MODULE_IS_PE_IMAGE;
139
140 PIMAGE_EXPORT_DIRECTORY exports = pe.GetExportDirectory();
141 if (exports) {
142 const char* image_name = reinterpret_cast<const char*>(
143 pe.RVAToAddr(exports->Name));
144 size_t i = 0;
145 for (; i < MAX_PATH && *image_name; ++i, ++image_name)
146 out_name->push_back(*image_name);
147 }
148
149 PIMAGE_NT_HEADERS headers = pe.GetNTHeaders();
150 if (headers) {
151 if (headers->OptionalHeader.AddressOfEntryPoint)
152 *flags |= sandbox::MODULE_HAS_ENTRY_POINT;
153 if (headers->OptionalHeader.SizeOfCode)
154 *flags |= sandbox::MODULE_HAS_CODE;
155 }
156 }
157 } __except((GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ||
158 GetExceptionCode() == EXCEPTION_GUARD_PAGE ||
159 GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR) ?
160 EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
161 out_name->clear();
162 }
163 }
164
165 base::string16 GetImageInfoFromLoadedModule(HMODULE module, uint32_t* flags) {
166 std::string out_name;
167 base::win::PEImage pe(module);
168 SafeGetImageInfo(pe, &out_name, flags);
169 return base::string16(out_name.begin(), out_name.end());
170 }
171
172 bool IsSameAsCurrentProcess(HANDLE process) {
173 return (NtCurrentProcess == process) ||
174 (::GetProcessId(process) == ::GetCurrentProcessId());
175 }
176
177 NTSTATUS BlNtMapViewOfSectionImpl(
178 NtMapViewOfSectionFunction orig_MapViewOfSection,
179 HANDLE section,
180 HANDLE process,
181 PVOID *base,
182 ULONG_PTR zero_bits,
183 SIZE_T commit_size,
184 PLARGE_INTEGER offset,
185 PSIZE_T view_size,
186 SECTION_INHERIT inherit,
187 ULONG allocation_type,
188 ULONG protect) {
189 NTSTATUS ret = orig_MapViewOfSection(section, process, base, zero_bits,
190 commit_size, offset, view_size, inherit,
191 allocation_type, protect);
192
193 if (!NT_SUCCESS(ret) || !IsSameAsCurrentProcess(process) ||
194 !IsModuleValidImageSection(section, base, offset, view_size)) {
195 return ret;
196 }
197
198 HMODULE module = reinterpret_cast<HMODULE>(*base);
199 if (module) {
200 UINT image_flags;
201
202 base::string16 module_name_from_image(GetImageInfoFromLoadedModule(
203 reinterpret_cast<HMODULE>(*base), &image_flags));
204
205 int blocked_index = DllMatch(module_name_from_image);
206
207 // If the module name isn't blacklisted, see if the file name is different
208 // and blacklisted.
209 if (blocked_index == -1) {
210 base::string16 file_name(GetBackingModuleFilePath(*base));
211 base::string16 module_name_from_file = ExtractLoadedModuleName(file_name);
212
213 if (module_name_from_image != module_name_from_file)
214 blocked_index = DllMatch(module_name_from_file);
215 }
216
217 if (blocked_index != -1) {
218 DCHECK_NT(g_nt_unmap_view_of_section_func);
219 g_nt_unmap_view_of_section_func(process, *base);
220 ret = STATUS_UNSUCCESSFUL;
221
222 blacklist::BlockedDll(blocked_index);
223 }
224 }
225
226 return ret;
227 }
228
229 } // namespace
230
231 namespace blacklist {
232
233 bool InitializeInterceptImports() {
234 g_nt_query_section_func =
235 reinterpret_cast<NtQuerySectionFunction>(
236 GetNtDllExportByName("NtQuerySection"));
237 g_nt_query_virtual_memory_func =
238 reinterpret_cast<NtQueryVirtualMemoryFunction>(
239 GetNtDllExportByName("NtQueryVirtualMemory"));
240 g_nt_unmap_view_of_section_func =
241 reinterpret_cast<NtUnmapViewOfSectionFunction>(
242 GetNtDllExportByName("NtUnmapViewOfSection"));
243
244 return (g_nt_query_section_func && g_nt_query_virtual_memory_func &&
245 g_nt_unmap_view_of_section_func);
246 }
247
248 SANDBOX_INTERCEPT NTSTATUS WINAPI BlNtMapViewOfSection(
249 NtMapViewOfSectionFunction orig_MapViewOfSection,
250 HANDLE section,
251 HANDLE process,
252 PVOID *base,
253 ULONG_PTR zero_bits,
254 SIZE_T commit_size,
255 PLARGE_INTEGER offset,
256 PSIZE_T view_size,
257 SECTION_INHERIT inherit,
258 ULONG allocation_type,
259 ULONG protect) {
260 NTSTATUS ret = STATUS_UNSUCCESSFUL;
261
262 __try {
263 ret = BlNtMapViewOfSectionImpl(orig_MapViewOfSection, section, process,
264 base, zero_bits, commit_size, offset,
265 view_size, inherit, allocation_type,
266 protect);
267 } __except(GenerateCrashDump(GetExceptionInformation())) {
268 }
269
270 return ret;
271 }
272
273 #if defined(_WIN64)
274 NTSTATUS WINAPI BlNtMapViewOfSection64(
275 HANDLE section, HANDLE process, PVOID *base, ULONG_PTR zero_bits,
276 SIZE_T commit_size, PLARGE_INTEGER offset, PSIZE_T view_size,
277 SECTION_INHERIT inherit, ULONG allocation_type, ULONG protect) {
278 return BlNtMapViewOfSection(g_nt_map_view_of_section_func, section, process,
279 base, zero_bits, commit_size, offset, view_size,
280 inherit, allocation_type, protect);
281 }
282 #endif
283 } // namespace blacklist
OLDNEW
« no previous file with comments | « chrome_elf/blacklist/blacklist_interceptions.h ('k') | chrome_elf/blacklist/test/blacklist_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698