chromium/mojo/public/cpp/platform/platform_handle.cc

// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "mojo/public/cpp/platform/platform_handle.h"

#include <tuple>

#include "base/logging.h"
#include "build/build_config.h"

#if BUILDFLAG(IS_WIN)
#include <windows.h>

#include "base/win/scoped_handle.h"
#elif BUILDFLAG(IS_FUCHSIA)
#include <lib/fdio/limits.h>
#include <unistd.h>
#include <zircon/status.h>

#include "base/fuchsia/fuchsia_logging.h"
#elif BUILDFLAG(IS_APPLE)
#include <mach/vm_map.h>

#include "base/apple/mach_logging.h"
#include "base/apple/scoped_mach_port.h"
#endif

#if BUILDFLAG(IS_POSIX)
#include <unistd.h>

#include "base/files/scoped_file.h"
#endif

#if BUILDFLAG(IS_ANDROID)
#include "base/android/binder.h"
#endif

namespace mojo {

namespace {

#if BUILDFLAG(IS_WIN)
base::win::ScopedHandle CloneHandle(const base::win::ScopedHandle& handle) {
  DCHECK(handle.IsValid());

  HANDLE dupe;
  BOOL result = FALSE;

  // INVALID_HANDLE_VALUE and the process pseudo-handle are both represented as
  // the value -1. This means that if a caller does not correctly check the
  // handle returned by file and pipe creation APIs, then it would pass an
  // INVALID_HANDLE_VALUE to the code below, which would result in the
  // destination process getting full control over the calling process (see
  // http://crbug.com/243339 for an example of this vulnerability). So, we just
  // explicitly check for INVALID_HANDLE_VALUE, since there's no valid scenario
  // in which it would be passed as the source handle here.
  if (handle.Get() != INVALID_HANDLE_VALUE) {
    result = ::DuplicateHandle(::GetCurrentProcess(), handle.Get(),
                               ::GetCurrentProcess(), &dupe, 0, FALSE,
                               DUPLICATE_SAME_ACCESS);
  }
  if (!result)
    return base::win::ScopedHandle();
  DCHECK_NE(dupe, INVALID_HANDLE_VALUE);
  return base::win::ScopedHandle(dupe);
}
#elif BUILDFLAG(IS_FUCHSIA)
zx::handle CloneHandle(const zx::handle& handle) {
  DCHECK(handle.is_valid());

  zx::handle dupe;
  zx_status_t result = handle.duplicate(ZX_RIGHT_SAME_RIGHTS, &dupe);
  if (result != ZX_OK)
    ZX_DLOG(ERROR, result) << "zx_duplicate_handle";
  return std::move(dupe);
}
#elif BUILDFLAG(IS_APPLE)
base::apple::ScopedMachSendRight CloneMachPort(
    const base::apple::ScopedMachSendRight& mach_port) {
  DCHECK(mach_port.is_valid());

  kern_return_t kr = mach_port_mod_refs(mach_task_self(), mach_port.get(),
                                        MACH_PORT_RIGHT_SEND, 1);
  if (kr != KERN_SUCCESS) {
    MACH_DLOG(ERROR, kr) << "mach_port_mod_refs";
    return base::apple::ScopedMachSendRight();
  }
  return base::apple::ScopedMachSendRight(mach_port.get());
}
#endif

#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
base::ScopedFD CloneFD(const base::ScopedFD& fd) {}
#endif

}  // namespace

PlatformHandle::PlatformHandle() = default;

PlatformHandle::PlatformHandle(PlatformHandle&& other) {}

#if BUILDFLAG(IS_WIN)
PlatformHandle::PlatformHandle(base::win::ScopedHandle handle)
    : type_(Type::kHandle), handle_(std::move(handle)) {}
#elif BUILDFLAG(IS_FUCHSIA)
PlatformHandle::PlatformHandle(zx::handle handle)
    : type_(Type::kHandle), handle_(std::move(handle)) {}
#elif BUILDFLAG(IS_APPLE)
PlatformHandle::PlatformHandle(base::apple::ScopedMachSendRight mach_port)
    : type_(Type::kMachSend), mach_send_(std::move(mach_port)) {}
PlatformHandle::PlatformHandle(base::apple::ScopedMachReceiveRight mach_port)
    : type_(Type::kMachReceive), mach_receive_(std::move(mach_port)) {}
#endif

#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
PlatformHandle::PlatformHandle(base::ScopedFD fd)
    :{}
#endif

#if BUILDFLAG(IS_ANDROID)
PlatformHandle::PlatformHandle(base::android::BinderRef binder)
    : type_(Type::kBinder), binder_(std::move(binder)) {}
#endif

PlatformHandle::~PlatformHandle() = default;

PlatformHandle& PlatformHandle::operator=(PlatformHandle&& other) {}

// static
void PlatformHandle::ToMojoPlatformHandle(PlatformHandle handle,
                                          MojoPlatformHandle* out_handle) {}

// static
PlatformHandle PlatformHandle::FromMojoPlatformHandle(
    const MojoPlatformHandle* handle) {}

void PlatformHandle::reset() {}

void PlatformHandle::release() {}

PlatformHandle PlatformHandle::Clone() const {}

}  // namespace mojo