// 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(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(handle, &resource);
  if (status != ZX_OK) {
    return status;
  }

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