| 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 "components/nacl/zygote/nacl_fork_delegate_linux.h" | 5 #include "components/nacl/zygote/nacl_fork_delegate_linux.h" |
| 6 | 6 |
| 7 #include <signal.h> | 7 #include <signal.h> |
| 8 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 #include <sys/resource.h> | 9 #include <sys/resource.h> |
| 10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 #endif | 91 #endif |
| 92 | 92 |
| 93 // Send an IPC request on |ipc_channel|. The request is contained in | 93 // Send an IPC request on |ipc_channel|. The request is contained in |
| 94 // |request_pickle| and can have file descriptors attached in |attached_fds|. | 94 // |request_pickle| and can have file descriptors attached in |attached_fds|. |
| 95 // |reply_data_buffer| must be allocated by the caller and will contain the | 95 // |reply_data_buffer| must be allocated by the caller and will contain the |
| 96 // reply. The size of the reply will be written to |reply_size|. | 96 // reply. The size of the reply will be written to |reply_size|. |
| 97 // This code assumes that only one thread can write to |ipc_channel| to make | 97 // This code assumes that only one thread can write to |ipc_channel| to make |
| 98 // requests. | 98 // requests. |
| 99 bool SendIPCRequestAndReadReply(int ipc_channel, | 99 bool SendIPCRequestAndReadReply(int ipc_channel, |
| 100 const std::vector<int>& attached_fds, | 100 const std::vector<int>& attached_fds, |
| 101 const Pickle& request_pickle, | 101 const base::Pickle& request_pickle, |
| 102 char* reply_data_buffer, | 102 char* reply_data_buffer, |
| 103 size_t reply_data_buffer_size, | 103 size_t reply_data_buffer_size, |
| 104 ssize_t* reply_size) { | 104 ssize_t* reply_size) { |
| 105 DCHECK_LE(static_cast<size_t>(kNaClMaxIPCMessageLength), | 105 DCHECK_LE(static_cast<size_t>(kNaClMaxIPCMessageLength), |
| 106 reply_data_buffer_size); | 106 reply_data_buffer_size); |
| 107 DCHECK(reply_size); | 107 DCHECK(reply_size); |
| 108 | 108 |
| 109 if (!UnixDomainSocket::SendMsg(ipc_channel, request_pickle.data(), | 109 if (!UnixDomainSocket::SendMsg(ipc_channel, request_pickle.data(), |
| 110 request_pickle.size(), attached_fds)) { | 110 request_pickle.size(), attached_fds)) { |
| 111 LOG(ERROR) << "SendIPCRequestAndReadReply: SendMsg failed"; | 111 LOG(ERROR) << "SendIPCRequestAndReadReply: SendMsg failed"; |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 VLOG(1) << "NaClForkDelegate::Fork"; | 360 VLOG(1) << "NaClForkDelegate::Fork"; |
| 361 | 361 |
| 362 DCHECK(fds.size() == kNumPassedFDs); | 362 DCHECK(fds.size() == kNumPassedFDs); |
| 363 | 363 |
| 364 if (status_ != kNaClHelperSuccess) { | 364 if (status_ != kNaClHelperSuccess) { |
| 365 LOG(ERROR) << "Cannot launch NaCl process: nacl_helper failed to start"; | 365 LOG(ERROR) << "Cannot launch NaCl process: nacl_helper failed to start"; |
| 366 return -1; | 366 return -1; |
| 367 } | 367 } |
| 368 | 368 |
| 369 // First, send a remote fork request. | 369 // First, send a remote fork request. |
| 370 Pickle write_pickle; | 370 base::Pickle write_pickle; |
| 371 write_pickle.WriteInt(nacl::kNaClForkRequest); | 371 write_pickle.WriteInt(nacl::kNaClForkRequest); |
| 372 // TODO(hamaji): When we split the helper binary for non-SFI mode | 372 // TODO(hamaji): When we split the helper binary for non-SFI mode |
| 373 // from nacl_helper, stop sending this information. | 373 // from nacl_helper, stop sending this information. |
| 374 write_pickle.WriteBool(nonsfi_mode_); | 374 write_pickle.WriteBool(nonsfi_mode_); |
| 375 write_pickle.WriteString(channel_id); | 375 write_pickle.WriteString(channel_id); |
| 376 | 376 |
| 377 char reply_buf[kNaClMaxIPCMessageLength]; | 377 char reply_buf[kNaClMaxIPCMessageLength]; |
| 378 ssize_t reply_size = 0; | 378 ssize_t reply_size = 0; |
| 379 bool got_reply = | 379 bool got_reply = |
| 380 SendIPCRequestAndReadReply(fd_, fds, write_pickle, | 380 SendIPCRequestAndReadReply(fd_, fds, write_pickle, |
| 381 reply_buf, sizeof(reply_buf), &reply_size); | 381 reply_buf, sizeof(reply_buf), &reply_size); |
| 382 if (!got_reply) { | 382 if (!got_reply) { |
| 383 LOG(ERROR) << "Could not perform remote fork."; | 383 LOG(ERROR) << "Could not perform remote fork."; |
| 384 return -1; | 384 return -1; |
| 385 } | 385 } |
| 386 | 386 |
| 387 // Now see if the other end managed to fork. | 387 // Now see if the other end managed to fork. |
| 388 Pickle reply_pickle(reply_buf, reply_size); | 388 base::Pickle reply_pickle(reply_buf, reply_size); |
| 389 PickleIterator iter(reply_pickle); | 389 base::PickleIterator iter(reply_pickle); |
| 390 pid_t nacl_child; | 390 pid_t nacl_child; |
| 391 if (!iter.ReadInt(&nacl_child)) { | 391 if (!iter.ReadInt(&nacl_child)) { |
| 392 LOG(ERROR) << "NaClForkDelegate::Fork: pickle failed"; | 392 LOG(ERROR) << "NaClForkDelegate::Fork: pickle failed"; |
| 393 return -1; | 393 return -1; |
| 394 } | 394 } |
| 395 VLOG(1) << "nacl_child is " << nacl_child; | 395 VLOG(1) << "nacl_child is " << nacl_child; |
| 396 return nacl_child; | 396 return nacl_child; |
| 397 } | 397 } |
| 398 | 398 |
| 399 bool NaClForkDelegate::GetTerminationStatus(pid_t pid, bool known_dead, | 399 bool NaClForkDelegate::GetTerminationStatus(pid_t pid, bool known_dead, |
| 400 base::TerminationStatus* status, | 400 base::TerminationStatus* status, |
| 401 int* exit_code) { | 401 int* exit_code) { |
| 402 VLOG(1) << "NaClForkDelegate::GetTerminationStatus"; | 402 VLOG(1) << "NaClForkDelegate::GetTerminationStatus"; |
| 403 DCHECK(status); | 403 DCHECK(status); |
| 404 DCHECK(exit_code); | 404 DCHECK(exit_code); |
| 405 | 405 |
| 406 Pickle write_pickle; | 406 base::Pickle write_pickle; |
| 407 write_pickle.WriteInt(nacl::kNaClGetTerminationStatusRequest); | 407 write_pickle.WriteInt(nacl::kNaClGetTerminationStatusRequest); |
| 408 write_pickle.WriteInt(pid); | 408 write_pickle.WriteInt(pid); |
| 409 write_pickle.WriteBool(known_dead); | 409 write_pickle.WriteBool(known_dead); |
| 410 | 410 |
| 411 const std::vector<int> empty_fds; | 411 const std::vector<int> empty_fds; |
| 412 char reply_buf[kNaClMaxIPCMessageLength]; | 412 char reply_buf[kNaClMaxIPCMessageLength]; |
| 413 ssize_t reply_size = 0; | 413 ssize_t reply_size = 0; |
| 414 bool got_reply = | 414 bool got_reply = |
| 415 SendIPCRequestAndReadReply(fd_, empty_fds, write_pickle, | 415 SendIPCRequestAndReadReply(fd_, empty_fds, write_pickle, |
| 416 reply_buf, sizeof(reply_buf), &reply_size); | 416 reply_buf, sizeof(reply_buf), &reply_size); |
| 417 if (!got_reply) { | 417 if (!got_reply) { |
| 418 LOG(ERROR) << "Could not perform remote GetTerminationStatus."; | 418 LOG(ERROR) << "Could not perform remote GetTerminationStatus."; |
| 419 return false; | 419 return false; |
| 420 } | 420 } |
| 421 | 421 |
| 422 Pickle reply_pickle(reply_buf, reply_size); | 422 base::Pickle reply_pickle(reply_buf, reply_size); |
| 423 PickleIterator iter(reply_pickle); | 423 base::PickleIterator iter(reply_pickle); |
| 424 int termination_status; | 424 int termination_status; |
| 425 if (!iter.ReadInt(&termination_status) || | 425 if (!iter.ReadInt(&termination_status) || |
| 426 termination_status < 0 || | 426 termination_status < 0 || |
| 427 termination_status >= base::TERMINATION_STATUS_MAX_ENUM) { | 427 termination_status >= base::TERMINATION_STATUS_MAX_ENUM) { |
| 428 LOG(ERROR) << "GetTerminationStatus: pickle failed"; | 428 LOG(ERROR) << "GetTerminationStatus: pickle failed"; |
| 429 return false; | 429 return false; |
| 430 } | 430 } |
| 431 | 431 |
| 432 int remote_exit_code; | 432 int remote_exit_code; |
| 433 if (!iter.ReadInt(&remote_exit_code)) { | 433 if (!iter.ReadInt(&remote_exit_code)) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 455 pass_through_vars.push_back(kNaClVerbosity); | 455 pass_through_vars.push_back(kNaClVerbosity); |
| 456 pass_through_vars.push_back(sandbox::kSandboxEnvironmentApiRequest); | 456 pass_through_vars.push_back(sandbox::kSandboxEnvironmentApiRequest); |
| 457 for (size_t i = 0; i < pass_through_vars.size(); ++i) { | 457 for (size_t i = 0; i < pass_through_vars.size(); ++i) { |
| 458 std::string temp; | 458 std::string temp; |
| 459 if (env->GetVar(pass_through_vars[i].c_str(), &temp)) | 459 if (env->GetVar(pass_through_vars[i].c_str(), &temp)) |
| 460 options->environ[pass_through_vars[i]] = temp; | 460 options->environ[pass_through_vars[i]] = temp; |
| 461 } | 461 } |
| 462 } | 462 } |
| 463 | 463 |
| 464 } // namespace nacl | 464 } // namespace nacl |
| OLD | NEW |