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

Side by Side Diff: ipc/ipc_channel_posix.cc

Issue 6596093: Add some bullet proofing to ipc_channel_posix. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/ipc
Patch Set: replace NOTREACHED with LOG(ERROR) Created 9 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 | Annotate | Revision Log
« no previous file with comments | « ipc/ipc_channel_posix.h ('k') | ipc/ipc_channel_posix_unittest.cc » ('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) 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 "ipc/ipc_channel_posix.h" 5 #include "ipc/ipc_channel_posix.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <stddef.h> 9 #include <stddef.h>
10 #include <sys/types.h> 10 #include <sys/types.h>
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 366
367 // Four possible cases: 367 // Four possible cases:
368 // 1) It's a channel wrapping a pipe that is given to us. 368 // 1) It's a channel wrapping a pipe that is given to us.
369 // 2) It's for a named channel, so we create it. 369 // 2) It's for a named channel, so we create it.
370 // 3) It's for a client that we implement ourself. This is used 370 // 3) It's for a client that we implement ourself. This is used
371 // in unittesting. 371 // in unittesting.
372 // 4) It's the initial IPC channel: 372 // 4) It's the initial IPC channel:
373 // 4a) Client side: Pull the pipe out of the GlobalDescriptors set. 373 // 4a) Client side: Pull the pipe out of the GlobalDescriptors set.
374 // 4b) Server side: create the pipe. 374 // 4b) Server side: create the pipe.
375 375
376 int local_pipe = -1;
376 if (channel_handle.socket.fd != -1) { 377 if (channel_handle.socket.fd != -1) {
377 // Case 1 from comment above. 378 // Case 1 from comment above.
378 pipe_ = channel_handle.socket.fd; 379 local_pipe = channel_handle.socket.fd;
379 #if defined(IPC_USES_READWRITE) 380 #if defined(IPC_USES_READWRITE)
380 // Test the socket passed into us to make sure it is nonblocking. 381 // Test the socket passed into us to make sure it is nonblocking.
381 // We don't want to call read/write on a blocking socket. 382 // We don't want to call read/write on a blocking socket.
382 int value = fcntl(pipe_, F_GETFL); 383 int value = fcntl(local_pipe, F_GETFL);
383 if (value == -1) { 384 if (value == -1) {
384 PLOG(ERROR) << "fcntl(F_GETFL) " << pipe_name_; 385 PLOG(ERROR) << "fcntl(F_GETFL) " << pipe_name_;
385 return false; 386 return false;
386 } 387 }
387 if (!(value & O_NONBLOCK)) { 388 if (!(value & O_NONBLOCK)) {
388 LOG(ERROR) << "Socket " << pipe_name_ << " must be O_NONBLOCK"; 389 LOG(ERROR) << "Socket " << pipe_name_ << " must be O_NONBLOCK";
389 return false; 390 return false;
390 } 391 }
391 #endif // IPC_USES_READWRITE 392 #endif // IPC_USES_READWRITE
392 } else if (mode_ & MODE_NAMED_FLAG) { 393 } else if (mode_ & MODE_NAMED_FLAG) {
393 // Case 2 from comment above. 394 // Case 2 from comment above.
394 if (mode_ & MODE_SERVER_FLAG) { 395 if (mode_ & MODE_SERVER_FLAG) {
395 if (!CreateServerUnixDomainSocket(pipe_name_, &pipe_)) { 396 if (!CreateServerUnixDomainSocket(pipe_name_, &local_pipe)) {
396 return false; 397 return false;
397 } 398 }
398 must_unlink_ = true; 399 must_unlink_ = true;
399 } else if (mode_ & MODE_CLIENT_FLAG) { 400 } else if (mode_ & MODE_CLIENT_FLAG) {
400 if (!CreateClientUnixDomainSocket(pipe_name_, &pipe_)) { 401 if (!CreateClientUnixDomainSocket(pipe_name_, &local_pipe)) {
401 return false; 402 return false;
402 } 403 }
403 } else { 404 } else {
404 NOTREACHED(); 405 LOG(ERROR) << "Bad mode: " << mode_;
jeremy 2011/03/02 19:05:45 Why did you changed the NOTREACHED()'s to LOG(ERRO
405 return false; 406 return false;
406 } 407 }
407 } else { 408 } else {
408 pipe_ = PipeMap::GetInstance()->Lookup(pipe_name_); 409 local_pipe = PipeMap::GetInstance()->Lookup(pipe_name_);
409 if (mode_ & MODE_CLIENT_FLAG) { 410 if (mode_ & MODE_CLIENT_FLAG) {
410 if (pipe_ != -1) { 411 if (local_pipe != -1) {
411 // Case 3 from comment above. 412 // Case 3 from comment above.
412 // We only allow one connection. 413 // We only allow one connection.
413 pipe_ = HANDLE_EINTR(dup(pipe_)); 414 local_pipe = HANDLE_EINTR(dup(local_pipe));
414 PipeMap::GetInstance()->RemoveAndClose(pipe_name_); 415 PipeMap::GetInstance()->RemoveAndClose(pipe_name_);
415 } else { 416 } else {
416 // Case 4a from comment above. 417 // Case 4a from comment above.
417 // Guard against inappropriate reuse of the initial IPC channel. If 418 // Guard against inappropriate reuse of the initial IPC channel. If
418 // an IPC channel closes and someone attempts to reuse it by name, the 419 // an IPC channel closes and someone attempts to reuse it by name, the
419 // initial channel must not be recycled here. http://crbug.com/26754. 420 // initial channel must not be recycled here. http://crbug.com/26754.
420 static bool used_initial_channel = false; 421 static bool used_initial_channel = false;
421 if (used_initial_channel) { 422 if (used_initial_channel) {
422 LOG(FATAL) << "Denying attempt to reuse initial IPC channel for " 423 LOG(FATAL) << "Denying attempt to reuse initial IPC channel for "
423 << pipe_name_; 424 << pipe_name_;
424 return false; 425 return false;
425 } 426 }
426 used_initial_channel = true; 427 used_initial_channel = true;
427 428
428 pipe_ = base::GlobalDescriptors::GetInstance()->Get(kPrimaryIPCChannel); 429 local_pipe =
430 base::GlobalDescriptors::GetInstance()->Get(kPrimaryIPCChannel);
429 } 431 }
430 } else if (mode_ & MODE_SERVER_FLAG) { 432 } else if (mode_ & MODE_SERVER_FLAG) {
431 // Case 4b from comment above. 433 // Case 4b from comment above.
432 if (pipe_ != -1) { 434 if (local_pipe != -1) {
433 LOG(ERROR) << "Server already exists for " << pipe_name_; 435 LOG(ERROR) << "Server already exists for " << pipe_name_;
434 return false; 436 return false;
435 } 437 }
436 if (!SocketPair(&pipe_, &client_pipe_)) 438 if (!SocketPair(&local_pipe, &client_pipe_))
437 return false; 439 return false;
438 PipeMap::GetInstance()->Insert(pipe_name_, client_pipe_); 440 PipeMap::GetInstance()->Insert(pipe_name_, client_pipe_);
439 } else { 441 } else {
440 NOTREACHED(); 442 LOG(ERROR) << "Bad mode: " << mode_;
441 return false; 443 return false;
442 } 444 }
443 } 445 }
444 446
445 if ((mode_ & MODE_SERVER_FLAG) && (mode_ & MODE_NAMED_FLAG)) {
446 server_listen_pipe_ = pipe_;
447 pipe_ = -1;
448 }
449
450 #if defined(IPC_USES_READWRITE) 447 #if defined(IPC_USES_READWRITE)
451 // Create a dedicated socketpair() for exchanging file descriptors. 448 // Create a dedicated socketpair() for exchanging file descriptors.
452 // See comments for IPC_USES_READWRITE for details. 449 // See comments for IPC_USES_READWRITE for details.
453 if (mode_ & MODE_CLIENT_FLAG) { 450 if (mode_ & MODE_CLIENT_FLAG) {
454 if (!SocketPair(&fd_pipe_, &remote_fd_pipe_)) { 451 if (!SocketPair(&fd_pipe_, &remote_fd_pipe_)) {
455 return false; 452 return false;
456 } 453 }
457 } 454 }
458 #endif // IPC_USES_READWRITE 455 #endif // IPC_USES_READWRITE
459 456
457 if ((mode_ & MODE_SERVER_FLAG) && (mode_ & MODE_NAMED_FLAG)) {
458 server_listen_pipe_ = local_pipe;
459 local_pipe = -1;
460 }
461
462 pipe_ = local_pipe;
460 return true; 463 return true;
461 } 464 }
462 465
463 bool Channel::ChannelImpl::Connect() { 466 bool Channel::ChannelImpl::Connect() {
464 if (server_listen_pipe_ == -1 && pipe_ == -1) { 467 if (server_listen_pipe_ == -1 && pipe_ == -1) {
465 DLOG(INFO) << "Must call create on a channel before calling connect"; 468 DLOG(INFO) << "Channel creation failed: " << pipe_name_;
466 return false; 469 return false;
467 } 470 }
468 471
469 bool did_connect = true; 472 bool did_connect = true;
470 if (server_listen_pipe_ != -1) { 473 if (server_listen_pipe_ != -1) {
471 // Watch the pipe for connections, and turn any connections into 474 // Watch the pipe for connections, and turn any connections into
472 // active sockets. 475 // active sockets.
473 MessageLoopForIO::current()->WatchFileDescriptor( 476 MessageLoopForIO::current()->WatchFileDescriptor(
474 server_listen_pipe_, 477 server_listen_pipe_,
475 true, 478 true,
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 1159
1157 bool Channel::HasAcceptedConnection() const { 1160 bool Channel::HasAcceptedConnection() const {
1158 return channel_impl_->HasAcceptedConnection(); 1161 return channel_impl_->HasAcceptedConnection();
1159 } 1162 }
1160 1163
1161 void Channel::ResetToAcceptingConnectionState() { 1164 void Channel::ResetToAcceptingConnectionState() {
1162 channel_impl_->ResetToAcceptingConnectionState(); 1165 channel_impl_->ResetToAcceptingConnectionState();
1163 } 1166 }
1164 1167
1165 } // namespace IPC 1168 } // namespace IPC
OLDNEW
« no previous file with comments | « ipc/ipc_channel_posix.h ('k') | ipc/ipc_channel_posix_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698