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

Side by Side Diff: chrome/browser/nacl_host/nacl_process_host.cc

Issue 2832093: NaCl: Allow setting up multiple sockets for subprocess instead of just one (Closed) Base URL: git://codf21.jail/chromium.git
Patch Set: Whitespace fixes Created 10 years, 4 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
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "build/build_config.h" 5 #include "build/build_config.h"
6 6
7 #include "chrome/browser/nacl_host/nacl_process_host.h" 7 #include "chrome/browser/nacl_host/nacl_process_host.h"
8 8
9 #if defined(OS_POSIX) 9 #if defined(OS_POSIX)
10 #include <fcntl.h> 10 #include <fcntl.h>
11 #endif 11 #endif
12 12
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "chrome/browser/renderer_host/resource_message_filter.h" 14 #include "chrome/browser/renderer_host/resource_message_filter.h"
15 #include "chrome/common/chrome_switches.h" 15 #include "chrome/common/chrome_switches.h"
16 #include "chrome/common/logging_chrome.h" 16 #include "chrome/common/logging_chrome.h"
17 #include "chrome/common/nacl_cmd_line.h" 17 #include "chrome/common/nacl_cmd_line.h"
18 #include "chrome/common/nacl_messages.h" 18 #include "chrome/common/nacl_messages.h"
19 #include "chrome/common/render_messages.h" 19 #include "chrome/common/render_messages.h"
20 #include "ipc/ipc_switches.h" 20 #include "ipc/ipc_switches.h"
21 21
22 #if defined(OS_POSIX) 22 #if defined(OS_POSIX)
23 #include "ipc/ipc_channel_posix.h" 23 #include "ipc/ipc_channel_posix.h"
24 #elif defined(OS_WIN) 24 #elif defined(OS_WIN)
25 #include "chrome/browser/nacl_host/nacl_broker_service_win.h" 25 #include "chrome/browser/nacl_host/nacl_broker_service_win.h"
26 #endif 26 #endif
27 27
28 namespace {
29
30 void SetCloseOnExec(nacl::Handle fd) {
31 #if defined(OS_POSIX)
32 int flags = fcntl(fd, F_GETFD);
33 CHECK(flags != -1);
34 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
35 CHECK(rc == 0);
36 #endif
37 }
38
39 } // namespace
40
28 NaClProcessHost::NaClProcessHost( 41 NaClProcessHost::NaClProcessHost(
29 ResourceDispatcherHost *resource_dispatcher_host, 42 ResourceDispatcherHost *resource_dispatcher_host,
30 const std::wstring& url) 43 const std::wstring& url)
31 : BrowserChildProcessHost(NACL_LOADER_PROCESS, resource_dispatcher_host), 44 : BrowserChildProcessHost(NACL_LOADER_PROCESS, resource_dispatcher_host),
32 resource_dispatcher_host_(resource_dispatcher_host), 45 resource_dispatcher_host_(resource_dispatcher_host),
33 reply_msg_(NULL), 46 reply_msg_(NULL),
34 descriptor_(0),
35 running_on_wow64_(false) { 47 running_on_wow64_(false) {
36 set_name(url); 48 set_name(url);
37 #if defined(OS_WIN) 49 #if defined(OS_WIN)
38 CheckIsWow64(); 50 CheckIsWow64();
39 #endif 51 #endif
40 } 52 }
41 53
42 NaClProcessHost::~NaClProcessHost() { 54 NaClProcessHost::~NaClProcessHost() {
43 if (!reply_msg_) 55 if (!reply_msg_)
44 return; 56 return;
45 57
58 for (size_t i = 0; i < sockets_for_renderer_.size(); i++) {
59 nacl::Close(sockets_for_renderer_[i]);
60 }
61 for (size_t i = 0; i < sockets_for_sel_ldr_.size(); i++) {
62 nacl::Close(sockets_for_sel_ldr_[i]);
63 }
64
46 // OnProcessLaunched didn't get called because the process couldn't launch. 65 // OnProcessLaunched didn't get called because the process couldn't launch.
47 // Don't keep the renderer hanging. 66 // Don't keep the renderer hanging.
48 reply_msg_->set_reply_error(); 67 reply_msg_->set_reply_error();
49 resource_message_filter_->Send(reply_msg_); 68 resource_message_filter_->Send(reply_msg_);
50 } 69 }
51 70
52 bool NaClProcessHost::Launch(ResourceMessageFilter* resource_message_filter, 71 bool NaClProcessHost::Launch(ResourceMessageFilter* resource_message_filter,
53 const int descriptor, 72 int socket_count,
54 IPC::Message* reply_msg) { 73 IPC::Message* reply_msg) {
55 #ifdef DISABLE_NACL 74 #ifdef DISABLE_NACL
56 NOTIMPLEMENTED() << "Native Client disabled at build time"; 75 NOTIMPLEMENTED() << "Native Client disabled at build time";
57 return false; 76 return false;
58 #else 77 #else
59 // Create a connected socket 78 // Place an arbitrary limit on the number of sockets to limit
60 if (nacl::SocketPair(pair_) == -1) 79 // exposure in case the renderer is compromised. We can increase
61 return false; 80 // this if necessary.
62 81 if (socket_count > 8) {
63 // Launch the process
64 descriptor_ = descriptor;
65 if (!LaunchSelLdr()) {
66 nacl::Close(pair_[0]);
67 return false; 82 return false;
68 } 83 }
69 84
85 // Rather than creating a socket pair in the renderer, and passing
86 // one side through the browser to sel_ldr, socket pairs are created
87 // in the browser and then passed to the renderer and sel_ldr.
88 //
89 // This is mainly for the benefit of Windows, where sockets cannot
90 // be passed in messages, but are copied via DuplicateHandle().
91 // This means the sandboxed renderer cannot send handles to the
92 // browser process.
93
94 for (int i = 0; i < socket_count; i++) {
95 nacl::Handle pair[2];
96 // Create a connected socket
97 if (nacl::SocketPair(pair) == -1)
98 return false;
99 sockets_for_renderer_.push_back(pair[0]);
100 sockets_for_sel_ldr_.push_back(pair[1]);
101 SetCloseOnExec(pair[0]);
102 SetCloseOnExec(pair[1]);
103 }
104
105 // Launch the process
106 if (!LaunchSelLdr()) {
107 return false;
108 }
109
70 resource_message_filter_ = resource_message_filter; 110 resource_message_filter_ = resource_message_filter;
71 reply_msg_ = reply_msg; 111 reply_msg_ = reply_msg;
72 112
73 return true; 113 return true;
74 #endif // DISABLE_NACL 114 #endif // DISABLE_NACL
75 } 115 }
76 116
77 bool NaClProcessHost::LaunchSelLdr() { 117 bool NaClProcessHost::LaunchSelLdr() {
78 if (!CreateChannel()) 118 if (!CreateChannel())
79 return false; 119 return false;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 } 162 }
123 163
124 void NaClProcessHost::OnChildDied() { 164 void NaClProcessHost::OnChildDied() {
125 #if defined(OS_WIN) 165 #if defined(OS_WIN)
126 NaClBrokerService::GetInstance()->OnLoaderDied(); 166 NaClBrokerService::GetInstance()->OnLoaderDied();
127 #endif 167 #endif
128 BrowserChildProcessHost::OnChildDied(); 168 BrowserChildProcessHost::OnChildDied();
129 } 169 }
130 170
131 void NaClProcessHost::OnProcessLaunched() { 171 void NaClProcessHost::OnProcessLaunched() {
132 nacl::FileDescriptor imc_handle; 172 std::vector<nacl::FileDescriptor> handles_for_renderer;
133 base::ProcessHandle nacl_process_handle; 173 base::ProcessHandle nacl_process_handle;
174
175 for (size_t i = 0; i < sockets_for_renderer_.size(); i++) {
134 #if defined(OS_WIN) 176 #if defined(OS_WIN)
135 // Duplicate the IMC handle 177 // Copy the handle into the renderer process.
136 // We assume the size of imc_handle has the same size as HANDLE, so the cast 178 HANDLE handle_in_renderer;
137 // below is safe. 179 DuplicateHandle(base::GetCurrentProcessHandle(),
138 DCHECK(sizeof(HANDLE) == sizeof(imc_handle)); 180 reinterpret_cast<HANDLE>(sockets_for_renderer_[i]),
139 DuplicateHandle(base::GetCurrentProcessHandle(), 181 resource_message_filter_->handle(),
140 reinterpret_cast<HANDLE>(pair_[0]), 182 &handle_in_renderer,
141 resource_message_filter_->handle(), 183 GENERIC_READ | GENERIC_WRITE,
142 reinterpret_cast<HANDLE*>(&imc_handle), 184 FALSE,
143 GENERIC_READ | GENERIC_WRITE, 185 DUPLICATE_CLOSE_SOURCE);
144 FALSE, 186 handles_for_renderer.push_back(
145 DUPLICATE_CLOSE_SOURCE); 187 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer));
188 #else
189 // No need to dup the imc_handle - we don't pass it anywhere else so
190 // it cannot be closed.
191 nacl::FileDescriptor imc_handle;
192 imc_handle.fd = sockets_for_renderer_[i];
193 imc_handle.auto_close = true;
194 handles_for_renderer.push_back(imc_handle);
195 #endif
196 }
146 197
147 // Duplicate the process handle 198 #if defined(OS_WIN)
199 // Copy the process handle into the renderer process.
148 DuplicateHandle(base::GetCurrentProcessHandle(), 200 DuplicateHandle(base::GetCurrentProcessHandle(),
149 handle(), 201 handle(),
150 resource_message_filter_->handle(), 202 resource_message_filter_->handle(),
151 &nacl_process_handle, 203 &nacl_process_handle,
152 PROCESS_DUP_HANDLE, 204 PROCESS_DUP_HANDLE,
153 FALSE, 205 FALSE,
154 0); 206 0);
155 #else 207 #else
156 int flags = fcntl(pair_[0], F_GETFD);
157 if (flags != -1) {
158 flags |= FD_CLOEXEC;
159 fcntl(pair_[0], F_SETFD, flags);
160 }
161 // No need to dup the imc_handle - we don't pass it anywhere else so
162 // it cannot be closed.
163 imc_handle.fd = pair_[0];
164 imc_handle.auto_close = true;
165
166 // We use pid as process handle on Posix 208 // We use pid as process handle on Posix
167 nacl_process_handle = handle(); 209 nacl_process_handle = handle();
168 #endif 210 #endif
169 211
170 // Get the pid of the NaCl process 212 // Get the pid of the NaCl process
171 base::ProcessId nacl_process_id = base::GetProcId(handle()); 213 base::ProcessId nacl_process_id = base::GetProcId(handle());
172 214
173 ViewHostMsg_LaunchNaCl::WriteReplyParams( 215 ViewHostMsg_LaunchNaCl::WriteReplyParams(
174 reply_msg_, imc_handle, nacl_process_handle, nacl_process_id); 216 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id);
175 resource_message_filter_->Send(reply_msg_); 217 resource_message_filter_->Send(reply_msg_);
176 resource_message_filter_ = NULL; 218 resource_message_filter_ = NULL;
177 reply_msg_ = NULL; 219 reply_msg_ = NULL;
220 sockets_for_renderer_.clear();
178 221
179 SendStartMessage(); 222 SendStartMessage();
180 } 223 }
181 224
182 void NaClProcessHost::SendStartMessage() { 225 void NaClProcessHost::SendStartMessage() {
183 nacl::FileDescriptor channel; 226 std::vector<nacl::FileDescriptor> handles_for_sel_ldr;
227 for (size_t i = 0; i < sockets_for_sel_ldr_.size(); i++) {
184 #if defined(OS_WIN) 228 #if defined(OS_WIN)
185 if (!DuplicateHandle(GetCurrentProcess(), 229 HANDLE channel;
186 reinterpret_cast<HANDLE>(pair_[1]), 230 if (!DuplicateHandle(GetCurrentProcess(),
187 handle(), 231 reinterpret_cast<HANDLE>(sockets_for_sel_ldr_[i]),
188 reinterpret_cast<HANDLE*>(&channel), 232 handle(),
189 GENERIC_READ | GENERIC_WRITE, 233 &channel,
190 FALSE, DUPLICATE_CLOSE_SOURCE)) { 234 GENERIC_READ | GENERIC_WRITE,
191 return; 235 FALSE, DUPLICATE_CLOSE_SOURCE)) {
236 return;
237 }
238 handles_for_sel_ldr.push_back(
239 reinterpret_cast<nacl::FileDescriptor>(channel));
240 #else
241 nacl::FileDescriptor channel;
242 channel.fd = dup(sockets_for_sel_ldr_[i]);
243 channel.auto_close = true;
244 handles_for_sel_ldr.push_back(channel);
245 #endif
192 } 246 }
193 #else 247
194 channel.fd = dup(pair_[1]); 248 Send(new NaClProcessMsg_Start(handles_for_sel_ldr));
195 channel.auto_close = true; 249 sockets_for_sel_ldr_.clear();
196 #endif
197 Send(new NaClProcessMsg_Start(descriptor_, channel));
198 } 250 }
199 251
200 void NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { 252 void NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
201 NOTREACHED() << "Invalid message with type = " << msg.type(); 253 NOTREACHED() << "Invalid message with type = " << msg.type();
202 } 254 }
203 255
204 URLRequestContext* NaClProcessHost::GetRequestContext( 256 URLRequestContext* NaClProcessHost::GetRequestContext(
205 uint32 request_id, 257 uint32 request_id,
206 const ViewHostMsg_Resource_Request& request_data) { 258 const ViewHostMsg_Resource_Request& request_data) {
207 return NULL; 259 return NULL;
(...skipping 12 matching lines...) Expand all
220 if (fnIsWow64Process != NULL) { 272 if (fnIsWow64Process != NULL) {
221 BOOL bIsWow64 = FALSE; 273 BOOL bIsWow64 = FALSE;
222 if (fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) { 274 if (fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) {
223 if (bIsWow64) { 275 if (bIsWow64) {
224 running_on_wow64_ = true; 276 running_on_wow64_ = true;
225 } 277 }
226 } 278 }
227 } 279 }
228 } 280 }
229 #endif 281 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698