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

Side by Side Diff: sandbox/win/src/handle_closer.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
« no previous file with comments | « sandbox/win/src/handle_closer.h ('k') | sandbox/win/src/handle_closer_agent.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "sandbox/win/src/handle_closer.h"
6
7 #include <stddef.h>
8
9 #include "base/logging.h"
10 #include "base/memory/free_deleter.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/win/windows_version.h"
13 #include "sandbox/win/src/interceptors.h"
14 #include "sandbox/win/src/internal_types.h"
15 #include "sandbox/win/src/nt_internals.h"
16 #include "sandbox/win/src/process_thread_interception.h"
17 #include "sandbox/win/src/win_utils.h"
18
19 namespace {
20
21 template<typename T> T RoundUpToWordSize(T v) {
22 if (size_t mod = v % sizeof(size_t))
23 v += sizeof(size_t) - mod;
24 return v;
25 }
26
27 template<typename T> T* RoundUpToWordSize(T* v) {
28 return reinterpret_cast<T*>(RoundUpToWordSize(reinterpret_cast<size_t>(v)));
29 }
30
31 } // namespace
32
33 namespace sandbox {
34
35 // Memory buffer mapped from the parent, with the list of handles.
36 SANDBOX_INTERCEPT HandleCloserInfo* g_handles_to_close;
37
38 HandleCloser::HandleCloser() {
39 }
40
41 HandleCloser::~HandleCloser() {
42 }
43
44 ResultCode HandleCloser::AddHandle(const base::char16* handle_type,
45 const base::char16* handle_name) {
46 if (!handle_type)
47 return SBOX_ERROR_BAD_PARAMS;
48
49 base::string16 resolved_name;
50 if (handle_name) {
51 resolved_name = handle_name;
52 if (handle_type == base::string16(L"Key"))
53 if (!ResolveRegistryName(resolved_name, &resolved_name))
54 return SBOX_ERROR_BAD_PARAMS;
55 }
56
57 HandleMap::iterator names = handles_to_close_.find(handle_type);
58 if (names == handles_to_close_.end()) { // We have no entries for this type.
59 std::pair<HandleMap::iterator, bool> result = handles_to_close_.insert(
60 HandleMap::value_type(handle_type, HandleMap::mapped_type()));
61 names = result.first;
62 if (handle_name)
63 names->second.insert(resolved_name);
64 } else if (!handle_name) { // Now we need to close all handles of this type.
65 names->second.clear();
66 } else if (!names->second.empty()) { // Add another name for this type.
67 names->second.insert(resolved_name);
68 } // If we're already closing all handles of type then we're done.
69
70 return SBOX_ALL_OK;
71 }
72
73 size_t HandleCloser::GetBufferSize() {
74 size_t bytes_total = offsetof(HandleCloserInfo, handle_entries);
75
76 for (HandleMap::iterator i = handles_to_close_.begin();
77 i != handles_to_close_.end(); ++i) {
78 size_t bytes_entry = offsetof(HandleListEntry, handle_type) +
79 (i->first.size() + 1) * sizeof(base::char16);
80 for (HandleMap::mapped_type::iterator j = i->second.begin();
81 j != i->second.end(); ++j) {
82 bytes_entry += ((*j).size() + 1) * sizeof(base::char16);
83 }
84
85 // Round up to the nearest multiple of word size.
86 bytes_entry = RoundUpToWordSize(bytes_entry);
87 bytes_total += bytes_entry;
88 }
89
90 return bytes_total;
91 }
92
93 bool HandleCloser::InitializeTargetHandles(TargetProcess* target) {
94 // Do nothing on an empty list (global pointer already initialized to NULL).
95 if (handles_to_close_.empty())
96 return true;
97
98 size_t bytes_needed = GetBufferSize();
99 scoped_ptr<size_t[]> local_buffer(
100 new size_t[bytes_needed / sizeof(size_t)]);
101
102 if (!SetupHandleList(local_buffer.get(), bytes_needed))
103 return false;
104
105 HANDLE child = target->Process();
106
107 // Allocate memory in the target process without specifying the address
108 void* remote_data = ::VirtualAllocEx(child, NULL, bytes_needed,
109 MEM_COMMIT, PAGE_READWRITE);
110 if (NULL == remote_data)
111 return false;
112
113 // Copy the handle buffer over.
114 SIZE_T bytes_written;
115 BOOL result = ::WriteProcessMemory(child, remote_data, local_buffer.get(),
116 bytes_needed, &bytes_written);
117 if (!result || bytes_written != bytes_needed) {
118 ::VirtualFreeEx(child, remote_data, 0, MEM_RELEASE);
119 return false;
120 }
121
122 g_handles_to_close = reinterpret_cast<HandleCloserInfo*>(remote_data);
123
124 ResultCode rc = target->TransferVariable("g_handles_to_close",
125 &g_handles_to_close,
126 sizeof(g_handles_to_close));
127
128 return (SBOX_ALL_OK == rc);
129 }
130
131 bool HandleCloser::SetupHandleList(void* buffer, size_t buffer_bytes) {
132 ::ZeroMemory(buffer, buffer_bytes);
133 HandleCloserInfo* handle_info = reinterpret_cast<HandleCloserInfo*>(buffer);
134 handle_info->record_bytes = buffer_bytes;
135 handle_info->num_handle_types = handles_to_close_.size();
136
137 base::char16* output = reinterpret_cast<base::char16*>(
138 &handle_info->handle_entries[0]);
139 base::char16* end = reinterpret_cast<base::char16*>(
140 reinterpret_cast<char*>(buffer) + buffer_bytes);
141 for (HandleMap::iterator i = handles_to_close_.begin();
142 i != handles_to_close_.end(); ++i) {
143 if (output >= end)
144 return false;
145 HandleListEntry* list_entry = reinterpret_cast<HandleListEntry*>(output);
146 output = &list_entry->handle_type[0];
147
148 // Copy the typename and set the offset and count.
149 i->first._Copy_s(output, i->first.size(), i->first.size());
150 *(output += i->first.size()) = L'\0';
151 output++;
152 list_entry->offset_to_names = reinterpret_cast<char*>(output) -
153 reinterpret_cast<char*>(list_entry);
154 list_entry->name_count = i->second.size();
155
156 // Copy the handle names.
157 for (HandleMap::mapped_type::iterator j = i->second.begin();
158 j != i->second.end(); ++j) {
159 output = std::copy((*j).begin(), (*j).end(), output) + 1;
160 }
161
162 // Round up to the nearest multiple of sizeof(size_t).
163 output = RoundUpToWordSize(output);
164 list_entry->record_bytes = reinterpret_cast<char*>(output) -
165 reinterpret_cast<char*>(list_entry);
166 }
167
168 DCHECK_EQ(reinterpret_cast<size_t>(output), reinterpret_cast<size_t>(end));
169 return output <= end;
170 }
171
172 bool GetHandleName(HANDLE handle, base::string16* handle_name) {
173 static NtQueryObject QueryObject = NULL;
174 if (!QueryObject)
175 ResolveNTFunctionPtr("NtQueryObject", &QueryObject);
176
177 ULONG size = MAX_PATH;
178 scoped_ptr<UNICODE_STRING, base::FreeDeleter> name;
179 NTSTATUS result;
180
181 do {
182 name.reset(static_cast<UNICODE_STRING*>(malloc(size)));
183 DCHECK(name.get());
184 result = QueryObject(handle, ObjectNameInformation, name.get(),
185 size, &size);
186 } while (result == STATUS_INFO_LENGTH_MISMATCH ||
187 result == STATUS_BUFFER_OVERFLOW);
188
189 if (NT_SUCCESS(result) && name->Buffer && name->Length)
190 handle_name->assign(name->Buffer, name->Length / sizeof(wchar_t));
191 else
192 handle_name->clear();
193
194 return NT_SUCCESS(result);
195 }
196
197 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/win/src/handle_closer.h ('k') | sandbox/win/src/handle_closer_agent.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698