// Copyright 2017 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 <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <threads.h>

#include <lib/zx/channel.h>
#include <lib/zx/event.h>
#include <lib/zx/exception.h>
#include <lib/zx/handle.h>
#include <lib/zx/job.h>
#include <lib/zx/port.h>
#include <lib/zx/process.h>
#include <lib/zx/thread.h>
#include <lib/zx/vmar.h>

#include <fbl/algorithm.h>

#include <zircon/process.h>
#include <zircon/syscalls/debug.h>
#include <zircon/syscalls/exception.h>
#include <zircon/syscalls/policy.h>
#include <zircon/syscalls/port.h>

#include <mini-process/mini-process.h>

#include <unistd.h>
#include <unittest/unittest.h>

static const unsigned kExceptionPortKey = 42u;

// Basic job operation is tested by core-tests.
static zx::job make_job() {
    zx::job job;
    if (zx::job::create(*zx::job::default_job(), 0u, &job) != ZX_OK)
        return zx::job();
    return job;
}

static zx::process make_test_process(const zx::job& job, zx::thread* out_thread,
                                     zx_handle_t* ctrl) {
    zx::vmar vmar;
    zx::process proc;
    zx_status_t status = zx::process::create(job, "poltst", 6u, 0u, &proc, &vmar);
    if (status != ZX_OK)
        return zx::process();

    zx::thread thread;
    status = zx::thread::create(proc, "poltst", 6u, 0, &thread);
    if (status != ZX_OK)
        return zx::process();
    if (out_thread) {
        status = thread.duplicate(ZX_RIGHT_SAME_RIGHTS, out_thread);
        if (status != ZX_OK)
            return zx::process();
    }

    zx::event event;
    status = zx::event::create(0u, &event);
    if (status != ZX_OK)
        return zx::process();

    auto thr = thread.release();
    status = start_mini_process_etc(proc.get(), thr, vmar.get(), event.release(), ctrl);
    if (status != ZX_OK)
        return zx::process();

    return proc;
}

static bool AbsThenRel() {
    BEGIN_TEST;

    zx_policy_basic_t policy[] = {{ZX_POL_BAD_HANDLE, ZX_POL_ACTION_KILL}};

    auto job = make_job();
    EXPECT_EQ(job.set_policy(ZX_JOB_POL_ABSOLUTE, ZX_JOB_POL_BASIC, policy,
                             static_cast<uint32_t>(fbl::count_of(policy))),
              ZX_OK);

    // A contradictory policy should fail.
    policy[0].policy = ZX_POL_ACTION_DENY_EXCEPTION;
    EXPECT_EQ(job.set_policy(ZX_JOB_POL_ABSOLUTE, ZX_JOB_POL_BASIC, policy,
                             static_cast<uint32_t>(fbl::count_of(policy))),
              ZX_ERR_ALREADY_EXISTS);

    // The same again will succeed.
    policy[0].policy = ZX_POL_ACTION_KILL;
    EXPECT_EQ(job.set_policy(ZX_JOB_POL_ABSOLUTE, ZX_JOB_POL_BASIC, policy,
                             static_cast<uint32_t>(fbl::count_of(policy))),
              ZX_OK);

    // A contradictory relative policy will succeed, but is a no-op
    policy[0].policy = ZX_POL_ACTION_ALLOW;
    EXPECT_EQ(job.set_policy(ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC, policy,
                             static_cast<uint32_t>(fbl::count_of(policy))),
              ZX_OK);

    zx_policy_basic_t more[] = {{ZX_POL_NEW_CHANNEL, ZX_POL_ACTION_ALLOW_EXCEPTION},
                                {ZX_POL_NEW_FIFO, ZX_POL_ACTION_DENY}};

    // An additional absolute policy that doesn't contradict existing
    // policy can be added.
    EXPECT_EQ(job.set_policy(ZX_JOB_POL_ABSOLUTE, ZX_JOB_POL_BASIC, more,
                             static_cast<uint32_t>(fbl::count_of(more))),
              ZX_OK);

    END_TEST;
}

__WARN_UNUSED_RESULT
static bool invalid_calls(uint32_t options) {
    BEGIN_HELPER;


    {
        // Null policy pointer.
        auto job = make_job();
        EXPECT_EQ(job.set_policy(options, ZX_JOB_POL_BASIC, nullptr, 0u), ZX_ERR_INVALID_ARGS);
        EXPECT_EQ(job.set_policy(options, ZX_JOB_POL_BASIC, nullptr, 1u), ZX_ERR_INVALID_ARGS);
        EXPECT_EQ(job.set_policy(options, ZX_JOB_POL_BASIC, nullptr, 5u), ZX_ERR_INVALID_ARGS);

        zx_policy_basic_t policy[] = {{ZX_POL_BAD_HANDLE, ZX_POL_ACTION_KILL}};
        EXPECT_EQ(job.set_policy(options, ZX_JOB_POL_BASIC, policy, 1u), ZX_OK);
    }

    {
        // Count is 0.
        auto job = make_job();
        zx_policy_basic_t policy[] = {{ZX_POL_BAD_HANDLE, ZX_POL_ACTION_KILL}};
        EXPECT_EQ(job.set_policy(options, ZX_JOB_POL_BASIC, policy, 0u), ZX_ERR_INVALID_ARGS);

        EXPECT_EQ(job.set_policy(options, ZX_JOB_POL_BASIC, policy, 1u), ZX_OK);
    }

    {
        // Too many.
        auto job = make_job();
        zx_policy_basic_t policy[15]{};
        for (unsigned i = 0; i < fbl::count_of(policy); ++i) {
            policy[i] = {ZX_POL_BAD_HANDLE, ZX_POL_ACTION_KILL};
        }
        EXPECT_EQ(job.set_policy(options, ZX_JOB_POL_BASIC, policy, fbl::count_of(policy)),
                  ZX_ERR_OUT_OF_RANGE);

        EXPECT_EQ(job.set_policy(options, ZX_JOB_POL_BASIC, policy, 1u), ZX_OK);
    }

    {
        // Invalid condition value.
        auto job = make_job();
        zx_policy_basic_t policy[] = {{100001u, ZX_POL_ACTION_KILL}};
        EXPECT_EQ(job.set_policy(options, ZX_JOB_POL_BASIC, policy,
                                 static_cast<uint32_t>(fbl::count_of(policy))),
                  ZX_ERR_INVALID_ARGS);

        zx_policy_basic_t good_policy[] = {{ZX_POL_BAD_HANDLE, ZX_POL_ACTION_KILL}};
        EXPECT_EQ(job.set_policy(options, ZX_JOB_POL_BASIC, good_policy, 1u), ZX_OK);
    }

    {
        // Invalid action value.
        auto job = make_job();
        zx_policy_basic_t policy[] = {{ZX_POL_BAD_HANDLE, ZX_POL_ACTION_KILL + 1}};
        EXPECT_EQ(job.set_policy(options, ZX_JOB_POL_BASIC, policy,
                                 static_cast<uint32_t>(fbl::count_of(policy))),
                  ZX_ERR_NOT_SUPPORTED);

        zx_policy_basic_t good_policy[] = {{ZX_POL_BAD_HANDLE, ZX_POL_ACTION_KILL}};
        EXPECT_EQ(job.set_policy(options, ZX_JOB_POL_BASIC, good_policy, 1u), ZX_OK);
    }

    END_HELPER;
}

static bool InvalidCallsAbs() {
    BEGIN_TEST;

    ASSERT_TRUE(invalid_calls(ZX_JOB_POL_ABSOLUTE));

    END_TEST;
}

static bool InvalidCallsRel() {
    BEGIN_TEST;

    ASSERT_TRUE(invalid_calls(ZX_JOB_POL_RELATIVE));

    END_TEST;
}

// Checks that executing the given mini-process.h command (|minip_cmd|) produces the given result
// (|expect|) when the given policy is in force.
//
// Returns true if all expectations are met.
__WARN_UNUSED_RESULT
static bool CheckInvokingPolicy(zx_policy_basic_t* pol, uint32_t pol_count, uint32_t minip_cmd,
                                zx_status_t expect) {
    BEGIN_HELPER;

    auto job = make_job();
    ASSERT_EQ(job.set_policy(ZX_JOB_POL_ABSOLUTE, ZX_JOB_POL_BASIC, pol, pol_count), ZX_OK);

    zx_handle_t ctrl;
    auto proc = make_test_process(job, nullptr, &ctrl);
    ASSERT_TRUE(proc.is_valid());
    ASSERT_NE(ctrl, ZX_HANDLE_INVALID);

    zx_handle_t obj;
    EXPECT_EQ(mini_process_cmd(ctrl, minip_cmd, &obj), expect);
    EXPECT_EQ(mini_process_cmd(ctrl, MINIP_CMD_EXIT_NORMAL, nullptr), ZX_ERR_PEER_CLOSED);

    zx_handle_close(ctrl);

    END_HELPER;
}

static bool EnforceDenyEvent() {
    BEGIN_TEST;

    zx_policy_basic_t policy[] = {{ZX_POL_NEW_EVENT, ZX_POL_ACTION_DENY}};
    ASSERT_TRUE(CheckInvokingPolicy(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                    MINIP_CMD_CREATE_EVENT, ZX_ERR_ACCESS_DENIED));

    END_TEST;
}

static bool EnforceDenyProfile() {
    BEGIN_TEST;

    zx_policy_basic_t policy[] = {{ZX_POL_NEW_PROFILE, ZX_POL_ACTION_DENY}};
    ASSERT_TRUE(CheckInvokingPolicy(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                    MINIP_CMD_CREATE_PROFILE, ZX_ERR_ACCESS_DENIED));

    END_TEST;
}

static bool EnforceDenyChannel() {
    BEGIN_TEST;

    zx_policy_basic_t policy[] = {{ZX_POL_NEW_CHANNEL, ZX_POL_ACTION_DENY}};
    ASSERT_TRUE(CheckInvokingPolicy(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                    MINIP_CMD_CREATE_CHANNEL, ZX_ERR_ACCESS_DENIED));

    END_TEST;
}

static bool EnforceDenyPagerVmo() {
    BEGIN_TEST;

    zx_policy_basic_t policy[] = {{ZX_POL_NEW_VMO, ZX_POL_ACTION_DENY}};
    ASSERT_TRUE(CheckInvokingPolicy(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                    MINIP_CMD_CREATE_PAGER_VMO, ZX_ERR_ACCESS_DENIED));

    END_TEST;
}

static bool EnforceDenyVmoContiguous() {
    BEGIN_TEST;

    zx_policy_basic_t policy[] = {{ZX_POL_NEW_VMO, ZX_POL_ACTION_DENY}};
    ASSERT_TRUE(CheckInvokingPolicy(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                    MINIP_CMD_CREATE_VMO_CONTIGUOUS, ZX_ERR_ACCESS_DENIED));

    END_TEST;
}

static bool EnforceDenyVmoPhysical() {
    BEGIN_TEST;

    zx_policy_basic_t policy[] = {{ZX_POL_NEW_VMO, ZX_POL_ACTION_DENY}};
    ASSERT_TRUE(CheckInvokingPolicy(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                    MINIP_CMD_CREATE_VMO_PHYSICAL, ZX_ERR_ACCESS_DENIED));

    END_TEST;
}

static bool EnforceDenyAny() {
    BEGIN_TEST;

    zx_policy_basic_t policy[] = {{ZX_POL_NEW_ANY, ZX_POL_ACTION_DENY}};
    ASSERT_TRUE(CheckInvokingPolicy(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                    MINIP_CMD_CREATE_EVENT, ZX_ERR_ACCESS_DENIED));
    ASSERT_TRUE(CheckInvokingPolicy(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                    MINIP_CMD_CREATE_PROFILE, ZX_ERR_ACCESS_DENIED));
    ASSERT_TRUE(CheckInvokingPolicy(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                    MINIP_CMD_CREATE_CHANNEL, ZX_ERR_ACCESS_DENIED));

    END_TEST;
}

// Check that executing the given mini-process.h command (|minip_cmd|) kills the process when the
// given policy |pol| is in effect.
//
// Returns true if all expectations are met.
__WARN_UNUSED_RESULT
static bool CheckInvokingPolicyKill(zx_policy_basic_t* pol, uint32_t count, uint32_t minip_cmd) {
    BEGIN_HELPER;

    auto job = make_job();
    ASSERT_EQ(job.set_policy(ZX_JOB_POL_ABSOLUTE, ZX_JOB_POL_BASIC, pol, count), ZX_OK);

    zx_handle_t ctrl;
    auto proc = make_test_process(job, nullptr, &ctrl);
    ASSERT_TRUE(proc.is_valid());
    ASSERT_NE(ctrl, ZX_HANDLE_INVALID);

    zx_handle_t obj;
    ASSERT_EQ(mini_process_cmd(ctrl, minip_cmd, &obj), ZX_ERR_PEER_CLOSED);
    ASSERT_EQ(proc.wait_one(ZX_TASK_TERMINATED, zx::time::infinite(), nullptr), ZX_OK);

    zx_info_process_t proc_info;
    ASSERT_EQ(proc.get_info(ZX_INFO_PROCESS, &proc_info, sizeof(proc_info), nullptr, nullptr),
              ZX_OK);
    ASSERT_TRUE(proc_info.exited);
    ASSERT_EQ(proc_info.return_code, ZX_TASK_RETCODE_POLICY_KILL);

    zx_handle_close(ctrl);

    END_HELPER;
}

static bool EnforceKillEvent() {
    BEGIN_TEST;

    zx_policy_basic_t policy[] = {{ZX_POL_NEW_EVENT, ZX_POL_ACTION_KILL}};
    ASSERT_TRUE(CheckInvokingPolicyKill(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                        MINIP_CMD_CREATE_EVENT));

    END_TEST;
}

static bool EnforceAllowAny() {
    BEGIN_TEST;

    zx_policy_basic_t policy[] = {{ZX_POL_NEW_ANY, ZX_POL_ACTION_ALLOW}};
    ASSERT_TRUE(CheckInvokingPolicy(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                    MINIP_CMD_CREATE_EVENT, ZX_OK));

    END_TEST;
}

static bool EnforceDenyButEvent() {
    BEGIN_TEST;

    zx_policy_basic_t policy[] = {{ZX_POL_NEW_ANY, ZX_POL_ACTION_DENY},
                                  {ZX_POL_NEW_EVENT, ZX_POL_ACTION_ALLOW}};
    ASSERT_TRUE(CheckInvokingPolicy(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                    MINIP_CMD_CREATE_EVENT, ZX_OK));
    ASSERT_TRUE(CheckInvokingPolicy(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                    MINIP_CMD_CREATE_CHANNEL, ZX_ERR_ACCESS_DENIED));

    END_TEST;
}

__WARN_UNUSED_RESULT
static bool get_koid(zx_handle_t handle, zx_koid_t* koid) {
    BEGIN_HELPER;

    zx_info_handle_basic_t info;
    ASSERT_EQ(
        zx_object_get_info(handle, ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr),
        ZX_OK);
    *koid = info.koid;

    END_HELPER;
}

#if defined(__x86_64__)

static uint64_t get_syscall_result(zx_thread_state_general_regs_t* regs) {
    return regs->rax;
}

#elif defined(__aarch64__)

static uint64_t get_syscall_result(zx_thread_state_general_regs_t* regs) {
    return regs->r[0];
}

#else
#error Unsupported architecture
#endif

namespace {

enum class ExceptionTestType { kPorts,
                               kChannels };

} // namespace

// Like CheckInvokingPolicy(), this tests that executing the given
// mini-process.h command produces the given result when the given policy
// is in force.  In addition, it tests that a debug port exception gets
// generated.
__WARN_UNUSED_RESULT
static bool CheckInvokingPolicyWithException(ExceptionTestType test_type,
                                             const zx_policy_basic_t* policy, uint32_t policy_count,
                                             uint32_t minip_cmd,
                                             zx_status_t expected_syscall_result) {
    BEGIN_HELPER;

    auto job = make_job();
    ASSERT_EQ(job.set_policy(ZX_JOB_POL_ABSOLUTE, ZX_JOB_POL_BASIC, policy, policy_count), ZX_OK);

    zx_handle_t ctrl;
    zx::thread thread;
    auto proc = make_test_process(job, &thread, &ctrl);
    ASSERT_TRUE(proc.is_valid());
    ASSERT_NE(ctrl, ZX_HANDLE_INVALID);

    zx_handle_t exc_port = ZX_HANDLE_INVALID;
    zx::channel exc_channel;
    if (test_type == ExceptionTestType::kPorts) {
        ASSERT_EQ(zx_port_create(0, &exc_port), ZX_OK);
        ASSERT_EQ(zx_task_bind_exception_port(proc.get(), exc_port, kExceptionPortKey,
                                              ZX_EXCEPTION_PORT_DEBUGGER),
                  ZX_OK);
    } else {
        ASSERT_EQ(proc.create_exception_channel(ZX_EXCEPTION_PORT_DEBUGGER, &exc_channel), ZX_OK);
    }

    EXPECT_EQ(mini_process_cmd_send(ctrl, minip_cmd), ZX_OK);

    // Check that the subprocess did not return a reply yet (indicating
    // that it was suspended).
    EXPECT_EQ(zx_object_wait_one(ctrl, ZX_CHANNEL_READABLE, zx_deadline_after(ZX_MSEC(1)), nullptr),
              ZX_ERR_TIMED_OUT);

    zx_koid_t pid;
    zx_koid_t tid;
    ASSERT_TRUE(get_koid(proc.get(), &pid));
    ASSERT_TRUE(get_koid(thread.get(), &tid));

    // Check that we receive an exception message.
    zx::exception exception;
    if (test_type == ExceptionTestType::kPorts) {
        zx_port_packet_t packet;
        ASSERT_EQ(zx_port_wait(exc_port, ZX_TIME_INFINITE, &packet), ZX_OK);

        // Check the exception message contents.
        ASSERT_EQ(packet.key, kExceptionPortKey);
        ASSERT_EQ(packet.type, (uint32_t)ZX_EXCP_POLICY_ERROR);
        ASSERT_EQ(packet.exception.pid, pid);
        ASSERT_EQ(packet.exception.tid, tid);
    } else {
        zx_exception_info_t info;
        ASSERT_EQ(exc_channel.wait_one(ZX_CHANNEL_READABLE, zx::time::infinite(), nullptr), ZX_OK);
        ASSERT_EQ(exc_channel.read(0, &info, exception.reset_and_get_address(), sizeof(info), 1,
                                   nullptr, nullptr),
                  ZX_OK);

        ASSERT_EQ(info.type, ZX_EXCP_POLICY_ERROR);
        ASSERT_EQ(info.tid, tid);
        ASSERT_EQ(info.pid, pid);

        // Make sure the exception has the correct task handles.
        zx::thread exception_thread;
        zx::process exception_process;
        ASSERT_EQ(exception.get_thread(&exception_thread), ZX_OK);
        ASSERT_EQ(exception.get_process(&exception_process), ZX_OK);

        zx_koid_t handle_tid = ZX_KOID_INVALID;
        EXPECT_TRUE(get_koid(exception_thread.get(), &handle_tid));
        EXPECT_EQ(handle_tid, tid);

        zx_koid_t handle_pid = ZX_KOID_INVALID;
        EXPECT_TRUE(get_koid(exception_process.get(), &handle_pid));
        EXPECT_EQ(handle_pid, pid);
    }

    // Check that we can read the thread's register state.
    zx_thread_state_general_regs_t regs;
    ASSERT_EQ(zx_thread_read_state(thread.get(), ZX_THREAD_STATE_GENERAL_REGS, &regs, sizeof(regs)),
              ZX_OK);
    ASSERT_EQ(get_syscall_result(&regs), (uint64_t)expected_syscall_result);
    // TODO(mseaborn): Check the values of other registers.  We could check
    // that rip/pc is within the VDSO, which will require figuring out
    // where the VDSO is mapped.  We could check that unwinding the stack
    // using crashlogger gives a correct backtrace.

    // Resume the thread.
    if (test_type == ExceptionTestType::kPorts) {
        ASSERT_EQ(zx_task_resume_from_exception(thread.get(), exc_port, 0), ZX_OK);
    } else {
        uint32_t state = ZX_EXCEPTION_STATE_HANDLED;
        ASSERT_EQ(exception.set_property(ZX_PROP_EXCEPTION_STATE, &state, sizeof(state)), ZX_OK);
        exception.reset();
    }

    // Check that the read-ready state of the channel changed compared with
    // the earlier check.
    EXPECT_EQ(zx_object_wait_one(ctrl, ZX_CHANNEL_READABLE, ZX_TIME_INFINITE, nullptr), ZX_OK);

    // Check that we receive a reply message from the resumed thread.
    zx_handle_t obj;
    EXPECT_EQ(mini_process_cmd_read_reply(ctrl, &obj), expected_syscall_result);
    if (expected_syscall_result == ZX_OK)
        EXPECT_EQ(zx_handle_close(obj), ZX_OK);

    // Clean up: Tell the subprocess to exit.
    EXPECT_EQ(mini_process_cmd(ctrl, MINIP_CMD_EXIT_NORMAL, nullptr), ZX_ERR_PEER_CLOSED);

    zx_handle_close(ctrl);

    END_HELPER;
}

// Invokes a policy exception test using both port and channel exceptions.
__WARN_UNUSED_RESULT
static bool CheckInvokingPolicyWithException(const zx_policy_basic_t* policy, uint32_t policy_count,
                                             uint32_t minip_cmd,
                                             zx_status_t expected_syscall_result) {
    BEGIN_HELPER;

    EXPECT_TRUE(CheckInvokingPolicyWithException(ExceptionTestType::kPorts, policy, policy_count,
                                                 minip_cmd, expected_syscall_result));

    EXPECT_TRUE(CheckInvokingPolicyWithException(ExceptionTestType::kChannels, policy, policy_count,
                                                 minip_cmd, expected_syscall_result));

    END_HELPER;
}

static bool TestExceptionOnNewEventAndDeny() {
    BEGIN_TEST;

    zx_policy_basic_t policy[] = {
        {ZX_POL_NEW_EVENT, ZX_POL_ACTION_DENY_EXCEPTION},
    };
    ASSERT_TRUE(CheckInvokingPolicyWithException(policy,
                                                 static_cast<uint32_t>(fbl::count_of(policy)),
                                                 MINIP_CMD_CREATE_EVENT, ZX_ERR_ACCESS_DENIED));

    END_TEST;
}

static bool TestExceptionOnNewEventButAllow() {
    BEGIN_TEST;

    zx_policy_basic_t policy[] = {
        {ZX_POL_NEW_EVENT, ZX_POL_ACTION_ALLOW_EXCEPTION},
    };
    ASSERT_TRUE(CheckInvokingPolicyWithException(
        policy, static_cast<uint32_t>(fbl::count_of(policy)), MINIP_CMD_CREATE_EVENT, ZX_OK));

    END_TEST;
}

static bool TestExceptionOnNewProfileAndDeny() {
    BEGIN_TEST;

    zx_policy_basic_t policy[] = {
        {ZX_POL_NEW_PROFILE, ZX_POL_ACTION_DENY_EXCEPTION},
    };
    ASSERT_TRUE(CheckInvokingPolicyWithException(policy,
                                                 static_cast<uint32_t>(fbl::count_of(policy)),
                                                 MINIP_CMD_CREATE_PROFILE, ZX_ERR_ACCESS_DENIED));

    END_TEST;
}

// Test ZX_POL_BAD_HANDLE when syscalls are allowed to continue.
static bool TestErrorOnBadHandle() {
    BEGIN_TEST;

    // The ALLOW and DENY actions should be equivalent for ZX_POL_BAD_HANDLE.
    uint32_t actions[] = {ZX_POL_ACTION_ALLOW, ZX_POL_ACTION_DENY};
    for (uint32_t action : actions) {
        unittest_printf_critical("Testing action=%d\n", action);
        zx_policy_basic_t policy[] = {
            {ZX_POL_BAD_HANDLE, action},
        };
        ASSERT_TRUE(CheckInvokingPolicy(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                        MINIP_CMD_USE_BAD_HANDLE_CLOSED, ZX_ERR_BAD_HANDLE));
        ASSERT_TRUE(CheckInvokingPolicy(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                        MINIP_CMD_USE_BAD_HANDLE_TRANSFERRED, ZX_ERR_BAD_HANDLE));
    }

    END_TEST;
}

// Test ZX_POL_BAD_HANDLE with ZX_POL_ACTION_EXCEPTION.
static bool TestExceptionOnBadHandle() {
    BEGIN_TEST;

    // The ALLOW_EXCEPTION and DENY_EXCEPTION actions should be equivalent for ZX_POL_BAD_HANDLE.
    uint32_t actions[] = {ZX_POL_ACTION_ALLOW_EXCEPTION, ZX_POL_ACTION_DENY_EXCEPTION};
    for (uint32_t action : actions) {
        unittest_printf_critical("Testing action=%d\n", action);
        zx_policy_basic_t policy[] = {{ZX_POL_BAD_HANDLE, action}};
        ASSERT_TRUE(
            CheckInvokingPolicyWithException(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                             MINIP_CMD_USE_BAD_HANDLE_CLOSED, ZX_ERR_BAD_HANDLE));
        ASSERT_TRUE(CheckInvokingPolicyWithException(
            policy, static_cast<uint32_t>(fbl::count_of(policy)),
            MINIP_CMD_USE_BAD_HANDLE_TRANSFERRED, ZX_ERR_BAD_HANDLE));
    }

    END_TEST;
}

// The one exception for ZX_POL_BAD_HANDLE is zx_object_info( ZX_INFO_HANDLE_VALID).
static bool TestGetInfoOnBadHandle() {
    BEGIN_TEST;

    zx_policy_basic_t policy[] = {
        {ZX_POL_BAD_HANDLE, ZX_POL_ACTION_DENY_EXCEPTION}};
    ASSERT_TRUE(CheckInvokingPolicy(policy, static_cast<uint32_t>(fbl::count_of(policy)),
                                    MINIP_CMD_VALIDATE_CLOSED_HANDLE, ZX_ERR_BAD_HANDLE));

    END_TEST;
}

BEGIN_TEST_CASE(job_policy)
RUN_TEST(InvalidCallsAbs)
RUN_TEST(InvalidCallsRel)
RUN_TEST(AbsThenRel)
RUN_TEST(EnforceDenyEvent)
RUN_TEST(EnforceDenyProfile)
RUN_TEST(EnforceDenyChannel)
RUN_TEST(EnforceDenyPagerVmo)
RUN_TEST(EnforceDenyVmoContiguous)
RUN_TEST(EnforceDenyVmoPhysical)
RUN_TEST(EnforceDenyAny)
RUN_TEST(EnforceKillEvent)
RUN_TEST(EnforceAllowAny)
RUN_TEST(EnforceDenyButEvent)
RUN_TEST(TestExceptionOnNewEventAndDeny)
RUN_TEST(TestExceptionOnNewEventButAllow)
RUN_TEST(TestExceptionOnNewProfileAndDeny)
RUN_TEST(TestErrorOnBadHandle)
RUN_TEST(TestExceptionOnBadHandle)
RUN_TEST(TestGetInfoOnBadHandle)
END_TEST_CASE(job_policy)
