Home | History | Annotate | Download | only in core
      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 #ifndef MOJO_CORE_PLATFORM_HANDLE_IN_TRANSIT_H_
      6 #define MOJO_CORE_PLATFORM_HANDLE_IN_TRANSIT_H_
      7 
      8 #include "base/macros.h"
      9 #include "build/build_config.h"
     10 #include "mojo/core/scoped_process_handle.h"
     11 #include "mojo/public/cpp/platform/platform_handle.h"
     12 
     13 #if defined(OS_MACOSX) && !defined(OS_IOS)
     14 #include <mach/mach.h>
     15 #endif
     16 
     17 #if defined(OS_WIN)
     18 #include <windows.h>
     19 #endif
     20 
     21 namespace mojo {
     22 namespace core {
     23 
     24 // Owns a PlatformHandle which may actually belong to another process. On
     25 // Windows and (sometimes) Mac, handles in a message object may take on values
     26 // which only have meaning in the context of a remote process.
     27 //
     28 // This class provides a safe way of scoping the lifetime of such handles so
     29 // that they don't leak when transmission can't be completed.
     30 class PlatformHandleInTransit {
     31  public:
     32   PlatformHandleInTransit();
     33   explicit PlatformHandleInTransit(PlatformHandle handle);
     34   PlatformHandleInTransit(PlatformHandleInTransit&&);
     35   ~PlatformHandleInTransit();
     36 
     37   PlatformHandleInTransit& operator=(PlatformHandleInTransit&&);
     38 
     39   // Accessor for the owned handle. Must be owned by the calling process.
     40   const PlatformHandle& handle() const {
     41     DCHECK(!owning_process_.is_valid());
     42     return handle_;
     43   }
     44 
     45   // Returns the process which owns this handle. If this is invalid, the handle
     46   // is owned by the current process.
     47   const ScopedProcessHandle& owning_process() const { return owning_process_; }
     48 
     49   // Takes ownership of the held handle as-is. The handle must belong to the
     50   // current process.
     51   PlatformHandle TakeHandle();
     52 
     53   // Discards the handle owned by this object. The implication is that its
     54   // value has been successfully communicated to the owning process and the
     55   // calling process is no longer responsible for managing the handle's
     56   // lifetime.
     57   void CompleteTransit();
     58 
     59   // Transfers ownership of this (local) handle to |target_process|.
     60   bool TransferToProcess(ScopedProcessHandle target_process);
     61 
     62 #if defined(OS_WIN)
     63   HANDLE remote_handle() const { return remote_handle_; }
     64 
     65   // Returns a new local handle, with ownership of |handle| being transferred
     66   // from |owning_process| to the caller.
     67   static PlatformHandle TakeIncomingRemoteHandle(
     68       HANDLE handle,
     69       base::ProcessHandle owning_process);
     70 #endif
     71 
     72 #if defined(OS_MACOSX) && !defined(OS_IOS)
     73   // Creates a special wrapper holding an unowned Mach port name. This may refer
     74   // to a send or receive right in a remote task (process), and is used for
     75   // cases where message must retain such an object as one of its attached
     76   // handles. We're OK for now with leaking in any scenario where a lack of
     77   // strict ownership could cause leakage. See https://crbug.com/855930 for more
     78   // details.
     79   static PlatformHandleInTransit CreateForMachPortName(mach_port_t name);
     80 
     81   bool is_mach_port_name() const { return mach_port_name_ != MACH_PORT_NULL; }
     82   mach_port_t mach_port_name() const { return mach_port_name_; }
     83 #endif
     84 
     85  private:
     86 #if defined(OS_WIN)
     87   // We don't use a ScopedHandle (or, by extension, PlatformHandle) here because
     88   // the handle verifier expects all handle values to be owned by this process.
     89   // On Windows we use |handle_| for locally owned handles and |remote_handle_|
     90   // otherwise. On all other platforms we use |handle_| regardless of ownership.
     91   HANDLE remote_handle_ = INVALID_HANDLE_VALUE;
     92 #endif
     93 
     94   PlatformHandle handle_;
     95   ScopedProcessHandle owning_process_;
     96 
     97 #if defined(OS_MACOSX) && !defined(OS_IOS)
     98   mach_port_t mach_port_name_ = MACH_PORT_NULL;
     99 #endif
    100 
    101   DISALLOW_COPY_AND_ASSIGN(PlatformHandleInTransit);
    102 };
    103 
    104 }  // namespace core
    105 }  // namespace mojo
    106 
    107 #endif  // MOJO_CORE_PLATFORM_HANDLE_IN_TRANSIT_H_
    108