| 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/types.h> | 10 #include <sys/types.h> |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 | 293 |
| 294 } // namespace | 294 } // namespace |
| 295 //------------------------------------------------------------------------------ | 295 //------------------------------------------------------------------------------ |
| 296 | 296 |
| 297 #if defined(OS_LINUX) | 297 #if defined(OS_LINUX) |
| 298 int Channel::ChannelImpl::global_pid_ = 0; | 298 int Channel::ChannelImpl::global_pid_ = 0; |
| 299 #endif // OS_LINUX | 299 #endif // OS_LINUX |
| 300 | 300 |
| 301 Channel::ChannelImpl::ChannelImpl(const IPC::ChannelHandle& channel_handle, | 301 Channel::ChannelImpl::ChannelImpl(const IPC::ChannelHandle& channel_handle, |
| 302 Mode mode, Listener* listener) | 302 Mode mode, Listener* listener) |
| 303 : mode_(mode), | 303 : ChannelReader(listener), |
| 304 mode_(mode), |
| 304 is_blocked_on_write_(false), | 305 is_blocked_on_write_(false), |
| 305 waiting_connect_(true), | 306 waiting_connect_(true), |
| 306 message_send_bytes_written_(0), | 307 message_send_bytes_written_(0), |
| 307 server_listen_pipe_(-1), | 308 server_listen_pipe_(-1), |
| 308 pipe_(-1), | 309 pipe_(-1), |
| 309 client_pipe_(-1), | 310 client_pipe_(-1), |
| 310 #if defined(IPC_USES_READWRITE) | 311 #if defined(IPC_USES_READWRITE) |
| 311 fd_pipe_(-1), | 312 fd_pipe_(-1), |
| 312 remote_fd_pipe_(-1), | 313 remote_fd_pipe_(-1), |
| 313 #endif // IPC_USES_READWRITE | 314 #endif // IPC_USES_READWRITE |
| 314 pipe_name_(channel_handle.name), | 315 pipe_name_(channel_handle.name), |
| 315 listener_(listener), | |
| 316 must_unlink_(false) { | 316 must_unlink_(false) { |
| 317 memset(input_buf_, 0, sizeof(input_buf_)); | |
| 318 memset(input_cmsg_buf_, 0, sizeof(input_cmsg_buf_)); | 317 memset(input_cmsg_buf_, 0, sizeof(input_cmsg_buf_)); |
| 319 if (!CreatePipe(channel_handle)) { | 318 if (!CreatePipe(channel_handle)) { |
| 320 // The pipe may have been closed already. | 319 // The pipe may have been closed already. |
| 321 const char *modestr = (mode_ & MODE_SERVER_FLAG) ? "server" : "client"; | 320 const char *modestr = (mode_ & MODE_SERVER_FLAG) ? "server" : "client"; |
| 322 LOG(WARNING) << "Unable to create pipe named \"" << channel_handle.name | 321 LOG(WARNING) << "Unable to create pipe named \"" << channel_handle.name |
| 323 << "\" in " << modestr << " mode"; | 322 << "\" in " << modestr << " mode"; |
| 324 } | 323 } |
| 325 } | 324 } |
| 326 | 325 |
| 327 Channel::ChannelImpl::~ChannelImpl() { | 326 Channel::ChannelImpl::~ChannelImpl() { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 true, | 470 true, |
| 472 MessageLoopForIO::WATCH_READ, | 471 MessageLoopForIO::WATCH_READ, |
| 473 &server_listen_connection_watcher_, | 472 &server_listen_connection_watcher_, |
| 474 this); | 473 this); |
| 475 } else { | 474 } else { |
| 476 did_connect = AcceptConnection(); | 475 did_connect = AcceptConnection(); |
| 477 } | 476 } |
| 478 return did_connect; | 477 return did_connect; |
| 479 } | 478 } |
| 480 | 479 |
| 481 bool Channel::ChannelImpl::ProcessIncomingMessages() { | |
| 482 while (true) { | |
| 483 int bytes_read = 0; | |
| 484 ReadState read_state = ReadData(input_buf_, Channel::kReadBufferSize, | |
| 485 &bytes_read); | |
| 486 if (read_state == READ_FAILED) | |
| 487 return false; | |
| 488 if (read_state == READ_PENDING) | |
| 489 return true; | |
| 490 | |
| 491 DCHECK(bytes_read > 0); | |
| 492 if (!DispatchInputData(input_buf_, bytes_read)) | |
| 493 return false; | |
| 494 } | |
| 495 } | |
| 496 | |
| 497 bool Channel::ChannelImpl::DispatchInputData(const char* input_data, | |
| 498 int input_data_len) { | |
| 499 const char* p; | |
| 500 const char* end; | |
| 501 | |
| 502 // Possibly combine with the overflow buffer to make a larger buffer. | |
| 503 if (input_overflow_buf_.empty()) { | |
| 504 p = input_data; | |
| 505 end = input_data + input_data_len; | |
| 506 } else { | |
| 507 if (input_overflow_buf_.size() > | |
| 508 kMaximumMessageSize - input_data_len) { | |
| 509 input_overflow_buf_.clear(); | |
| 510 LOG(ERROR) << "IPC message is too big"; | |
| 511 return false; | |
| 512 } | |
| 513 input_overflow_buf_.append(input_data, input_data_len); | |
| 514 p = input_overflow_buf_.data(); | |
| 515 end = p + input_overflow_buf_.size(); | |
| 516 } | |
| 517 | |
| 518 // Dispatch all complete messages in the data buffer. | |
| 519 while (p < end) { | |
| 520 const char* message_tail = Message::FindNext(p, end); | |
| 521 if (message_tail) { | |
| 522 int len = static_cast<int>(message_tail - p); | |
| 523 Message m(p, len); | |
| 524 if (!WillDispatchInputMessage(&m)) | |
| 525 return false; | |
| 526 | |
| 527 if (IsHelloMessage(&m)) | |
| 528 HandleHelloMessage(m); | |
| 529 else | |
| 530 listener_->OnMessageReceived(m); | |
| 531 p = message_tail; | |
| 532 } else { | |
| 533 // Last message is partial. | |
| 534 break; | |
| 535 } | |
| 536 } | |
| 537 | |
| 538 // Save any partial data in the overflow buffer. | |
| 539 input_overflow_buf_.assign(p, end - p); | |
| 540 | |
| 541 if (input_overflow_buf_.empty() && !DidEmptyInputBuffers()) | |
| 542 return false; | |
| 543 return true; | |
| 544 } | |
| 545 | |
| 546 bool Channel::ChannelImpl::ProcessOutgoingMessages() { | 480 bool Channel::ChannelImpl::ProcessOutgoingMessages() { |
| 547 DCHECK(!waiting_connect_); // Why are we trying to send messages if there's | 481 DCHECK(!waiting_connect_); // Why are we trying to send messages if there's |
| 548 // no connection? | 482 // no connection? |
| 549 if (output_queue_.empty()) | 483 if (output_queue_.empty()) |
| 550 return true; | 484 return true; |
| 551 | 485 |
| 552 if (pipe_ == -1) | 486 if (pipe_ == -1) |
| 553 return false; | 487 return false; |
| 554 | 488 |
| 555 // Write out all the messages we can till the write blocks or there are no | 489 // Write out all the messages we can till the write blocks or there are no |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fds); | 531 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fds); |
| 598 msg->file_descriptor_set()->GetDescriptors( | 532 msg->file_descriptor_set()->GetDescriptors( |
| 599 reinterpret_cast<int*>(CMSG_DATA(cmsg))); | 533 reinterpret_cast<int*>(CMSG_DATA(cmsg))); |
| 600 msgh.msg_controllen = cmsg->cmsg_len; | 534 msgh.msg_controllen = cmsg->cmsg_len; |
| 601 | 535 |
| 602 // DCHECK_LE above already checks that | 536 // DCHECK_LE above already checks that |
| 603 // num_fds < kMaxDescriptorsPerMessage so no danger of overflow. | 537 // num_fds < kMaxDescriptorsPerMessage so no danger of overflow. |
| 604 msg->header()->num_fds = static_cast<uint16>(num_fds); | 538 msg->header()->num_fds = static_cast<uint16>(num_fds); |
| 605 | 539 |
| 606 #if defined(IPC_USES_READWRITE) | 540 #if defined(IPC_USES_READWRITE) |
| 607 if (!IsHelloMessage(msg)) { | 541 if (!IsHelloMessage(*msg)) { |
| 608 // Only the Hello message sends the file descriptor with the message. | 542 // Only the Hello message sends the file descriptor with the message. |
| 609 // Subsequently, we can send file descriptors on the dedicated | 543 // Subsequently, we can send file descriptors on the dedicated |
| 610 // fd_pipe_ which makes Seccomp sandbox operation more efficient. | 544 // fd_pipe_ which makes Seccomp sandbox operation more efficient. |
| 611 struct iovec fd_pipe_iov = { const_cast<char *>(""), 1 }; | 545 struct iovec fd_pipe_iov = { const_cast<char *>(""), 1 }; |
| 612 msgh.msg_iov = &fd_pipe_iov; | 546 msgh.msg_iov = &fd_pipe_iov; |
| 613 fd_written = fd_pipe_; | 547 fd_written = fd_pipe_; |
| 614 bytes_written = HANDLE_EINTR(sendmsg(fd_pipe_, &msgh, MSG_DONTWAIT)); | 548 bytes_written = HANDLE_EINTR(sendmsg(fd_pipe_, &msgh, MSG_DONTWAIT)); |
| 615 msgh.msg_iov = &iov; | 549 msgh.msg_iov = &iov; |
| 616 msgh.msg_controllen = 0; | 550 msgh.msg_controllen = 0; |
| 617 if (bytes_written > 0) { | 551 if (bytes_written > 0) { |
| 618 msg->file_descriptor_set()->CommitAll(); | 552 msg->file_descriptor_set()->CommitAll(); |
| 619 } | 553 } |
| 620 } | 554 } |
| 621 #endif // IPC_USES_READWRITE | 555 #endif // IPC_USES_READWRITE |
| 622 } | 556 } |
| 623 | 557 |
| 624 if (bytes_written == 1) { | 558 if (bytes_written == 1) { |
| 625 fd_written = pipe_; | 559 fd_written = pipe_; |
| 626 #if defined(IPC_USES_READWRITE) | 560 #if defined(IPC_USES_READWRITE) |
| 627 if ((mode_ & MODE_CLIENT_FLAG) && IsHelloMessage(msg)) { | 561 if ((mode_ & MODE_CLIENT_FLAG) && IsHelloMessage(*msg)) { |
| 628 DCHECK_EQ(msg->file_descriptor_set()->size(), 1U); | 562 DCHECK_EQ(msg->file_descriptor_set()->size(), 1U); |
| 629 } | 563 } |
| 630 if (!msgh.msg_controllen) { | 564 if (!msgh.msg_controllen) { |
| 631 bytes_written = HANDLE_EINTR(write(pipe_, out_bytes, amt_to_write)); | 565 bytes_written = HANDLE_EINTR(write(pipe_, out_bytes, amt_to_write)); |
| 632 } else | 566 } else |
| 633 #endif // IPC_USES_READWRITE | 567 #endif // IPC_USES_READWRITE |
| 634 { | 568 { |
| 635 bytes_written = HANDLE_EINTR(sendmsg(pipe_, &msgh, MSG_DONTWAIT)); | 569 bytes_written = HANDLE_EINTR(sendmsg(pipe_, &msgh, MSG_DONTWAIT)); |
| 636 } | 570 } |
| 637 } | 571 } |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 } | 743 } |
| 810 #endif // OS_LINUX | 744 #endif // OS_LINUX |
| 811 | 745 |
| 812 // Called by libevent when we can read from the pipe without blocking. | 746 // Called by libevent when we can read from the pipe without blocking. |
| 813 void Channel::ChannelImpl::OnFileCanReadWithoutBlocking(int fd) { | 747 void Channel::ChannelImpl::OnFileCanReadWithoutBlocking(int fd) { |
| 814 bool send_server_hello_msg = false; | 748 bool send_server_hello_msg = false; |
| 815 if (fd == server_listen_pipe_) { | 749 if (fd == server_listen_pipe_) { |
| 816 int new_pipe = 0; | 750 int new_pipe = 0; |
| 817 if (!ServerAcceptConnection(server_listen_pipe_, &new_pipe)) { | 751 if (!ServerAcceptConnection(server_listen_pipe_, &new_pipe)) { |
| 818 Close(); | 752 Close(); |
| 819 listener_->OnChannelListenError(); | 753 listener()->OnChannelListenError(); |
| 820 } | 754 } |
| 821 | 755 |
| 822 if (pipe_ != -1) { | 756 if (pipe_ != -1) { |
| 823 // We already have a connection. We only handle one at a time. | 757 // We already have a connection. We only handle one at a time. |
| 824 // close our new descriptor. | 758 // close our new descriptor. |
| 825 if (HANDLE_EINTR(shutdown(new_pipe, SHUT_RDWR)) < 0) | 759 if (HANDLE_EINTR(shutdown(new_pipe, SHUT_RDWR)) < 0) |
| 826 DPLOG(ERROR) << "shutdown " << pipe_name_; | 760 DPLOG(ERROR) << "shutdown " << pipe_name_; |
| 827 if (HANDLE_EINTR(close(new_pipe)) < 0) | 761 if (HANDLE_EINTR(close(new_pipe)) < 0) |
| 828 DPLOG(ERROR) << "close " << pipe_name_; | 762 DPLOG(ERROR) << "close " << pipe_name_; |
| 829 listener_->OnChannelDenied(); | 763 listener()->OnChannelDenied(); |
| 830 return; | 764 return; |
| 831 } | 765 } |
| 832 pipe_ = new_pipe; | 766 pipe_ = new_pipe; |
| 833 | 767 |
| 834 if ((mode_ & MODE_OPEN_ACCESS_FLAG) == 0) { | 768 if ((mode_ & MODE_OPEN_ACCESS_FLAG) == 0) { |
| 835 // Verify that the IPC channel peer is running as the same user. | 769 // Verify that the IPC channel peer is running as the same user. |
| 836 uid_t client_euid; | 770 uid_t client_euid; |
| 837 if (!GetClientEuid(&client_euid)) { | 771 if (!GetClientEuid(&client_euid)) { |
| 838 DLOG(ERROR) << "Unable to query client euid"; | 772 DLOG(ERROR) << "Unable to query client euid"; |
| 839 ResetToAcceptingConnectionState(); | 773 ResetToAcceptingConnectionState(); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 return true; | 837 return true; |
| 904 } else { | 838 } else { |
| 905 NOTREACHED(); | 839 NOTREACHED(); |
| 906 return false; | 840 return false; |
| 907 } | 841 } |
| 908 } | 842 } |
| 909 | 843 |
| 910 void Channel::ChannelImpl::ClosePipeOnError() { | 844 void Channel::ChannelImpl::ClosePipeOnError() { |
| 911 if (HasAcceptedConnection()) { | 845 if (HasAcceptedConnection()) { |
| 912 ResetToAcceptingConnectionState(); | 846 ResetToAcceptingConnectionState(); |
| 913 listener_->OnChannelError(); | 847 listener()->OnChannelError(); |
| 914 } else { | 848 } else { |
| 915 Close(); | 849 Close(); |
| 916 if (AcceptsConnections()) { | 850 if (AcceptsConnections()) { |
| 917 listener_->OnChannelListenError(); | 851 listener()->OnChannelListenError(); |
| 918 } else { | 852 } else { |
| 919 listener_->OnChannelError(); | 853 listener()->OnChannelError(); |
| 920 } | 854 } |
| 921 } | 855 } |
| 922 } | 856 } |
| 923 | 857 |
| 924 int Channel::ChannelImpl::GetHelloMessageProcId() { | 858 int Channel::ChannelImpl::GetHelloMessageProcId() { |
| 925 int pid = base::GetCurrentProcId(); | 859 int pid = base::GetCurrentProcId(); |
| 926 #if defined(OS_LINUX) | 860 #if defined(OS_LINUX) |
| 927 // Our process may be in a sandbox with a separate PID namespace. | 861 // Our process may be in a sandbox with a separate PID namespace. |
| 928 if (global_pid_) { | 862 if (global_pid_) { |
| 929 pid = global_pid_; | 863 pid = global_pid_; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 946 if (!msg->WriteFileDescriptor(base::FileDescriptor(remote_fd_pipe_, | 880 if (!msg->WriteFileDescriptor(base::FileDescriptor(remote_fd_pipe_, |
| 947 false))) { | 881 false))) { |
| 948 NOTREACHED() << "Unable to pickle hello message file descriptors"; | 882 NOTREACHED() << "Unable to pickle hello message file descriptors"; |
| 949 } | 883 } |
| 950 DCHECK_EQ(msg->file_descriptor_set()->size(), 1U); | 884 DCHECK_EQ(msg->file_descriptor_set()->size(), 1U); |
| 951 } | 885 } |
| 952 #endif // IPC_USES_READWRITE | 886 #endif // IPC_USES_READWRITE |
| 953 output_queue_.push(msg.release()); | 887 output_queue_.push(msg.release()); |
| 954 } | 888 } |
| 955 | 889 |
| 956 bool Channel::ChannelImpl::IsHelloMessage(const Message* m) const { | |
| 957 return m->routing_id() == MSG_ROUTING_NONE && m->type() == HELLO_MESSAGE_TYPE; | |
| 958 } | |
| 959 | |
| 960 Channel::ChannelImpl::ReadState Channel::ChannelImpl::ReadData( | 890 Channel::ChannelImpl::ReadState Channel::ChannelImpl::ReadData( |
| 961 char* buffer, | 891 char* buffer, |
| 962 int buffer_len, | 892 int buffer_len, |
| 963 int* bytes_read) { | 893 int* bytes_read) { |
| 964 if (pipe_ == -1) | 894 if (pipe_ == -1) |
| 965 return READ_FAILED; | 895 return READ_FAILED; |
| 966 | 896 |
| 967 struct msghdr msg = {0}; | 897 struct msghdr msg = {0}; |
| 968 | 898 |
| 969 struct iovec iov = {buffer, buffer_len}; | 899 struct iovec iov = {buffer, buffer_len}; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1028 | 958 |
| 1029 if (bytes_received != 1) | 959 if (bytes_received != 1) |
| 1030 return true; // No message waiting. | 960 return true; // No message waiting. |
| 1031 | 961 |
| 1032 if (!ExtractFileDescriptorsFromMsghdr(&msg)) | 962 if (!ExtractFileDescriptorsFromMsghdr(&msg)) |
| 1033 return false; | 963 return false; |
| 1034 return true; | 964 return true; |
| 1035 } | 965 } |
| 1036 #endif | 966 #endif |
| 1037 | 967 |
| 968 // On Posix, we need to fix up the file descriptors before the input message |
| 969 // is dispatched. |
| 970 // |
| 971 // This will read from the input_fds_ (READWRITE mode only) and read more |
| 972 // handles from the FD pipe if necessary. |
| 1038 bool Channel::ChannelImpl::WillDispatchInputMessage(Message* msg) { | 973 bool Channel::ChannelImpl::WillDispatchInputMessage(Message* msg) { |
| 1039 uint16 header_fds = msg->header()->num_fds; | 974 uint16 header_fds = msg->header()->num_fds; |
| 1040 if (!header_fds) | 975 if (!header_fds) |
| 1041 return true; // Nothing to do. | 976 return true; // Nothing to do. |
| 1042 | 977 |
| 1043 // The message has file descriptors. | 978 // The message has file descriptors. |
| 1044 const char* error = NULL; | 979 const char* error = NULL; |
| 1045 if (header_fds > input_fds_.size()) { | 980 if (header_fds > input_fds_.size()) { |
| 1046 // The message has been completely received, but we didn't get | 981 // The message has been completely received, but we didn't get |
| 1047 // enough file descriptors. | 982 // enough file descriptors. |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1138 // subsequent file descriptor passing. | 1073 // subsequent file descriptor passing. |
| 1139 DCHECK_EQ(msg.file_descriptor_set()->size(), 1U); | 1074 DCHECK_EQ(msg.file_descriptor_set()->size(), 1U); |
| 1140 base::FileDescriptor descriptor; | 1075 base::FileDescriptor descriptor; |
| 1141 if (!msg.ReadFileDescriptor(&iter, &descriptor)) { | 1076 if (!msg.ReadFileDescriptor(&iter, &descriptor)) { |
| 1142 NOTREACHED(); | 1077 NOTREACHED(); |
| 1143 } | 1078 } |
| 1144 fd_pipe_ = descriptor.fd; | 1079 fd_pipe_ = descriptor.fd; |
| 1145 CHECK(descriptor.auto_close); | 1080 CHECK(descriptor.auto_close); |
| 1146 } | 1081 } |
| 1147 #endif // IPC_USES_READWRITE | 1082 #endif // IPC_USES_READWRITE |
| 1148 listener_->OnChannelConnected(pid); | 1083 listener()->OnChannelConnected(pid); |
| 1149 } | 1084 } |
| 1150 | 1085 |
| 1151 void Channel::ChannelImpl::Close() { | 1086 void Channel::ChannelImpl::Close() { |
| 1152 // Close can be called multiple time, so we need to make sure we're | 1087 // Close can be called multiple time, so we need to make sure we're |
| 1153 // idempotent. | 1088 // idempotent. |
| 1154 | 1089 |
| 1155 ResetToAcceptingConnectionState(); | 1090 ResetToAcceptingConnectionState(); |
| 1156 | 1091 |
| 1157 if (must_unlink_) { | 1092 if (must_unlink_) { |
| 1158 unlink(pipe_name_.c_str()); | 1093 unlink(pipe_name_.c_str()); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 } | 1161 } |
| 1227 | 1162 |
| 1228 #if defined(OS_LINUX) | 1163 #if defined(OS_LINUX) |
| 1229 // static | 1164 // static |
| 1230 void Channel::SetGlobalPid(int pid) { | 1165 void Channel::SetGlobalPid(int pid) { |
| 1231 ChannelImpl::SetGlobalPid(pid); | 1166 ChannelImpl::SetGlobalPid(pid); |
| 1232 } | 1167 } |
| 1233 #endif // OS_LINUX | 1168 #endif // OS_LINUX |
| 1234 | 1169 |
| 1235 } // namespace IPC | 1170 } // namespace IPC |
| OLD | NEW |