| OLD | NEW |
| 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_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/socket.h> | 10 #include <sys/socket.h> |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 int pipe_fds[2]; | 199 int pipe_fds[2]; |
| 200 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { | 200 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { |
| 201 PLOG(ERROR) << "socketpair()"; | 201 PLOG(ERROR) << "socketpair()"; |
| 202 return false; | 202 return false; |
| 203 } | 203 } |
| 204 | 204 |
| 205 // Set both ends to be non-blocking. | 205 // Set both ends to be non-blocking. |
| 206 if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 || | 206 if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 || |
| 207 fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) { | 207 fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) { |
| 208 PLOG(ERROR) << "fcntl(O_NONBLOCK)"; | 208 PLOG(ERROR) << "fcntl(O_NONBLOCK)"; |
| 209 if (HANDLE_EINTR(close(pipe_fds[0])) < 0) | 209 if (IGNORE_EINTR(close(pipe_fds[0])) < 0) |
| 210 PLOG(ERROR) << "close"; | 210 PLOG(ERROR) << "close"; |
| 211 if (HANDLE_EINTR(close(pipe_fds[1])) < 0) | 211 if (IGNORE_EINTR(close(pipe_fds[1])) < 0) |
| 212 PLOG(ERROR) << "close"; | 212 PLOG(ERROR) << "close"; |
| 213 return false; | 213 return false; |
| 214 } | 214 } |
| 215 | 215 |
| 216 *fd1 = pipe_fds[0]; | 216 *fd1 = pipe_fds[0]; |
| 217 *fd2 = pipe_fds[1]; | 217 *fd2 = pipe_fds[1]; |
| 218 | 218 |
| 219 return true; | 219 return true; |
| 220 } | 220 } |
| 221 | 221 |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 PipeMap::GetInstance()->Remove(pipe_name_); | 540 PipeMap::GetInstance()->Remove(pipe_name_); |
| 541 client_pipe_ = -1; | 541 client_pipe_ = -1; |
| 542 } | 542 } |
| 543 return fd; | 543 return fd; |
| 544 } | 544 } |
| 545 | 545 |
| 546 void Channel::ChannelImpl::CloseClientFileDescriptor() { | 546 void Channel::ChannelImpl::CloseClientFileDescriptor() { |
| 547 base::AutoLock lock(client_pipe_lock_); | 547 base::AutoLock lock(client_pipe_lock_); |
| 548 if (client_pipe_ != -1) { | 548 if (client_pipe_ != -1) { |
| 549 PipeMap::GetInstance()->Remove(pipe_name_); | 549 PipeMap::GetInstance()->Remove(pipe_name_); |
| 550 if (HANDLE_EINTR(close(client_pipe_)) < 0) | 550 if (IGNORE_EINTR(close(client_pipe_)) < 0) |
| 551 PLOG(ERROR) << "close " << pipe_name_; | 551 PLOG(ERROR) << "close " << pipe_name_; |
| 552 client_pipe_ = -1; | 552 client_pipe_ = -1; |
| 553 } | 553 } |
| 554 } | 554 } |
| 555 | 555 |
| 556 bool Channel::ChannelImpl::AcceptsConnections() const { | 556 bool Channel::ChannelImpl::AcceptsConnections() const { |
| 557 return server_listen_pipe_ != -1; | 557 return server_listen_pipe_ != -1; |
| 558 } | 558 } |
| 559 | 559 |
| 560 bool Channel::ChannelImpl::HasAcceptedConnection() const { | 560 bool Channel::ChannelImpl::HasAcceptedConnection() const { |
| 561 return AcceptsConnections() && pipe_ != -1; | 561 return AcceptsConnections() && pipe_ != -1; |
| 562 } | 562 } |
| 563 | 563 |
| 564 bool Channel::ChannelImpl::GetPeerEuid(uid_t* peer_euid) const { | 564 bool Channel::ChannelImpl::GetPeerEuid(uid_t* peer_euid) const { |
| 565 DCHECK(!(mode_ & MODE_SERVER) || HasAcceptedConnection()); | 565 DCHECK(!(mode_ & MODE_SERVER) || HasAcceptedConnection()); |
| 566 return IPC::GetPeerEuid(pipe_, peer_euid); | 566 return IPC::GetPeerEuid(pipe_, peer_euid); |
| 567 } | 567 } |
| 568 | 568 |
| 569 void Channel::ChannelImpl::ResetToAcceptingConnectionState() { | 569 void Channel::ChannelImpl::ResetToAcceptingConnectionState() { |
| 570 // Unregister libevent for the unix domain socket and close it. | 570 // Unregister libevent for the unix domain socket and close it. |
| 571 read_watcher_.StopWatchingFileDescriptor(); | 571 read_watcher_.StopWatchingFileDescriptor(); |
| 572 write_watcher_.StopWatchingFileDescriptor(); | 572 write_watcher_.StopWatchingFileDescriptor(); |
| 573 if (pipe_ != -1) { | 573 if (pipe_ != -1) { |
| 574 if (HANDLE_EINTR(close(pipe_)) < 0) | 574 if (IGNORE_EINTR(close(pipe_)) < 0) |
| 575 PLOG(ERROR) << "close pipe_ " << pipe_name_; | 575 PLOG(ERROR) << "close pipe_ " << pipe_name_; |
| 576 pipe_ = -1; | 576 pipe_ = -1; |
| 577 } | 577 } |
| 578 #if defined(IPC_USES_READWRITE) | 578 #if defined(IPC_USES_READWRITE) |
| 579 if (fd_pipe_ != -1) { | 579 if (fd_pipe_ != -1) { |
| 580 if (HANDLE_EINTR(close(fd_pipe_)) < 0) | 580 if (IGNORE_EINTR(close(fd_pipe_)) < 0) |
| 581 PLOG(ERROR) << "close fd_pipe_ " << pipe_name_; | 581 PLOG(ERROR) << "close fd_pipe_ " << pipe_name_; |
| 582 fd_pipe_ = -1; | 582 fd_pipe_ = -1; |
| 583 } | 583 } |
| 584 if (remote_fd_pipe_ != -1) { | 584 if (remote_fd_pipe_ != -1) { |
| 585 if (HANDLE_EINTR(close(remote_fd_pipe_)) < 0) | 585 if (IGNORE_EINTR(close(remote_fd_pipe_)) < 0) |
| 586 PLOG(ERROR) << "close remote_fd_pipe_ " << pipe_name_; | 586 PLOG(ERROR) << "close remote_fd_pipe_ " << pipe_name_; |
| 587 remote_fd_pipe_ = -1; | 587 remote_fd_pipe_ = -1; |
| 588 } | 588 } |
| 589 #endif // IPC_USES_READWRITE | 589 #endif // IPC_USES_READWRITE |
| 590 | 590 |
| 591 while (!output_queue_.empty()) { | 591 while (!output_queue_.empty()) { |
| 592 Message* m = output_queue_.front(); | 592 Message* m = output_queue_.front(); |
| 593 output_queue_.pop(); | 593 output_queue_.pop(); |
| 594 delete m; | 594 delete m; |
| 595 } | 595 } |
| 596 | 596 |
| 597 // Close any outstanding, received file descriptors. | 597 // Close any outstanding, received file descriptors. |
| 598 ClearInputFDs(); | 598 ClearInputFDs(); |
| 599 | 599 |
| 600 #if defined(OS_MACOSX) | 600 #if defined(OS_MACOSX) |
| 601 // Clear any outstanding, sent file descriptors. | 601 // Clear any outstanding, sent file descriptors. |
| 602 for (std::set<int>::iterator i = fds_to_close_.begin(); | 602 for (std::set<int>::iterator i = fds_to_close_.begin(); |
| 603 i != fds_to_close_.end(); | 603 i != fds_to_close_.end(); |
| 604 ++i) { | 604 ++i) { |
| 605 if (HANDLE_EINTR(close(*i)) < 0) | 605 if (IGNORE_EINTR(close(*i)) < 0) |
| 606 PLOG(ERROR) << "close"; | 606 PLOG(ERROR) << "close"; |
| 607 } | 607 } |
| 608 fds_to_close_.clear(); | 608 fds_to_close_.clear(); |
| 609 #endif | 609 #endif |
| 610 } | 610 } |
| 611 | 611 |
| 612 // static | 612 // static |
| 613 bool Channel::ChannelImpl::IsNamedServerInitialized( | 613 bool Channel::ChannelImpl::IsNamedServerInitialized( |
| 614 const std::string& channel_id) { | 614 const std::string& channel_id) { |
| 615 return base::PathExists(base::FilePath(channel_id)); | 615 return base::PathExists(base::FilePath(channel_id)); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 630 new_pipe < 0) { | 630 new_pipe < 0) { |
| 631 Close(); | 631 Close(); |
| 632 listener()->OnChannelListenError(); | 632 listener()->OnChannelListenError(); |
| 633 } | 633 } |
| 634 | 634 |
| 635 if (pipe_ != -1) { | 635 if (pipe_ != -1) { |
| 636 // We already have a connection. We only handle one at a time. | 636 // We already have a connection. We only handle one at a time. |
| 637 // close our new descriptor. | 637 // close our new descriptor. |
| 638 if (HANDLE_EINTR(shutdown(new_pipe, SHUT_RDWR)) < 0) | 638 if (HANDLE_EINTR(shutdown(new_pipe, SHUT_RDWR)) < 0) |
| 639 DPLOG(ERROR) << "shutdown " << pipe_name_; | 639 DPLOG(ERROR) << "shutdown " << pipe_name_; |
| 640 if (HANDLE_EINTR(close(new_pipe)) < 0) | 640 if (IGNORE_EINTR(close(new_pipe)) < 0) |
| 641 DPLOG(ERROR) << "close " << pipe_name_; | 641 DPLOG(ERROR) << "close " << pipe_name_; |
| 642 listener()->OnChannelDenied(); | 642 listener()->OnChannelDenied(); |
| 643 return; | 643 return; |
| 644 } | 644 } |
| 645 pipe_ = new_pipe; | 645 pipe_ = new_pipe; |
| 646 | 646 |
| 647 if ((mode_ & MODE_OPEN_ACCESS_FLAG) == 0) { | 647 if ((mode_ & MODE_OPEN_ACCESS_FLAG) == 0) { |
| 648 // Verify that the IPC channel peer is running as the same user. | 648 // Verify that the IPC channel peer is running as the same user. |
| 649 uid_t client_euid; | 649 uid_t client_euid; |
| 650 if (!GetPeerEuid(&client_euid)) { | 650 if (!GetPeerEuid(&client_euid)) { |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 return true; | 920 return true; |
| 921 } | 921 } |
| 922 } | 922 } |
| 923 | 923 |
| 924 // No file descriptors found, but that's OK. | 924 // No file descriptors found, but that's OK. |
| 925 return true; | 925 return true; |
| 926 } | 926 } |
| 927 | 927 |
| 928 void Channel::ChannelImpl::ClearInputFDs() { | 928 void Channel::ChannelImpl::ClearInputFDs() { |
| 929 for (size_t i = 0; i < input_fds_.size(); ++i) { | 929 for (size_t i = 0; i < input_fds_.size(); ++i) { |
| 930 if (HANDLE_EINTR(close(input_fds_[i])) < 0) | 930 if (IGNORE_EINTR(close(input_fds_[i])) < 0) |
| 931 PLOG(ERROR) << "close "; | 931 PLOG(ERROR) << "close "; |
| 932 } | 932 } |
| 933 input_fds_.clear(); | 933 input_fds_.clear(); |
| 934 } | 934 } |
| 935 | 935 |
| 936 void Channel::ChannelImpl::QueueCloseFDMessage(int fd, int hops) { | 936 void Channel::ChannelImpl::QueueCloseFDMessage(int fd, int hops) { |
| 937 switch (hops) { | 937 switch (hops) { |
| 938 case 1: | 938 case 1: |
| 939 case 2: { | 939 case 2: { |
| 940 // Create the message | 940 // Create the message |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 | 989 |
| 990 #if defined(OS_MACOSX) | 990 #if defined(OS_MACOSX) |
| 991 case Channel::CLOSE_FD_MESSAGE_TYPE: | 991 case Channel::CLOSE_FD_MESSAGE_TYPE: |
| 992 int fd, hops; | 992 int fd, hops; |
| 993 if (!msg.ReadInt(&iter, &hops)) | 993 if (!msg.ReadInt(&iter, &hops)) |
| 994 NOTREACHED(); | 994 NOTREACHED(); |
| 995 if (!msg.ReadInt(&iter, &fd)) | 995 if (!msg.ReadInt(&iter, &fd)) |
| 996 NOTREACHED(); | 996 NOTREACHED(); |
| 997 if (hops == 0) { | 997 if (hops == 0) { |
| 998 if (fds_to_close_.erase(fd) > 0) { | 998 if (fds_to_close_.erase(fd) > 0) { |
| 999 if (HANDLE_EINTR(close(fd)) < 0) | 999 if (IGNORE_EINTR(close(fd)) < 0) |
| 1000 PLOG(ERROR) << "close"; | 1000 PLOG(ERROR) << "close"; |
| 1001 } else { | 1001 } else { |
| 1002 NOTREACHED(); | 1002 NOTREACHED(); |
| 1003 } | 1003 } |
| 1004 } else { | 1004 } else { |
| 1005 QueueCloseFDMessage(fd, hops); | 1005 QueueCloseFDMessage(fd, hops); |
| 1006 } | 1006 } |
| 1007 break; | 1007 break; |
| 1008 #endif | 1008 #endif |
| 1009 } | 1009 } |
| 1010 } | 1010 } |
| 1011 | 1011 |
| 1012 void Channel::ChannelImpl::Close() { | 1012 void Channel::ChannelImpl::Close() { |
| 1013 // Close can be called multiple time, so we need to make sure we're | 1013 // Close can be called multiple time, so we need to make sure we're |
| 1014 // idempotent. | 1014 // idempotent. |
| 1015 | 1015 |
| 1016 ResetToAcceptingConnectionState(); | 1016 ResetToAcceptingConnectionState(); |
| 1017 | 1017 |
| 1018 if (must_unlink_) { | 1018 if (must_unlink_) { |
| 1019 unlink(pipe_name_.c_str()); | 1019 unlink(pipe_name_.c_str()); |
| 1020 must_unlink_ = false; | 1020 must_unlink_ = false; |
| 1021 } | 1021 } |
| 1022 if (server_listen_pipe_ != -1) { | 1022 if (server_listen_pipe_ != -1) { |
| 1023 if (HANDLE_EINTR(close(server_listen_pipe_)) < 0) | 1023 if (IGNORE_EINTR(close(server_listen_pipe_)) < 0) |
| 1024 DPLOG(ERROR) << "close " << server_listen_pipe_; | 1024 DPLOG(ERROR) << "close " << server_listen_pipe_; |
| 1025 server_listen_pipe_ = -1; | 1025 server_listen_pipe_ = -1; |
| 1026 // Unregister libevent for the listening socket and close it. | 1026 // Unregister libevent for the listening socket and close it. |
| 1027 server_listen_connection_watcher_.StopWatchingFileDescriptor(); | 1027 server_listen_connection_watcher_.StopWatchingFileDescriptor(); |
| 1028 } | 1028 } |
| 1029 | 1029 |
| 1030 CloseClientFileDescriptor(); | 1030 CloseClientFileDescriptor(); |
| 1031 } | 1031 } |
| 1032 | 1032 |
| 1033 //------------------------------------------------------------------------------ | 1033 //------------------------------------------------------------------------------ |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1101 | 1101 |
| 1102 | 1102 |
| 1103 #if defined(OS_LINUX) | 1103 #if defined(OS_LINUX) |
| 1104 // static | 1104 // static |
| 1105 void Channel::SetGlobalPid(int pid) { | 1105 void Channel::SetGlobalPid(int pid) { |
| 1106 ChannelImpl::SetGlobalPid(pid); | 1106 ChannelImpl::SetGlobalPid(pid); |
| 1107 } | 1107 } |
| 1108 #endif // OS_LINUX | 1108 #endif // OS_LINUX |
| 1109 | 1109 |
| 1110 } // namespace IPC | 1110 } // namespace IPC |
| OLD | NEW |