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 |