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 |