| 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 "content/browser/zygote_host/zygote_host_impl_linux.h" | 5 #include "content/browser/zygote_host/zygote_host_impl_linux.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 #include <sys/socket.h> | 8 #include <sys/socket.h> |
| 9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
| 10 #include <sys/types.h> | 10 #include <sys/types.h> |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 | 57 |
| 58 // Receive a fixed message on fd and return the sender's PID. | 58 // Receive a fixed message on fd and return the sender's PID. |
| 59 // Returns true if the message received matches the expected message. | 59 // Returns true if the message received matches the expected message. |
| 60 bool ReceiveFixedMessage(int fd, | 60 bool ReceiveFixedMessage(int fd, |
| 61 const char* expect_msg, | 61 const char* expect_msg, |
| 62 size_t expect_len, | 62 size_t expect_len, |
| 63 base::ProcessId* sender_pid) { | 63 base::ProcessId* sender_pid) { |
| 64 char buf[expect_len + 1]; | 64 char buf[expect_len + 1]; |
| 65 ScopedVector<base::ScopedFD> fds_vec; | 65 ScopedVector<base::ScopedFD> fds_vec; |
| 66 | 66 |
| 67 const ssize_t len = UnixDomainSocket::RecvMsgWithPid( | 67 const ssize_t len = base::UnixDomainSocket::RecvMsgWithPid( |
| 68 fd, buf, sizeof(buf), &fds_vec, sender_pid); | 68 fd, buf, sizeof(buf), &fds_vec, sender_pid); |
| 69 if (static_cast<size_t>(len) != expect_len) | 69 if (static_cast<size_t>(len) != expect_len) |
| 70 return false; | 70 return false; |
| 71 if (memcmp(buf, expect_msg, expect_len) != 0) | 71 if (memcmp(buf, expect_msg, expect_len) != 0) |
| 72 return false; | 72 return false; |
| 73 if (!fds_vec.empty()) | 73 if (!fds_vec.empty()) |
| 74 return false; | 74 return false; |
| 75 return true; | 75 return true; |
| 76 } | 76 } |
| 77 | 77 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 107 init_ = true; | 107 init_ = true; |
| 108 | 108 |
| 109 base::FilePath chrome_path; | 109 base::FilePath chrome_path; |
| 110 CHECK(PathService::Get(base::FILE_EXE, &chrome_path)); | 110 CHECK(PathService::Get(base::FILE_EXE, &chrome_path)); |
| 111 base::CommandLine cmd_line(chrome_path); | 111 base::CommandLine cmd_line(chrome_path); |
| 112 | 112 |
| 113 cmd_line.AppendSwitchASCII(switches::kProcessType, switches::kZygoteProcess); | 113 cmd_line.AppendSwitchASCII(switches::kProcessType, switches::kZygoteProcess); |
| 114 | 114 |
| 115 int fds[2]; | 115 int fds[2]; |
| 116 CHECK(socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fds) == 0); | 116 CHECK(socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fds) == 0); |
| 117 CHECK(UnixDomainSocket::EnableReceiveProcessId(fds[0])); | 117 CHECK(base::UnixDomainSocket::EnableReceiveProcessId(fds[0])); |
| 118 base::FileHandleMappingVector fds_to_map; | 118 base::FileHandleMappingVector fds_to_map; |
| 119 fds_to_map.push_back(std::make_pair(fds[1], kZygoteSocketPairFd)); | 119 fds_to_map.push_back(std::make_pair(fds[1], kZygoteSocketPairFd)); |
| 120 | 120 |
| 121 base::LaunchOptions options; | 121 base::LaunchOptions options; |
| 122 const base::CommandLine& browser_command_line = | 122 const base::CommandLine& browser_command_line = |
| 123 *base::CommandLine::ForCurrentProcess(); | 123 *base::CommandLine::ForCurrentProcess(); |
| 124 if (browser_command_line.HasSwitch(switches::kZygoteCmdPrefix)) { | 124 if (browser_command_line.HasSwitch(switches::kZygoteCmdPrefix)) { |
| 125 cmd_line.PrependWrapper( | 125 cmd_line.PrependWrapper( |
| 126 browser_command_line.GetSwitchValueNative(switches::kZygoteCmdPrefix)); | 126 browser_command_line.GetSwitchValueNative(switches::kZygoteCmdPrefix)); |
| 127 } | 127 } |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 TearDown(); | 274 TearDown(); |
| 275 } | 275 } |
| 276 } | 276 } |
| 277 | 277 |
| 278 bool ZygoteHostImpl::SendMessage(const Pickle& data, | 278 bool ZygoteHostImpl::SendMessage(const Pickle& data, |
| 279 const std::vector<int>* fds) { | 279 const std::vector<int>* fds) { |
| 280 DCHECK_NE(-1, control_fd_); | 280 DCHECK_NE(-1, control_fd_); |
| 281 CHECK(data.size() <= kZygoteMaxMessageLength) | 281 CHECK(data.size() <= kZygoteMaxMessageLength) |
| 282 << "Trying to send too-large message to zygote (sending " << data.size() | 282 << "Trying to send too-large message to zygote (sending " << data.size() |
| 283 << " bytes, max is " << kZygoteMaxMessageLength << ")"; | 283 << " bytes, max is " << kZygoteMaxMessageLength << ")"; |
| 284 CHECK(!fds || fds->size() <= UnixDomainSocket::kMaxFileDescriptors) | 284 CHECK(!fds || fds->size() <= base::UnixDomainSocket::kMaxFileDescriptors) |
| 285 << "Trying to send message with too many file descriptors to zygote " | 285 << "Trying to send message with too many file descriptors to zygote " |
| 286 << "(sending " << fds->size() << ", max is " | 286 << "(sending " << fds->size() << ", max is " |
| 287 << UnixDomainSocket::kMaxFileDescriptors << ")"; | 287 << base::UnixDomainSocket::kMaxFileDescriptors << ")"; |
| 288 | 288 |
| 289 return UnixDomainSocket::SendMsg(control_fd_, | 289 return base::UnixDomainSocket::SendMsg(control_fd_, |
| 290 data.data(), data.size(), | 290 data.data(), data.size(), |
| 291 fds ? *fds : std::vector<int>()); | 291 fds ? *fds : std::vector<int>()); |
| 292 } | 292 } |
| 293 | 293 |
| 294 ssize_t ZygoteHostImpl::ReadReply(void* buf, size_t buf_len) { | 294 ssize_t ZygoteHostImpl::ReadReply(void* buf, size_t buf_len) { |
| 295 DCHECK_NE(-1, control_fd_); | 295 DCHECK_NE(-1, control_fd_); |
| 296 // At startup we send a kZygoteCommandGetSandboxStatus request to the zygote, | 296 // At startup we send a kZygoteCommandGetSandboxStatus request to the zygote, |
| 297 // but don't wait for the reply. Thus, the first time that we read from the | 297 // but don't wait for the reply. Thus, the first time that we read from the |
| 298 // zygote, we get the reply to that request. | 298 // zygote, we get the reply to that request. |
| 299 if (!have_read_sandbox_status_word_) { | 299 if (!have_read_sandbox_status_word_) { |
| 300 if (HANDLE_EINTR(read(control_fd_, &sandbox_status_, | 300 if (HANDLE_EINTR(read(control_fd_, &sandbox_status_, |
| 301 sizeof(sandbox_status_))) != | 301 sizeof(sandbox_status_))) != |
| (...skipping 11 matching lines...) Expand all Loading... |
| 313 pid_t ZygoteHostImpl::ForkRequest(const std::vector<std::string>& argv, | 313 pid_t ZygoteHostImpl::ForkRequest(const std::vector<std::string>& argv, |
| 314 scoped_ptr<FileDescriptorInfo> mapping, | 314 scoped_ptr<FileDescriptorInfo> mapping, |
| 315 const std::string& process_type) { | 315 const std::string& process_type) { |
| 316 DCHECK(init_); | 316 DCHECK(init_); |
| 317 Pickle pickle; | 317 Pickle pickle; |
| 318 | 318 |
| 319 int raw_socks[2]; | 319 int raw_socks[2]; |
| 320 PCHECK(0 == socketpair(AF_UNIX, SOCK_SEQPACKET, 0, raw_socks)); | 320 PCHECK(0 == socketpair(AF_UNIX, SOCK_SEQPACKET, 0, raw_socks)); |
| 321 base::ScopedFD my_sock(raw_socks[0]); | 321 base::ScopedFD my_sock(raw_socks[0]); |
| 322 base::ScopedFD peer_sock(raw_socks[1]); | 322 base::ScopedFD peer_sock(raw_socks[1]); |
| 323 CHECK(UnixDomainSocket::EnableReceiveProcessId(my_sock.get())); | 323 CHECK(base::UnixDomainSocket::EnableReceiveProcessId(my_sock.get())); |
| 324 | 324 |
| 325 pickle.WriteInt(kZygoteCommandFork); | 325 pickle.WriteInt(kZygoteCommandFork); |
| 326 pickle.WriteString(process_type); | 326 pickle.WriteString(process_type); |
| 327 pickle.WriteInt(argv.size()); | 327 pickle.WriteInt(argv.size()); |
| 328 for (std::vector<std::string>::const_iterator | 328 for (std::vector<std::string>::const_iterator |
| 329 i = argv.begin(); i != argv.end(); ++i) | 329 i = argv.begin(); i != argv.end(); ++i) |
| 330 pickle.WriteString(*i); | 330 pickle.WriteString(*i); |
| 331 | 331 |
| 332 // Fork requests contain one file descriptor for the PID oracle, and one | 332 // Fork requests contain one file descriptor for the PID oracle, and one |
| 333 // more for each file descriptor mapping for the child process. | 333 // more for each file descriptor mapping for the child process. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 356 if (!SendMessage(pickle, &fds)) | 356 if (!SendMessage(pickle, &fds)) |
| 357 return base::kNullProcessHandle; | 357 return base::kNullProcessHandle; |
| 358 mapping.reset(); | 358 mapping.reset(); |
| 359 peer_sock.reset(); | 359 peer_sock.reset(); |
| 360 | 360 |
| 361 { | 361 { |
| 362 char buf[sizeof(kZygoteChildPingMessage) + 1]; | 362 char buf[sizeof(kZygoteChildPingMessage) + 1]; |
| 363 ScopedVector<base::ScopedFD> recv_fds; | 363 ScopedVector<base::ScopedFD> recv_fds; |
| 364 base::ProcessId real_pid; | 364 base::ProcessId real_pid; |
| 365 | 365 |
| 366 ssize_t n = UnixDomainSocket::RecvMsgWithPid( | 366 ssize_t n = base::UnixDomainSocket::RecvMsgWithPid( |
| 367 my_sock.get(), buf, sizeof(buf), &recv_fds, &real_pid); | 367 my_sock.get(), buf, sizeof(buf), &recv_fds, &real_pid); |
| 368 if (n != sizeof(kZygoteChildPingMessage) || | 368 if (n != sizeof(kZygoteChildPingMessage) || |
| 369 0 != memcmp(buf, | 369 0 != memcmp(buf, |
| 370 kZygoteChildPingMessage, | 370 kZygoteChildPingMessage, |
| 371 sizeof(kZygoteChildPingMessage))) { | 371 sizeof(kZygoteChildPingMessage))) { |
| 372 // Zygote children should still be trustworthy when they're supposed to | 372 // Zygote children should still be trustworthy when they're supposed to |
| 373 // ping us, so something's broken if we don't receive a valid ping. | 373 // ping us, so something's broken if we don't receive a valid ping. |
| 374 LOG(ERROR) << "Did not receive ping from zygote child"; | 374 LOG(ERROR) << "Did not receive ping from zygote child"; |
| 375 NOTREACHED(); | 375 NOTREACHED(); |
| 376 real_pid = -1; | 376 real_pid = -1; |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 } | 593 } |
| 594 | 594 |
| 595 if (!sandbox::Credentials::CanCreateProcessInNewUserNS()) { | 595 if (!sandbox::Credentials::CanCreateProcessInNewUserNS()) { |
| 596 return false; | 596 return false; |
| 597 } | 597 } |
| 598 | 598 |
| 599 return true; | 599 return true; |
| 600 } | 600 } |
| 601 | 601 |
| 602 } // namespace content | 602 } // namespace content |
| OLD | NEW |