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

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

Issue 107663008: Chrome browser process DLL blacklist. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Greg's feedback. Created 7 years 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 | Annotate | Revision Log
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 <string>
12 #include <vector>
13
14 // Note that only #includes from base that are either header-only or built into
15 // base_static (see base/base.gyp) are allowed here.
16 #include "base/basictypes.h"
17 #include "base/strings/string16.h"
18 #include "base/win/pe_image.h"
19 #include "chrome_elf/blacklist/blacklist.h"
20 #include "sandbox/win/src/internal_types.h"
21 #include "sandbox/win/src/nt_internals.h"
22 #include "sandbox/win/src/sandbox_nt_util.h"
23 #include "sandbox/win/src/sandbox_types.h"
24
25 namespace {
26
27 // TODO(robertshield): Merge with ntdll exports cache.
28 FARPROC GetNtDllExportByName(const char* export_name) {
29 HMODULE ntdll = ::GetModuleHandle(sandbox::kNtdllName);
30 return ::GetProcAddress(ntdll, export_name);
31 }
32
33 NtQuerySectionFunction g_nt_query_section_func =
34 reinterpret_cast<NtQuerySectionFunction>(
35 GetNtDllExportByName("NtQuerySection"));
rvargas (doing something else) 2013/12/17 22:09:27 Isn't it better to have an explicit initialization
robertshield 2013/12/18 02:34:43 Done.
36 NtQueryVirtualMemoryFunction g_nt_query_virtual_memory_func =
37 reinterpret_cast<NtQueryVirtualMemoryFunction>(
38 GetNtDllExportByName("NtQueryVirtualMemory"));
39 NtUnmapViewOfSectionFunction g_nt_unmap_view_of_section_func =
40 reinterpret_cast<NtUnmapViewOfSectionFunction>(
41 GetNtDllExportByName("NtUnmapViewOfSection"));
42
43 bool DllMatch(const string16& module_name) {
44 for (int i = 0; i < blacklist::g_troublesome_dlls_cur_index; ++i) {
45 if (module_name == blacklist::g_troublesome_dlls[i])
46 return true;
47 }
48 return false;
49 }
50
51 // Native reimplementation of PSAPIs GetMappedFileName.
52 string16 GetBackingModuleFilePath(PVOID address) {
rvargas (doing something else) 2013/12/17 22:09:27 it would have been nice to use the functions from
robertshield 2013/12/18 02:34:43 It could perhaps have been done, though iirc it mi
53 if (!g_nt_query_virtual_memory_func)
54 return string16();
55
56 // We'll start with something close to max_path characters for the name.
57 ULONG buffer_bytes = MAX_PATH * 2;
58 std::vector<BYTE> buffer_data(buffer_bytes);
59
60 for (;;) {
61 MEMORY_SECTION_NAME* section_name =
62 reinterpret_cast<MEMORY_SECTION_NAME*>(&buffer_data[0]);
63
64 if (!section_name)
65 break;
66
67 ULONG returned_bytes;
68 NTSTATUS ret = g_nt_query_virtual_memory_func(
69 NtCurrentProcess, address, MemorySectionName, section_name,
70 buffer_bytes, &returned_bytes);
71
72 if (STATUS_BUFFER_OVERFLOW == ret) {
73 // Retry the call with the given buffer size.
74 buffer_bytes = returned_bytes + 1;
75 buffer_data.resize(buffer_bytes);
76 section_name = NULL;
77 continue;
78 }
79 if (!NT_SUCCESS(ret)) {
rvargas (doing something else) 2013/12/17 22:09:27 nit: no {}
robertshield 2013/12/18 02:34:43 Done.
80 break;
81 }
82
83 UNICODE_STRING* section_string =
84 reinterpret_cast<UNICODE_STRING*>(section_name);
85 return string16(section_string->Buffer,
86 section_string->Length / sizeof(wchar_t));
87 }
88
89 return string16();
90 }
91
92 bool IsModuleValidImageSection(HANDLE section,
93 PVOID *base,
94 PLARGE_INTEGER offset,
95 PSIZE_T view_size) {
96 if (!section || !base || !view_size || offset)
97 return false;
98
99 if (!g_nt_query_section_func)
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 string16 ExtractLoadedModuleName(const string16& module_path) {
118 if (module_path.empty() || module_path[module_path.size() - 1] == L'\\')
119 return string16();
120
121 size_t sep = module_path.find_last_of(L'\\');
122 if (sep == 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.
129 void SafeGetImageName(const base::win::PEImage& pe, std::string* out_name) {
130 out_name->clear();
131 out_name->reserve(MAX_PATH);
132 PIMAGE_EXPORT_DIRECTORY exports = pe.GetExportDirectory();
133 if (exports) {
134 char* image_name = reinterpret_cast<char*>(pe.RVAToAddr(exports->Name));
Sigurður Ásgeirsson 2013/12/18 14:16:01 nit: while you're in there, perhaps const char*
robertshield 2013/12/18 17:01:36 Done.
135 __try {
136 size_t i = 0;
137 for (; i < MAX_PATH && *image_name; ++i, ++image_name)
138 out_name->push_back(*image_name);
139 } __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
140 EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
rvargas (doing something else) 2013/12/17 22:09:27 I'm curious about why letting the process crash he
robertshield 2013/12/18 02:34:43 It's more about avoiding the general badness of no
141 out_name->clear();
142 }
143 }
144 }
145
146 string16 GetImageInfoFromLoadedModule(HMODULE module, uint32* flags) {
147 std::string out_name;
148 *flags = 0;
149 base::win::PEImage pe(module);
rvargas (doing something else) 2013/12/17 22:09:27 this whole thing has to be inside the try block, n
robertshield 2013/12/18 02:34:43 Done.
150
151 if (pe.VerifyMagic()) {
152 *flags |= sandbox::MODULE_IS_PE_IMAGE;
153
154 SafeGetImageName(pe, &out_name);
155
156 PIMAGE_NT_HEADERS headers = pe.GetNTHeaders();
157 if (headers) {
158 if (headers->OptionalHeader.AddressOfEntryPoint)
159 *flags |= sandbox::MODULE_HAS_ENTRY_POINT;
160 if (headers->OptionalHeader.SizeOfCode)
161 *flags |= sandbox::MODULE_HAS_CODE;
162 }
163 }
164
165 return string16(out_name.begin(), out_name.end());
166 }
167
168 } // namespace
169
170 namespace blacklist {
171
172 SANDBOX_INTERCEPT NTSTATUS WINAPI BlNtMapViewOfSection(
173 NtMapViewOfSectionFunction orig_MapViewOfSection,
174 HANDLE section,
175 HANDLE process,
176 PVOID *base,
177 ULONG_PTR zero_bits,
178 SIZE_T commit_size,
179 PLARGE_INTEGER offset,
180 PSIZE_T view_size,
181 SECTION_INHERIT inherit,
182 ULONG allocation_type,
183 ULONG protect) {
184
185 NTSTATUS ret = orig_MapViewOfSection(section, process, base, zero_bits,
186 commit_size, offset, view_size, inherit,
187 allocation_type, protect);
188
189 if (!NT_SUCCESS(ret) || !sandbox::IsSameProcess(process) ||
190 !IsModuleValidImageSection(section, base, offset, view_size)) {
191 return ret;
192 }
193
194 HMODULE module = reinterpret_cast<HMODULE>(*base);
195 if (module) {
196 UINT image_flags;
197
198 string16 module_name(GetImageInfoFromLoadedModule(
199 reinterpret_cast<HMODULE>(*base), &image_flags));
200 string16 file_name(GetBackingModuleFilePath(*base));
201
202 if (module_name.empty() && (image_flags & sandbox::MODULE_HAS_CODE)) {
203 // If the module has no exports we retrieve the module name from the
204 // full path of the mapped section.
205 module_name = ExtractLoadedModuleName(file_name);
206 }
207
208 if (!module_name.empty() && DllMatch(module_name)) {
209 if (g_nt_unmap_view_of_section_func) {
210 g_nt_unmap_view_of_section_func(process, *base);
211 ret = STATUS_UNSUCCESSFUL;
212 }
213 }
214
215 }
216 return ret;
217 }
218
219 } // namespace blacklist
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698