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

#include "object/job_policy.h"

#include <assert.h>
#include <err.h>
#include <lib/counters.h>
#include <zircon/syscalls/policy.h>

#include <fbl/algorithm.h>
#include <kernel/deadline.h>

namespace {

constexpr uint32_t kDefaultAction = ZX_POL_ACTION_ALLOW;

constexpr pol_cookie_t kPolicyEmpty = 0u;

// The encoding of the basic policy is done 4 bits per each item.
//
// - When the top bit is 1, the lower 3 bits contain the action
//   (ZX_POL_ACTION_ALLOW, ZX_POL_ACTION_DENY, etc.)
//
// - When the top bit is 0 then its the default policy and other bits
//   should be zero so that kPolicyEmpty == 0 meets the requirement of
//   all entries being default.

union Encoding {
  static constexpr uint8_t kExplicitBit = 0b1000;
  static constexpr uint8_t kActionBits = 0b0111;

  // Indicates the policies are fully encoded in the cookie.
  static constexpr uint8_t kPolicyInCookie = 0;

  pol_cookie_t encoded;
  struct {
    uint64_t bad_handle : 4;
    uint64_t wrong_obj : 4;
    uint64_t vmar_wx : 4;
    uint64_t new_vmo : 4;
    uint64_t new_channel : 4;
    uint64_t new_event : 4;
    uint64_t new_eventpair : 4;
    uint64_t new_port : 4;
    uint64_t new_socket : 4;
    uint64_t new_fifo : 4;
    uint64_t new_timer : 4;
    uint64_t new_process : 4;
    uint64_t new_profile : 4;
    uint64_t ambient_mark_vmo_exec : 4;
    uint64_t unused_bits : 7;
    uint64_t cookie_mode : 1;  // see kPolicyInCookie.
  };

  static uint32_t action(uint64_t item) { return item & kActionBits; }
  static bool is_default(uint64_t item) { return item == 0; }
};

// The packing of bits on a bitset (above) is defined by the standard as
// implementation dependent so we must check that it is using the storage
// space of a single uint64_t so the 'union' trick works.
static_assert(sizeof(Encoding) == sizeof(pol_cookie_t), "bitfield issue");

// It is critical that this array contain all "new object" policies because it's used to implement
// ZX_NEW_ANY.
const uint32_t kNewObjectPolicies[]{
    ZX_POL_NEW_VMO,     ZX_POL_NEW_CHANNEL, ZX_POL_NEW_EVENT, ZX_POL_NEW_EVENTPAIR,
    ZX_POL_NEW_PORT,    ZX_POL_NEW_SOCKET,  ZX_POL_NEW_FIFO,  ZX_POL_NEW_TIMER,
    ZX_POL_NEW_PROCESS, ZX_POL_NEW_PROFILE,
};
static_assert(
    fbl::count_of(kNewObjectPolicies) + 5 == ZX_POL_MAX,
    "please update JobPolicy::AddPartial, JobPolicy::QueryBasicPolicy, kNewObjectPolicies,"
    "and the add_basic_policy_deny_any_new() test");

bool CanSetEntry(uint64_t existing, uint32_t new_action) {
  if (Encoding::is_default(existing))
    return true;
  return (new_action == Encoding::action(existing)) ? true : false;
}

uint32_t GetEffectiveAction(uint64_t policy) {
  return Encoding::is_default(policy) ? kDefaultAction : Encoding::action(policy);
}

#define POLMAN_SET_ENTRY(mode, existing, in_pol, resultant) \
  do {                                                      \
    if (CanSetEntry(existing, in_pol)) {                    \
      resultant = in_pol & Encoding::kActionBits;           \
      resultant |= Encoding::kExplicitBit;                  \
    } else if (mode == ZX_JOB_POL_ABSOLUTE) {               \
      return ZX_ERR_ALREADY_EXISTS;                         \
    }                                                       \
  } while (0)

zx_status_t AddPartial(uint32_t mode, pol_cookie_t existing_policy, uint32_t condition,
                       uint32_t policy, uint64_t* partial) {
  Encoding existing = {existing_policy};
  Encoding result = {};

  if (policy >= ZX_POL_ACTION_MAX)
    return ZX_ERR_NOT_SUPPORTED;

  switch (condition) {
    case ZX_POL_BAD_HANDLE:
      POLMAN_SET_ENTRY(mode, existing.bad_handle, policy, result.bad_handle);
      break;
    case ZX_POL_WRONG_OBJECT:
      POLMAN_SET_ENTRY(mode, existing.wrong_obj, policy, result.wrong_obj);
      break;
    case ZX_POL_VMAR_WX:
      POLMAN_SET_ENTRY(mode, existing.vmar_wx, policy, result.vmar_wx);
      break;
    case ZX_POL_NEW_VMO:
      POLMAN_SET_ENTRY(mode, existing.new_vmo, policy, result.new_vmo);
      break;
    case ZX_POL_NEW_CHANNEL:
      POLMAN_SET_ENTRY(mode, existing.new_channel, policy, result.new_channel);
      break;
    case ZX_POL_NEW_EVENT:
      POLMAN_SET_ENTRY(mode, existing.new_event, policy, result.new_event);
      break;
    case ZX_POL_NEW_EVENTPAIR:
      POLMAN_SET_ENTRY(mode, existing.new_eventpair, policy, result.new_eventpair);
      break;
    case ZX_POL_NEW_PORT:
      POLMAN_SET_ENTRY(mode, existing.new_port, policy, result.new_port);
      break;
    case ZX_POL_NEW_SOCKET:
      POLMAN_SET_ENTRY(mode, existing.new_socket, policy, result.new_socket);
      break;
    case ZX_POL_NEW_FIFO:
      POLMAN_SET_ENTRY(mode, existing.new_fifo, policy, result.new_fifo);
      break;
    case ZX_POL_NEW_TIMER:
      POLMAN_SET_ENTRY(mode, existing.new_timer, policy, result.new_timer);
      break;
    case ZX_POL_NEW_PROCESS:
      POLMAN_SET_ENTRY(mode, existing.new_process, policy, result.new_process);
      break;
    case ZX_POL_NEW_PROFILE:
      POLMAN_SET_ENTRY(mode, existing.new_profile, policy, result.new_profile);
      break;
    case ZX_POL_AMBIENT_MARK_VMO_EXEC:
      POLMAN_SET_ENTRY(mode, existing.ambient_mark_vmo_exec, policy, result.ambient_mark_vmo_exec);
      break;
    default:
      return ZX_ERR_NOT_SUPPORTED;
  }

  *partial = result.encoded;
  return ZX_OK;
}

#undef POLMAN_SET_ENTRY

}  // namespace

zx_status_t JobPolicy::AddBasicPolicy(uint32_t mode, const zx_policy_basic_t* policy_input,
                                      size_t policy_count) {
  // Don't allow overlong policies.
  if (policy_count > ZX_POL_MAX) {
    return ZX_ERR_OUT_OF_RANGE;
  }

  uint64_t partials[ZX_POL_MAX] = {};

  // The policy computation algorithm is as follows:
  //
  //    loop over all input entries
  //        if existing item is default or same then
  //            store new policy in partial result array
  //        else if mode is absolute exit with failure
  //        else continue
  //
  // A special case is ZX_POL_NEW_ANY which applies the algorithm with
  // the same input over all ZX_NEW_ actions so that the following can
  // be expressed:
  //
  //   [0] ZX_POL_NEW_ANY     --> ZX_POL_ACTION_DENY
  //   [1] ZX_POL_NEW_CHANNEL --> ZX_POL_ACTION_ALLOW
  //
  // Which means "deny all object creation except for channel".

  zx_status_t res = ZX_OK;

  pol_cookie_t new_cookie = cookie_;

  for (size_t ix = 0; ix != policy_count; ++ix) {
    const auto& in = policy_input[ix];

    if (in.condition >= ZX_POL_MAX) {
      return ZX_ERR_INVALID_ARGS;
    }

    if (in.condition == ZX_POL_NEW_ANY) {
      // loop over all ZX_POL_NEW_xxxx conditions.
      for (auto pol : kNewObjectPolicies) {
        if ((res = AddPartial(mode, new_cookie, pol, in.policy, &partials[pol])) < 0) {
          return res;
        }
      }
    } else {
      if ((res = AddPartial(mode, new_cookie, in.condition, in.policy, &partials[in.condition])) <
          0) {
        return res;
      }
    }
  }

  // Compute the resultant policy. The simple OR works because the only items that
  // can change are the items that have zero. See Encoding::is_default().
  for (const auto& partial : partials) {
    new_cookie |= partial;
  }

  cookie_ = new_cookie;
  return ZX_OK;
}

uint32_t JobPolicy::QueryBasicPolicy(uint32_t condition) const {
  if (cookie_ == kPolicyEmpty) {
    return kDefaultAction;
  }

  Encoding existing = {cookie_};
  DEBUG_ASSERT(existing.cookie_mode == Encoding::kPolicyInCookie);

  switch (condition) {
    case ZX_POL_BAD_HANDLE:
      return GetEffectiveAction(existing.bad_handle);
    case ZX_POL_WRONG_OBJECT:
      return GetEffectiveAction(existing.wrong_obj);
    case ZX_POL_NEW_VMO:
      return GetEffectiveAction(existing.new_vmo);
    case ZX_POL_NEW_CHANNEL:
      return GetEffectiveAction(existing.new_channel);
    case ZX_POL_NEW_EVENT:
      return GetEffectiveAction(existing.new_event);
    case ZX_POL_NEW_EVENTPAIR:
      return GetEffectiveAction(existing.new_eventpair);
    case ZX_POL_NEW_PORT:
      return GetEffectiveAction(existing.new_port);
    case ZX_POL_NEW_SOCKET:
      return GetEffectiveAction(existing.new_socket);
    case ZX_POL_NEW_FIFO:
      return GetEffectiveAction(existing.new_fifo);
    case ZX_POL_NEW_TIMER:
      return GetEffectiveAction(existing.new_timer);
    case ZX_POL_NEW_PROCESS:
      return GetEffectiveAction(existing.new_process);
    case ZX_POL_NEW_PROFILE:
      return GetEffectiveAction(existing.new_profile);
    case ZX_POL_VMAR_WX:
      return GetEffectiveAction(existing.vmar_wx);
    case ZX_POL_AMBIENT_MARK_VMO_EXEC:
      return GetEffectiveAction(existing.ambient_mark_vmo_exec);
    default:
      return ZX_POL_ACTION_DENY;
  }
}

void JobPolicy::SetTimerSlack(TimerSlack slack) { slack_ = slack; }

TimerSlack JobPolicy::GetTimerSlack() const { return slack_; }

bool JobPolicy::operator==(const JobPolicy& rhs) const {
  if (this == &rhs) {
    return true;
  }

  return cookie_ == rhs.cookie_ && slack_ == rhs.slack_;
}

bool JobPolicy::operator!=(const JobPolicy& rhs) const { return !operator==(rhs); }

// Evaluates to the name of the kcounter for the given action and condition.
//
// E.g. COUNTER(deny, new_channel) -> policy_action_deny_new_channel_count
#define COUNTER(action, condition) policy_##action##_##condition##_count

// Defines a kcounter for the given action and condition.
#define DEFINE_COUNTER(action, condition) \
  KCOUNTER(COUNTER(action, condition), "policy." #action "." #condition)

// Evaluates to the name of an array of pointers to Counter objects.
//
// See DEFINE_COUNTER_ARRAY for details.
#define COUNTER_ARRAY(action) counters_##action

// Defines kcounters for the given action and creates an array named |COUNTER_ARRAY(action)|.
//
// The array has length ZX_POL_MAX and contains pointers to the Counter objects. The array should be
// indexed by condition. Note, some array elements may be null.
//
// Example:
//
//     DEFINE_COUNTER_ARRAY(deny);
//     kcounter_add(*COUNTER_ARRAY(deny)[ZX_POL_NEW_CHANNEL], 1);
//
#define DEFINE_COUNTER_ARRAY(action)                                            \
  DEFINE_COUNTER(action, bad_handle)                                            \
  DEFINE_COUNTER(action, wrong_object)                                          \
  DEFINE_COUNTER(action, vmar_wx)                                               \
  DEFINE_COUNTER(action, new_vmo)                                               \
  DEFINE_COUNTER(action, new_channel)                                           \
  DEFINE_COUNTER(action, new_event)                                             \
  DEFINE_COUNTER(action, new_eventpair)                                         \
  DEFINE_COUNTER(action, new_port)                                              \
  DEFINE_COUNTER(action, new_socket)                                            \
  DEFINE_COUNTER(action, new_fifo)                                              \
  DEFINE_COUNTER(action, new_timer)                                             \
  DEFINE_COUNTER(action, new_process)                                           \
  DEFINE_COUNTER(action, new_profile)                                           \
  DEFINE_COUNTER(action, ambient_mark_vmo_exec)                                 \
  static constexpr const Counter* const COUNTER_ARRAY(action)[] = {             \
      [ZX_POL_BAD_HANDLE] = &COUNTER(action, bad_handle),                       \
      [ZX_POL_WRONG_OBJECT] = &COUNTER(action, wrong_object),                   \
      [ZX_POL_VMAR_WX] = &COUNTER(action, vmar_wx),                             \
      [ZX_POL_NEW_ANY] = nullptr, /* ZX_POL_NEW_ANY is a pseudo condition */    \
      [ZX_POL_NEW_VMO] = &COUNTER(action, new_vmo),                             \
      [ZX_POL_NEW_CHANNEL] = &COUNTER(action, new_channel),                     \
      [ZX_POL_NEW_EVENT] = &COUNTER(action, new_event),                         \
      [ZX_POL_NEW_EVENTPAIR] = &COUNTER(action, new_eventpair),                 \
      [ZX_POL_NEW_PORT] = &COUNTER(action, new_port),                           \
      [ZX_POL_NEW_SOCKET] = &COUNTER(action, new_socket),                       \
      [ZX_POL_NEW_FIFO] = &COUNTER(action, new_fifo),                           \
      [ZX_POL_NEW_TIMER] = &COUNTER(action, new_timer),                         \
      [ZX_POL_NEW_PROCESS] = &COUNTER(action, new_process),                     \
      [ZX_POL_NEW_PROFILE] = &COUNTER(action, new_profile),                     \
      [ZX_POL_AMBIENT_MARK_VMO_EXEC] = &COUNTER(action, ambient_mark_vmo_exec), \
  };                                                                            \
  static_assert(fbl::count_of(COUNTER_ARRAY(action)) == ZX_POL_MAX);

// Counts policy violations resulting in ZX_POL_ACTION_DENY or ZX_POL_ACTION_DENY_EXCEPTION.
DEFINE_COUNTER_ARRAY(deny)
// Counts policy violations resulting in ZX_POL_ACTION_KILL.
DEFINE_COUNTER_ARRAY(kill)
static_assert(ZX_POL_ACTION_MAX == 5, "add another instantiation of DEFINE_COUNTER_ARRAY");

void JobPolicy::IncrementCounter(uint32_t action, uint32_t condition) {
  DEBUG_ASSERT(action < ZX_POL_ACTION_MAX);
  DEBUG_ASSERT(condition < ZX_POL_MAX);

  const Counter* counter = nullptr;
  switch (action) {
    case ZX_POL_ACTION_DENY:
    case ZX_POL_ACTION_DENY_EXCEPTION:
      counter = COUNTER_ARRAY(deny)[condition];
      break;
    case ZX_POL_ACTION_KILL:
      counter = COUNTER_ARRAY(kill)[condition];
      break;
  };
  if (!counter) {
    return;
  }
  kcounter_add(*counter, 1);
}

#undef COUNTER
#undef DEFINE_COUNTER
#undef COUNTER_ARRAY
#undef DEFINE_COUNTER_ARRAY
