1 // Copyright 2016 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 #ifndef MOJO_CORE_MACH_PORT_RELAY_H_ 6 #define MOJO_CORE_MACH_PORT_RELAY_H_ 7 8 #include <set> 9 #include <vector> 10 11 #include "base/macros.h" 12 #include "base/process/port_provider_mac.h" 13 #include "base/synchronization/lock.h" 14 #include "mojo/core/channel.h" 15 16 namespace mojo { 17 namespace core { 18 19 // The MachPortRelay is used by a privileged process, usually the root process, 20 // to manipulate Mach ports in a child process. Ports can be added to and 21 // extracted from a child process that has registered itself with the 22 // |base::PortProvider| used by this class. 23 class MachPortRelay : public base::PortProvider::Observer { 24 public: 25 class Observer { 26 public: 27 // Called by the MachPortRelay to notify observers that a new process is 28 // ready for Mach ports to be sent/received. There are no guarantees about 29 // the thread this is called on, including the presence of a MessageLoop. 30 // Implementations must not call AddObserver() or RemoveObserver() during 31 // this function, as doing so will deadlock. 32 virtual void OnProcessReady(base::ProcessHandle process) = 0; 33 }; 34 35 // Used by a child process to receive Mach ports from a sender (privileged) 36 // process. The Mach port in |port| is interpreted as an intermediate Mach 37 // port. It replaces each Mach port with the final Mach port received from the 38 // intermediate port. This method takes ownership of the intermediate Mach 39 // port and gives ownership of the final Mach port to the caller. 40 // 41 // On failure, returns a null send right. 42 // 43 // See SendPortsToProcess() for the definition of intermediate and final Mach 44 // ports. 45 static base::mac::ScopedMachSendRight ReceiveSendRight( 46 base::mac::ScopedMachReceiveRight port); 47 48 explicit MachPortRelay(base::PortProvider* port_provider); 49 ~MachPortRelay() override; 50 51 // Sends the Mach ports attached to |message| to |process|. 52 // For each Mach port attached to |message|, a new Mach port, the intermediate 53 // port, is created in |process|. The message's Mach port is then sent over 54 // this intermediate port and the message is modified to refer to the name of 55 // the intermediate port. The Mach port received over the intermediate port in 56 // the child is referred to as the final Mach port. 57 // 58 // All ports in |message|'s set of handles are reset by this call, and all 59 // port names in the message's header are replaced with the new receive right 60 // ports. 61 void SendPortsToProcess(Channel::Message* message, 62 base::ProcessHandle process); 63 64 // Given the name of a Mach send right within |process|, extracts an owned 65 // send right ref and returns it. May return a null port on failure. 66 base::mac::ScopedMachSendRight ExtractPort(mach_port_t port_name, 67 base::ProcessHandle process); 68 69 // Observer interface. 70 void AddObserver(Observer* observer); 71 void RemoveObserver(Observer* observer); 72 port_provider()73 base::PortProvider* port_provider() const { return port_provider_; } 74 75 private: 76 // base::PortProvider::Observer implementation. 77 void OnReceivedTaskPort(base::ProcessHandle process) override; 78 79 base::PortProvider* const port_provider_; 80 81 base::Lock observers_lock_; 82 std::set<Observer*> observers_; 83 84 DISALLOW_COPY_AND_ASSIGN(MachPortRelay); 85 }; 86 87 } // namespace core 88 } // namespace mojo 89 90 #endif // MOJO_CORE_MACH_PORT_RELAY_H_ 91