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

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: Ricardo'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 NtQuerySectionFunction g_nt_query_section_func = NULL;
28 NtQueryVirtualMemoryFunction g_nt_query_virtual_memory_func = NULL;
29 NtUnmapViewOfSectionFunction g_nt_unmap_view_of_section_func = NULL;
30
31 // TODO(robertshield): Merge with ntdll exports cache.
32 FARPROC GetNtDllExportByName(const char* export_name) {
33 HMODULE ntdll = ::GetModuleHandle(sandbox::kNtdllName);
34 return ::GetProcAddress(ntdll, export_name);
35 }
36
37 bool DllMatch(const string16& module_name) {
38 for (int i = 0; i < blacklist::g_troublesome_dlls_cur_index; ++i) {
39 if (module_name == blacklist::g_troublesome_dlls[i])
40 return true;
41 }
42 return false;
43 }
44
45 // TODO(robertshield): Some of the helper functions below overlap somewhat with
46 // code in sandbox_nt_util.cc. See if they can be unified.
47
48 // Native reimplementation of PSAPIs GetMappedFileName.
49 string16 GetBackingModuleFilePath(PVOID address) {
50 if (!g_nt_query_virtual_memory_func)
rvargas (doing something else) 2013/12/18 03:19:27 should never happen
robertshield 2013/12/18 04:51:17 Done.
51 return string16();
52
53 // We'll start with something close to max_path characters for the name.
54 ULONG buffer_bytes = MAX_PATH * 2;
55 std::vector<BYTE> buffer_data(buffer_bytes);
56
57 for (;;) {
58 MEMORY_SECTION_NAME* section_name =
59 reinterpret_cast<MEMORY_SECTION_NAME*>(&buffer_data[0]);
60
61 if (!section_name)
62 break;
63
64 ULONG returned_bytes;
65 NTSTATUS ret = g_nt_query_virtual_memory_func(
66 NtCurrentProcess, address, MemorySectionName, section_name,
67 buffer_bytes, &returned_bytes);
68
69 if (STATUS_BUFFER_OVERFLOW == ret) {
70 // Retry the call with the given buffer size.
71 buffer_bytes = returned_bytes + 1;
72 buffer_data.resize(buffer_bytes);
73 section_name = NULL;
74 continue;
75 }
76 if (!NT_SUCCESS(ret))
77 break;
78
79 UNICODE_STRING* section_string =
80 reinterpret_cast<UNICODE_STRING*>(section_name);
81 return string16(section_string->Buffer,
82 section_string->Length / sizeof(wchar_t));
83 }
84
85 return string16();
86 }
87
88 bool IsModuleValidImageSection(HANDLE section,
89 PVOID *base,
90 PLARGE_INTEGER offset,
91 PSIZE_T view_size) {
92 if (!section || !base || !view_size || offset)
93 return false;
94
95 if (!g_nt_query_section_func)
rvargas (doing something else) 2013/12/18 03:19:27 should never happen
robertshield 2013/12/18 04:51:17 Done.
96 return false;
97
98 SECTION_BASIC_INFORMATION basic_info;
99 SIZE_T bytes_returned;
100 NTSTATUS ret = g_nt_query_section_func(section, SectionBasicInformation,
101 &basic_info, sizeof(basic_info),
102 &bytes_returned);
103
104 if (!NT_SUCCESS(ret) || sizeof(basic_info) != bytes_returned)
105 return false;
106
107 if (!(basic_info.Attributes & SEC_IMAGE))
108 return false;
109
110 return true;
111 }
112
113 string16 ExtractLoadedModuleName(const string16& module_path) {
114 if (module_path.empty() || module_path[module_path.size() - 1] == L'\\')
115 return string16();
116
117 size_t sep = module_path.find_last_of(L'\\');
118 if (sep == string16::npos)
119 return module_path;
120 else
121 return module_path.substr(sep+1);
122 }
123
124 // Fills |out_name| with the image name from the given |pe| image and |flags|
125 // with additional info about the image.
126 void SafeGetImageInfo(const base::win::PEImage& pe,
127 std::string* out_name,
128 uint32* flags) {
129 out_name->clear();
130 out_name->reserve(MAX_PATH);
131 *flags = 0;
132 __try {
133 if (pe.VerifyMagic()) {
134 *flags |= sandbox::MODULE_IS_PE_IMAGE;
135
136 PIMAGE_EXPORT_DIRECTORY exports = pe.GetExportDirectory();
137 if (exports) {
138 char* image_name = reinterpret_cast<char*>(pe.RVAToAddr(exports->Name));
139 size_t i = 0;
140 for (; i < MAX_PATH && *image_name; ++i, ++image_name)
141 out_name->push_back(*image_name);
142 }
143
144 PIMAGE_NT_HEADERS headers = pe.GetNTHeaders();
145 if (headers) {
146 if (headers->OptionalHeader.AddressOfEntryPoint)
147 *flags |= sandbox::MODULE_HAS_ENTRY_POINT;
148 if (headers->OptionalHeader.SizeOfCode)
149 *flags |= sandbox::MODULE_HAS_CODE;
150 }
151 }
152 } __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
153 EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
154 out_name->clear();
155 }
156 }
157
158 string16 GetImageInfoFromLoadedModule(HMODULE module, uint32* flags) {
159 std::string out_name;
160 base::win::PEImage pe(module);
161 SafeGetImageInfo(pe, &out_name, flags);
162 return string16(out_name.begin(), out_name.end());
163 }
164
165 } // namespace
166
167 namespace blacklist {
168
169 bool InitializeInterceptImports() {
170 g_nt_query_section_func = reinterpret_cast<NtQuerySectionFunction>(
171 GetNtDllExportByName("NtQuerySection"));
172 g_nt_query_virtual_memory_func =
173 reinterpret_cast<NtQueryVirtualMemoryFunction>(
174 GetNtDllExportByName("NtQueryVirtualMemory"));
175 g_nt_unmap_view_of_section_func =
176 reinterpret_cast<NtUnmapViewOfSectionFunction>(
177 GetNtDllExportByName("NtUnmapViewOfSection"));
178
179 return g_nt_query_section_func && g_nt_query_virtual_memory_func &&
180 g_nt_unmap_view_of_section_func;
181 }
182
183 SANDBOX_INTERCEPT NTSTATUS WINAPI BlNtMapViewOfSection(
184 NtMapViewOfSectionFunction orig_MapViewOfSection,
185 HANDLE section,
186 HANDLE process,
187 PVOID *base,
188 ULONG_PTR zero_bits,
189 SIZE_T commit_size,
190 PLARGE_INTEGER offset,
191 PSIZE_T view_size,
192 SECTION_INHERIT inherit,
193 ULONG allocation_type,
194 ULONG protect) {
195
196 NTSTATUS ret = orig_MapViewOfSection(section, process, base, zero_bits,
197 commit_size, offset, view_size, inherit,
198 allocation_type, protect);
199
200 if (!NT_SUCCESS(ret) || !sandbox::IsSameProcess(process) ||
201 !IsModuleValidImageSection(section, base, offset, view_size)) {
202 return ret;
203 }
204
205 HMODULE module = reinterpret_cast<HMODULE>(*base);
206 if (module) {
207 UINT image_flags;
208
209 string16 module_name(GetImageInfoFromLoadedModule(
210 reinterpret_cast<HMODULE>(*base), &image_flags));
211 string16 file_name(GetBackingModuleFilePath(*base));
212
213 if (module_name.empty() && (image_flags & sandbox::MODULE_HAS_CODE)) {
214 // If the module has no exports we retrieve the module name from the
215 // full path of the mapped section.
216 module_name = ExtractLoadedModuleName(file_name);
217 }
218
219 if (!module_name.empty() && DllMatch(module_name)) {
220 if (g_nt_unmap_view_of_section_func) {
rvargas (doing something else) 2013/12/18 03:19:27 should always be true now
robertshield 2013/12/18 04:51:17 Done.
221 g_nt_unmap_view_of_section_func(process, *base);
222 ret = STATUS_UNSUCCESSFUL;
223 }
224 }
225
226 }
227 return ret;
228 }
229
230 } // 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