// Copyright 2017 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include "object/resource.h"

#include <align.h>
#include <lib/root_resource_filter.h>
#include <trace.h>
#include <zircon/syscalls/resource.h>

#include <fbl/ref_ptr.h>
#include <kernel/range_check.h>
#include <object/process_dispatcher.h>
#include <object/resource_dispatcher.h>

#define LOCAL_TRACE 0

// TODO(fxbug.dev/32272): Take another look at validation and consider returning
// dispatchers or move validation into the parent dispatcher itself.

// Check if the resource referenced by |handle| is of kind |kind|, or ZX_RSRC_KIND_ROOT.
//
// Possible errors:
// ++ ZX_ERR_ACCESS_DENIED: |handle| is not the right |kind| of handle.
// ++ ZX_ERR_WRONG_TYPE: |handle| is not a valid handle.
zx_status_t validate_resource(zx_handle_t handle, zx_rsrc_kind_t kind) {
  auto up = ProcessDispatcher::GetCurrent();
  fbl::RefPtr<ResourceDispatcher> resource;
  auto status = up->handle_table().GetDispatcher(*up, handle, &resource);
  if (status != ZX_OK) {
    return status;
  }

  auto res_kind = resource->get_kind();
  if (res_kind == kind || res_kind == ZX_RSRC_KIND_ROOT) {
    return ZX_OK;
  }

  return ZX_ERR_WRONG_TYPE;
}

zx_status_t validate_ranged_resource(fbl::RefPtr<ResourceDispatcher> resource, zx_rsrc_kind_t kind,
                                     uintptr_t base, size_t size) {
  // Root gets access to almost everything, but there are still resource ranges
  // it is not permitted to mint. For example:
  //
  // 1) All of physical RAM is off limits (with limited platform specific
  //    exceptions). It exists on the CPU accessible physical bus (so, the
  //    domain controlled by ZX_RSRC_KIND_MMIO) and user mode program should not
  //    be able to request access to physical RAM by address, they should be
  //    forced to go through the PMM using VMO creation instead.
  // 2) Any MMIO accessible interrupt controller registers.
  // 3) Any MMIO accessible IOMMU registers.
  //
  // Enforce that policy here by disallowing resource minting for any request
  // which touches any disallowed ranges.
  //
  if (resource->get_kind() == ZX_RSRC_KIND_ROOT || resource->IsRangedRoot(kind)) {
    if (!root_resource_filter_can_access_region(base, size, kind)) {
      return ZX_ERR_ACCESS_DENIED;
    }
    return ZX_OK;
  }

  if (resource->get_kind() != kind) {
    return ZX_ERR_WRONG_TYPE;
  }

  uint64_t rbase = resource->get_base();
  size_t rsize = resource->get_size();
  // In the specific case of MMIO, everything is rounded to PAGE_SIZE units
  // because it's the smallest unit we can operate at with the MMU.
  if (resource->get_kind() == ZX_RSRC_KIND_MMIO) {
    const uint64_t aligned_rbase = ROUNDDOWN(rbase, PAGE_SIZE);
    rsize = PAGE_ALIGN((rbase - aligned_rbase) + rsize);
    rbase = aligned_rbase;
  }
  LTRACEF("req [base %#lx size %#lx] and resource [base %#lx size %#lx]\n", base, size, rbase,
          rsize);

  // All resources need to track their lineage back to the root resource,
  // and the root resource is specifically prohibited from producing ranges
  // which intersect anything in the deny list. Since all resource ranges
  // need to be a subset of their parent, it should be impossible for a
  // resource object to exist with a range which intersects anything in the
  // deny list. Check that with a debug assert here.
  ZX_DEBUG_ASSERT(root_resource_filter_can_access_region(rbase, rsize, kind));

  // Check for intersection and make sure the requested base+size fits within
  // the resource's address space  allocation.
  uintptr_t ibase;
  size_t isize;
  if (!GetIntersect(base, size, rbase, rsize, &ibase, &isize) || isize != size || ibase != base) {
    return ZX_ERR_OUT_OF_RANGE;
  }

  return ZX_OK;
}

// Check if the resource referenced by |handle| is of kind |kind|, or ZX_RSRC_KIND_ROOT. If
// |kind| matches the resource's kind, then range validation between |base| and |size| will
// be made against the resource's backing address space allocation.
//
// Possible errors:
// ++ ZX_ERR_ACCESS_DENIED: |handle| is not a valid handle.
// ++ ZX_ERR_WRONG_TYPE: |handle| is not a valid resource handle, or |kind| is invalid for
//                       the request.
// ++ ZX_ERR_OUT_OF_RANGE: The range specified by |base| and |Len| is not granted by this
// resource.
zx_status_t validate_ranged_resource(zx_handle_t handle, zx_rsrc_kind_t kind, uintptr_t base,
                                     size_t size) {
  auto up = ProcessDispatcher::GetCurrent();
  fbl::RefPtr<ResourceDispatcher> resource;
  auto status = up->handle_table().GetDispatcher(*up, handle, &resource);
  if (status != ZX_OK) {
    return status;
  }

  return validate_ranged_resource(resource, kind, base, size);
}
