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

Side by Side Diff: ipc/ipc_channel_nacl.cc

Issue 183553004: Eliminate a potential race in IPC::ChannelProxy (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: merge Created 6 years, 9 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 | « ipc/ipc_channel_nacl.h ('k') | ipc/ipc_channel_proxy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ipc/ipc_channel_nacl.h" 5 #include "ipc/ipc_channel_nacl.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <sys/types.h> 9 #include <sys/types.h>
10 10
11 #include <algorithm> 11 #include <algorithm>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/message_loop/message_loop_proxy.h" 15 #include "base/message_loop/message_loop_proxy.h"
16 #include "base/synchronization/lock.h" 16 #include "base/synchronization/lock.h"
17 #include "base/task_runner_util.h" 17 #include "base/task_runner_util.h"
18 #include "base/threading/simple_thread.h" 18 #include "base/threading/simple_thread.h"
19 #include "ipc/file_descriptor_set_posix.h" 19 #include "ipc/file_descriptor_set_posix.h"
20 #include "ipc/ipc_listener.h"
20 #include "ipc/ipc_logging.h" 21 #include "ipc/ipc_logging.h"
21 #include "native_client/src/public/imc_syscalls.h" 22 #include "native_client/src/public/imc_syscalls.h"
22 #include "native_client/src/public/imc_types.h" 23 #include "native_client/src/public/imc_types.h"
23 24
24 namespace IPC { 25 namespace IPC {
25 26
26 struct MessageContents { 27 struct MessageContents {
27 std::vector<char> data; 28 std::vector<char> data;
28 std::vector<int> fds; 29 std::vector<int> fds;
29 }; 30 };
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 const char *modestr = (mode_ & MODE_SERVER_FLAG) ? "server" : "client"; 132 const char *modestr = (mode_ & MODE_SERVER_FLAG) ? "server" : "client";
132 LOG(WARNING) << "Unable to create pipe named \"" << channel_handle.name 133 LOG(WARNING) << "Unable to create pipe named \"" << channel_handle.name
133 << "\" in " << modestr << " mode"; 134 << "\" in " << modestr << " mode";
134 } 135 }
135 } 136 }
136 137
137 Channel::ChannelImpl::~ChannelImpl() { 138 Channel::ChannelImpl::~ChannelImpl() {
138 Close(); 139 Close();
139 } 140 }
140 141
142 base::ProcessId Channel::ChannelImpl::peer_pid() const {
143 // This shouldn't actually get used in the untrusted side of the proxy, and we
144 // don't have the real pid anyway.
145 return -1;
146 }
147
141 bool Channel::ChannelImpl::Connect() { 148 bool Channel::ChannelImpl::Connect() {
142 if (pipe_ == -1) { 149 if (pipe_ == -1) {
143 DLOG(INFO) << "Channel creation failed: " << pipe_name_; 150 DLOG(WARNING) << "Channel creation failed: " << pipe_name_;
144 return false; 151 return false;
145 } 152 }
146 153
147 // Note that Connect is called on the "Channel" thread (i.e., the same thread 154 // Note that Connect is called on the "Channel" thread (i.e., the same thread
148 // where Channel::Send will be called, and the same thread that should receive 155 // where Channel::Send will be called, and the same thread that should receive
149 // messages). The constructor might be invoked on another thread (see 156 // messages). The constructor might be invoked on another thread (see
150 // ChannelProxy for an example of that). Therefore, we must wait until Connect 157 // ChannelProxy for an example of that). Therefore, we must wait until Connect
151 // is called to decide which MessageLoopProxy to pass to ReaderThreadRunner. 158 // is called to decide which MessageLoopProxy to pass to ReaderThreadRunner.
152 reader_thread_runner_.reset( 159 reader_thread_runner_.reset(
153 new ReaderThreadRunner( 160 new ReaderThreadRunner(
154 pipe_, 161 pipe_,
155 base::Bind(&Channel::ChannelImpl::DidRecvMsg, 162 base::Bind(&Channel::ChannelImpl::DidRecvMsg,
156 weak_ptr_factory_.GetWeakPtr()), 163 weak_ptr_factory_.GetWeakPtr()),
157 base::Bind(&Channel::ChannelImpl::ReadDidFail, 164 base::Bind(&Channel::ChannelImpl::ReadDidFail,
158 weak_ptr_factory_.GetWeakPtr()), 165 weak_ptr_factory_.GetWeakPtr()),
159 base::MessageLoopProxy::current())); 166 base::MessageLoopProxy::current()));
160 reader_thread_.reset( 167 reader_thread_.reset(
161 new base::DelegateSimpleThread(reader_thread_runner_.get(), 168 new base::DelegateSimpleThread(reader_thread_runner_.get(),
162 "ipc_channel_nacl reader thread")); 169 "ipc_channel_nacl reader thread"));
163 reader_thread_->Start(); 170 reader_thread_->Start();
164 waiting_connect_ = false; 171 waiting_connect_ = false;
165 // If there were any messages queued before connection, send them. 172 // If there were any messages queued before connection, send them.
166 ProcessOutgoingMessages(); 173 ProcessOutgoingMessages();
174 base::MessageLoopProxy::current()->PostTask(FROM_HERE,
175 base::Bind(&Channel::ChannelImpl::CallOnChannelConnected,
176 weak_ptr_factory_.GetWeakPtr()));
177
167 return true; 178 return true;
168 } 179 }
169 180
170 void Channel::ChannelImpl::Close() { 181 void Channel::ChannelImpl::Close() {
171 // For now, we assume that at shutdown, the reader thread will be woken with 182 // For now, we assume that at shutdown, the reader thread will be woken with
172 // a failure (see NaClIPCAdapter::BlockingRead and CloseChannel). Or... we 183 // a failure (see NaClIPCAdapter::BlockingRead and CloseChannel). Or... we
173 // might simply be killed with no chance to clean up anyway :-). 184 // might simply be killed with no chance to clean up anyway :-).
174 // If untrusted code tries to close the channel prior to shutdown, it's likely 185 // If untrusted code tries to close the channel prior to shutdown, it's likely
175 // to hang. 186 // to hang.
176 // TODO(dmichael): Can we do anything smarter here to make sure the reader 187 // TODO(dmichael): Can we do anything smarter here to make sure the reader
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 msg->file_descriptor_set()->CommitAll(); 297 msg->file_descriptor_set()->CommitAll();
287 } 298 }
288 299
289 // Message sent OK! 300 // Message sent OK!
290 DVLOG(2) << "sent message @" << msg.get() << " with type " << msg->type() 301 DVLOG(2) << "sent message @" << msg.get() << " with type " << msg->type()
291 << " on fd " << pipe_; 302 << " on fd " << pipe_;
292 } 303 }
293 return true; 304 return true;
294 } 305 }
295 306
307 void Channel::ChannelImpl::CallOnChannelConnected() {
308 listener()->OnChannelConnected(peer_pid());
309 }
310
296 Channel::ChannelImpl::ReadState Channel::ChannelImpl::ReadData( 311 Channel::ChannelImpl::ReadState Channel::ChannelImpl::ReadData(
297 char* buffer, 312 char* buffer,
298 int buffer_len, 313 int buffer_len,
299 int* bytes_read) { 314 int* bytes_read) {
300 *bytes_read = 0; 315 *bytes_read = 0;
301 if (pipe_ == -1) 316 if (pipe_ == -1)
302 return READ_FAILED; 317 return READ_FAILED;
303 if (read_queue_.empty()) 318 if (read_queue_.empty())
304 return READ_PENDING; 319 return READ_PENDING;
305 while (!read_queue_.empty() && *bytes_read < buffer_len) { 320 while (!read_queue_.empty() && *bytes_read < buffer_len) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 380
366 bool Channel::Connect() { 381 bool Channel::Connect() {
367 return channel_impl_->Connect(); 382 return channel_impl_->Connect();
368 } 383 }
369 384
370 void Channel::Close() { 385 void Channel::Close() {
371 channel_impl_->Close(); 386 channel_impl_->Close();
372 } 387 }
373 388
374 base::ProcessId Channel::peer_pid() const { 389 base::ProcessId Channel::peer_pid() const {
375 // This shouldn't actually get used in the untrusted side of the proxy, and we 390 return channel_impl_->peer_pid();
376 // don't have the real pid anyway.
377 return -1;
378 } 391 }
379 392
380 bool Channel::Send(Message* message) { 393 bool Channel::Send(Message* message) {
381 return channel_impl_->Send(message); 394 return channel_impl_->Send(message);
382 } 395 }
383 396
384 } // namespace IPC 397 } // namespace IPC
OLDNEW
« no previous file with comments | « ipc/ipc_channel_nacl.h ('k') | ipc/ipc_channel_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698