1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/chrome_cleaner/ipc/mojo_sandbox_hooks.h"
6 
7 #include <string>
8 #include <utility>
9 
10 #include "base/check.h"
11 #include "base/rand_util.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "chrome/chrome_cleaner/constants/chrome_cleaner_switches.h"
14 
15 namespace chrome_cleaner {
16 
17 MojoSandboxSetupHooks::MojoSandboxSetupHooks() = default;
18 
19 MojoSandboxSetupHooks::~MojoSandboxSetupHooks() = default;
20 
SetupSandboxMessagePipe(sandbox::TargetPolicy * policy,base::CommandLine * command_line)21 mojo::ScopedMessagePipeHandle MojoSandboxSetupHooks::SetupSandboxMessagePipe(
22     sandbox::TargetPolicy* policy,
23     base::CommandLine* command_line) {
24   DCHECK(policy);
25   DCHECK(command_line);
26 
27   std::string pipe_token = base::NumberToString(base::RandUint64());
28   mojo::ScopedMessagePipeHandle mojo_pipe =
29       outgoing_invitation_.AttachMessagePipe(pipe_token);
30   command_line->AppendSwitchASCII(kSandboxMojoPipeTokenSwitch, pipe_token);
31 
32   base::HandlesToInheritVector handles_to_inherit;
33   mojo_channel_.PrepareToPassRemoteEndpoint(&handles_to_inherit, command_line);
34   for (HANDLE handle : handles_to_inherit)
35     policy->AddHandleToShare(handle);
36 
37   message_pipe_was_created_ = true;
38   return mojo_pipe;
39 }
40 
TargetSpawned(const base::Process & target_process,const base::win::ScopedHandle & target_thread)41 ResultCode MojoSandboxSetupHooks::TargetSpawned(
42     const base::Process& target_process,
43     const base::win::ScopedHandle& target_thread) {
44   DCHECK(message_pipe_was_created_);
45 
46   ReportProcessLaunchAttempt();
47 
48   // TODO(joenotcharles): Hook up the |error_callback| parameter of Send to a
49   // function that logs a security warning and exits. This callback will be
50   // called when an invalid message is written to the pipe.
51   mojo::OutgoingInvitation::Send(std::move(outgoing_invitation_),
52                                  target_process.Handle(),
53                                  mojo_channel_.TakeLocalEndpoint());
54 
55   return RESULT_CODE_SUCCESS;
56 }
57 
SetupFailed()58 void MojoSandboxSetupHooks::SetupFailed() {
59   if (process_launch_attempt_reported_) {
60     // Setup failed after calling TargetSpawned, so don't report the launch
61     // attempt again.
62     return;
63   }
64 
65   ReportProcessLaunchAttempt();
66 }
67 
ReportProcessLaunchAttempt()68 void MojoSandboxSetupHooks::ReportProcessLaunchAttempt() {
69   DCHECK(!process_launch_attempt_reported_);
70   mojo_channel_.RemoteProcessLaunchAttempted();
71   process_launch_attempt_reported_ = true;
72 }
73 
74 MojoSandboxTargetHooks::MojoSandboxTargetHooks() = default;
75 
76 MojoSandboxTargetHooks::~MojoSandboxTargetHooks() = default;
77 
ExtractSandboxMessagePipe(const base::CommandLine & command_line)78 mojo::ScopedMessagePipeHandle MojoSandboxTargetHooks::ExtractSandboxMessagePipe(
79     const base::CommandLine& command_line) {
80   auto channel_endpoint =
81       mojo::PlatformChannel::RecoverPassedEndpointFromCommandLine(command_line);
82   auto incoming_invitation =
83       mojo::IncomingInvitation::Accept(std::move(channel_endpoint));
84   return incoming_invitation.ExtractMessagePipe(
85       command_line.GetSwitchValueASCII(kSandboxMojoPipeTokenSwitch));
86 }
87 
88 }  // namespace chrome_cleaner
89