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

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

Powered by Google App Engine
This is Rietveld 408576698