Code: bool UnprivilegedProcessDelegate::LaunchProcess(
    IPC::Listener* delegate,
    ScopedHandle* process_exit_event_out) {
  DCHECK(main_task_runner_->BelongsToCurrentThread());
  std::string channel_name = GenerateIpcChannelName(this);

   ScopedHandle client;
   scoped_ptr<IPC::ChannelProxy> server;
  if (!CreateConnectedIpcChannel(channel_name, delegate, &client, &server))
     return false;
 
  std::string pipe_handle = base::StringPrintf(
      "%d", reinterpret_cast<ULONG_PTR>(client.Get()));

  CommandLine command_line(binary_path_);
  command_line.AppendSwitchASCII(kDaemonPipeSwitchName, pipe_handle);
  command_line.CopySwitchesFrom(*CommandLine::ForCurrentProcess(),
                                kCopiedSwitchNames,
                                arraysize(kCopiedSwitchNames));

  ScopedHandle worker_thread;
  worker_process_.Close();
  if (!LaunchProcessWithToken(command_line.GetProgram(),
                              command_line.GetCommandLineString(),
                              NULL,
                              true,
                              0,
                              &worker_process_,
                              &worker_thread)) {
    return false;
  }

  ScopedHandle process_exit_event;
  if (!DuplicateHandle(GetCurrentProcess(),
                       worker_process_,
                       GetCurrentProcess(),
                       process_exit_event.Receive(),
                       SYNCHRONIZE,
                       FALSE,
                       0)) {
    LOG_GETLASTERROR(ERROR) << "Failed to duplicate a handle";
    KillProcess(CONTROL_C_EXIT);
    return false;
  }

  channel_ = server.Pass();
  *process_exit_event_out = process_exit_event.Pass();
   return true;
 }

Commit Message: Validate and report peer's PID to WorkerProcessIpcDelegate so it will be able to duplicate handles to and from the worker process.

As a side effect WorkerProcessLauncher::Delegate is now responsible for retrieving the client's PID and deciding whether a launch failed due to a permanent error condition.

BUG=134694


Review URL: https://chromiumcodereview.appspot.com/11143025

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162778 0039d316-1c4b-4281-b951-d872f2087c98
CWE ID: CWE-399
bool UnprivilegedProcessDelegate::LaunchProcess(
    IPC::Listener* delegate,
    ScopedHandle* process_exit_event_out) {
  DCHECK(main_task_runner_->BelongsToCurrentThread());
  std::string channel_name = GenerateIpcChannelName(this);

   ScopedHandle client;
   scoped_ptr<IPC::ChannelProxy> server;
  ScopedHandle pipe;
  if (!CreateConnectedIpcChannel(channel_name, io_task_runner_, delegate,
                                 &client, &server, &pipe)) {
     return false;
  }
 
  std::string pipe_handle = base::StringPrintf(
      "%d", reinterpret_cast<ULONG_PTR>(client.Get()));

  CommandLine command_line(binary_path_);
  command_line.AppendSwitchASCII(kDaemonPipeSwitchName, pipe_handle);
  command_line.CopySwitchesFrom(*CommandLine::ForCurrentProcess(),
                                kCopiedSwitchNames,
                                arraysize(kCopiedSwitchNames));

  ScopedHandle worker_thread;
  worker_process_.Close();
  if (!LaunchProcessWithToken(command_line.GetProgram(),
                              command_line.GetCommandLineString(),
                              NULL,
                              true,
                              0,
                              &worker_process_,
                              &worker_thread)) {
    return false;
  }

  ScopedHandle process_exit_event;
  if (!DuplicateHandle(GetCurrentProcess(),
                       worker_process_,
                       GetCurrentProcess(),
                       process_exit_event.Receive(),
                       SYNCHRONIZE,
                       FALSE,
                       0)) {
    LOG_GETLASTERROR(ERROR) << "Failed to duplicate a handle";
    KillProcess(CONTROL_C_EXIT);
    return false;
  }

  channel_ = server.Pass();
  *process_exit_event_out = process_exit_event.Pass();
   return true;
 }
