// Copyright 2016 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 <err.h>
#include <inttypes.h>
#include <platform.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <trace.h>

#include <arch/arch_ops.h>

#include <lib/ktrace.h>
#include <lib/user_copy/user_ptr.h>
#include <object/handle.h>
#include <object/job_dispatcher.h>
#include <object/process_dispatcher.h>
#include <object/resource_dispatcher.h>
#include <object/suspend_token_dispatcher.h>
#include <object/thread_dispatcher.h>
#include <object/vm_address_region_dispatcher.h>

#include <fbl/auto_lock.h>
#include <fbl/inline_array.h>
#include <fbl/ref_ptr.h>
#include <fbl/string_piece.h>
#include <zircon/syscalls/debug.h>
#include <zircon/syscalls/policy.h>

#include "priv.h"

#define LOCAL_TRACE 0
#define THREAD_SET_PRIORITY_EXPERIMENT 1

#if THREAD_SET_PRIORITY_EXPERIMENT
#include <kernel/cmdline.h>
#include <kernel/thread.h>
#include <lk/init.h>
#endif

namespace {

constexpr size_t kMaxDebugReadBlock = 64 * 1024u * 1024u;
constexpr size_t kMaxDebugWriteBlock = 64 * 1024u * 1024u;

// Assume the typical set-policy call has 8 items or less.
constexpr size_t kPolicyBasicInlineCount = 8;

#if THREAD_SET_PRIORITY_EXPERIMENT
// This was initially set to false by default. See ZX-940 for the rationale
// for being enabled by default.
bool thread_set_priority_allowed = true;
void thread_set_priority_experiment_init_hook(uint) {
    thread_set_priority_allowed = !cmdline_get_bool("thread.set.priority.disable", false);
    printf("thread set priority experiment is : %s\n",
           thread_set_priority_allowed ? "ENABLED" : "DISABLED");
}
LK_INIT_HOOK(thread_set_priority_experiment,
             thread_set_priority_experiment_init_hook,
             LK_INIT_LEVEL_THREADING - 1);
#endif

// TODO(ZX-1025): copy_user_string may truncate the incoming string,
// and may copy extra data past the NUL.
// TODO(dbort): If anyone else needs this, move it into user_ptr.
zx_status_t copy_user_string(const user_in_ptr<const char>& src,
                             size_t src_len,
                             char* buf, size_t buf_len,
                             fbl::StringPiece* sp) {
    if (!src || src_len > buf_len) {
        return ZX_ERR_INVALID_ARGS;
    }
    zx_status_t result = src.copy_array_from_user(buf, src_len);
    if (result != ZX_OK) {
        return ZX_ERR_INVALID_ARGS;
    }

    // ensure zero termination
    size_t str_len = (src_len == buf_len ? src_len - 1 : src_len);
    buf[str_len] = 0;
    *sp = fbl::StringPiece(buf);

    return ZX_OK;
}

// Convenience function to go from process handle to process.
zx_status_t get_process(ProcessDispatcher* up,
                        zx_handle_t proc_handle,
                        fbl::RefPtr<ProcessDispatcher>* proc) {
    return up->GetDispatcherWithRights(proc_handle, ZX_RIGHT_WRITE, proc);
}

// This represents the local storage for thread_read/write_state. It should be large enough to
// handle all structures passed over these APIs.
union thread_state_local_buffer_t {
    zx_thread_state_general_regs_t general_regs; // ZX_THREAD_STATE_GENERAL_REGS
    zx_thread_state_fp_regs_t fp_regs;           // ZX_THREAD_STATE_FP_REGS
    zx_thread_state_vector_regs_t vector_regs;   // ZX_THREAD_STATE_VECTOR_REGS
    uint32_t single_step;                        // ZX_THREAD_STATE_SINGLE_STEP
    uint64_t x86_register_fs;                    // ZX_THREAD_X86_REGISTER_FS;
    uint64_t x86_register_gs;                    // ZX_THREAD_X86_REGISTER_GS;
};

// Validates the input topic to thread_read_state and thread_write_state is a valid value, and
// checks that the input buffer size is at least as large as necessary for the topic. On ZX_OK, the
// actual size necessary for the buffer will be placed in the output parameter.
zx_status_t validate_thread_state_input(uint32_t in_topic, size_t in_len, size_t* out_len) {
    switch (in_topic) {
    case ZX_THREAD_STATE_GENERAL_REGS:
        *out_len = sizeof(zx_thread_state_general_regs_t);
        break;
    case ZX_THREAD_STATE_FP_REGS:
        *out_len = sizeof(zx_thread_state_fp_regs_t);
        break;
    case ZX_THREAD_STATE_VECTOR_REGS:
        *out_len = sizeof(zx_thread_state_vector_regs_t);
        break;
    case ZX_THREAD_STATE_SINGLE_STEP:
        *out_len = sizeof(zx_thread_state_single_step_t);
        break;
    case ZX_THREAD_X86_REGISTER_FS:
        *out_len = sizeof(zx_thread_x86_register_fs_t);
        break;
    case ZX_THREAD_X86_REGISTER_GS:
        *out_len = sizeof(zx_thread_x86_register_gs_t);
        break;
    default:
        return ZX_ERR_INVALID_ARGS;
    }

    if (in_len < *out_len)
        return ZX_ERR_BUFFER_TOO_SMALL;
    return ZX_OK;
}

} // namespace

// zx_status_t zx_thread_create
zx_status_t sys_thread_create(zx_handle_t process_handle,
                              user_in_ptr<const char> _name, size_t name_len,
                              uint32_t options, user_out_handle* out) {
    LTRACEF("process handle %x, options %#x\n", process_handle, options);

    // currently, the only valid option value is 0
    if (options != 0)
        return ZX_ERR_INVALID_ARGS;

    // copy out the name
    char buf[ZX_MAX_NAME_LEN];
    fbl::StringPiece sp;
    // Silently truncate the given name.
    if (name_len > sizeof(buf))
        name_len = sizeof(buf);
    zx_status_t result = copy_user_string(_name, name_len,
                                          buf, sizeof(buf), &sp);
    if (result != ZX_OK)
        return result;
    LTRACEF("name %s\n", buf);

    // convert process handle to process dispatcher
    auto up = ProcessDispatcher::GetCurrent();

    fbl::RefPtr<ProcessDispatcher> process;
    result = get_process(up, process_handle, &process);
    if (result != ZX_OK)
        return result;

    uint32_t pid = (uint32_t)process->get_koid();

    // create the thread dispatcher
    fbl::RefPtr<Dispatcher> thread_dispatcher;
    zx_rights_t thread_rights;
    result = ThreadDispatcher::Create(fbl::move(process), options, sp,
                                      &thread_dispatcher, &thread_rights);
    if (result != ZX_OK)
        return result;

    uint32_t tid = (uint32_t)thread_dispatcher->get_koid();
    ktrace(TAG_THREAD_CREATE, tid, pid, 0, 0);
    ktrace_name(TAG_THREAD_NAME, tid, pid, buf);

    return out->make(fbl::move(thread_dispatcher), thread_rights);
}

// zx_status_t zx_thread_start
zx_status_t sys_thread_start(zx_handle_t thread_handle, zx_vaddr_t entry,
                             zx_vaddr_t stack, uintptr_t arg1, uintptr_t arg2) {
    LTRACEF("handle %x, entry %#" PRIxPTR ", sp %#" PRIxPTR
            ", arg1 %#" PRIxPTR ", arg2 %#" PRIxPTR "\n",
            thread_handle, entry, stack, arg1, arg2);

    auto up = ProcessDispatcher::GetCurrent();

    fbl::RefPtr<ThreadDispatcher> thread;
    zx_status_t status = up->GetDispatcherWithRights(thread_handle, ZX_RIGHT_MANAGE_THREAD,
                                                     &thread);
    if (status != ZX_OK) {
        // Try again, but with the WRITE right.
        // TODO(kulakowski) Remove this when all callers are using MANAGE_THREAD.
        status = up->GetDispatcherWithRights(thread_handle, ZX_RIGHT_WRITE, &thread);
        if (status != ZX_OK)
            return status;
    }

    ktrace(TAG_THREAD_START, (uint32_t)thread->get_koid(), 0, 0, 0);
    return thread->Start(entry, stack, arg1, arg2, /* initial_thread= */ false);
}

void sys_thread_exit() {
    LTRACE_ENTRY;
    ThreadDispatcher::GetCurrent()->Exit();
}

// zx_status_t zx_thread_read_state
zx_status_t sys_thread_read_state(zx_handle_t handle, uint32_t state_kind,
                                  user_out_ptr<void> _buffer, size_t buffer_len) {
    LTRACEF("handle %x, state_kind %u\n", handle, state_kind);

    auto up = ProcessDispatcher::GetCurrent();

    // TODO(ZX-968): debug rights
    fbl::RefPtr<ThreadDispatcher> thread;
    zx_status_t status = up->GetDispatcherWithRights(handle, ZX_RIGHT_READ, &thread);
    if (status != ZX_OK)
        return status;

    thread_state_local_buffer_t local_buffer;
    size_t local_buffer_len = 0;
    status = validate_thread_state_input(state_kind, buffer_len, &local_buffer_len);
    if (status != ZX_OK)
        return status;

    status = thread->ReadState(static_cast<zx_thread_state_topic_t>(state_kind), &local_buffer,
                               local_buffer_len);
    if (status != ZX_OK)
        return status;

    if (_buffer.copy_array_to_user(&local_buffer, local_buffer_len) != ZX_OK)
        return ZX_ERR_INVALID_ARGS;
    return ZX_OK;
}

// zx_status_t zx_thread_write_state
zx_status_t sys_thread_write_state(zx_handle_t handle, uint32_t state_kind,
                                   user_in_ptr<const void> _buffer, size_t buffer_len) {
    LTRACEF("handle %x, state_kind %u\n", handle, state_kind);

    auto up = ProcessDispatcher::GetCurrent();

    // TODO(ZX-968): debug rights
    fbl::RefPtr<ThreadDispatcher> thread;
    zx_status_t status = up->GetDispatcherWithRights(handle, ZX_RIGHT_WRITE, &thread);
    if (status != ZX_OK)
        return status;

    thread_state_local_buffer_t local_buffer;
    size_t local_buffer_len = 0;
    status = validate_thread_state_input(state_kind, buffer_len, &local_buffer_len);
    if (status != ZX_OK)
        return status;

    // Additionally check that the buffer is the exact size expected (validate only checks it's
    // larger, which is sufficient for reading).
    if (local_buffer_len != buffer_len)
        return ZX_ERR_INVALID_ARGS;

    status = _buffer.copy_array_from_user(&local_buffer, local_buffer_len);
    if (status != ZX_OK)
        return ZX_ERR_INVALID_ARGS;

    return thread->WriteState(static_cast<zx_thread_state_topic_t>(state_kind), &local_buffer,
                              local_buffer_len);
}

// See ZX-940
// zx_status_t zx_thread_set_priority
zx_status_t sys_thread_set_priority(int32_t prio) {
#if THREAD_SET_PRIORITY_EXPERIMENT
    // If the experimental zx_thread_set_priority has not been enabled using the
    // kernel command line option, simply deny this request.
    if (!thread_set_priority_allowed)
        return ZX_ERR_NOT_SUPPORTED;

    if ((prio < LOWEST_PRIORITY) || (prio > HIGHEST_PRIORITY))
        return ZX_ERR_INVALID_ARGS;

    thread_set_priority(get_current_thread(), prio);

    return ZX_OK;
#else
    return ZX_ERR_NOT_SUPPORTED;
#endif
}

// zx_status_t zx_task_suspend
zx_status_t sys_task_suspend(zx_handle_t task_handle, user_out_handle* token) {
    LTRACE_ENTRY;

    auto up = ProcessDispatcher::GetCurrent();

    // TODO(ZX-1840): Add support for tasks other than threads
    fbl::RefPtr<ThreadDispatcher> thread;
    zx_status_t status = up->GetDispatcherWithRights(task_handle, ZX_RIGHT_WRITE,
                                                     &thread);
    if (status != ZX_OK)
        return status;

    fbl::RefPtr<Dispatcher> suspend_token;
    zx_rights_t rights;
    status = SuspendTokenDispatcher::Create(fbl::move(thread), &suspend_token, &rights);
    if (status == ZX_OK)
        status = token->make(fbl::move(suspend_token), rights);
    return status;
}

// zx_status_t zx_task_suspend_token
zx_status_t sys_task_suspend_token(zx_handle_t task_handle, user_out_handle* token) {
    return sys_task_suspend(task_handle, token);
}

// zx_status_t zx_process_create
zx_status_t sys_process_create(zx_handle_t job_handle,
                               user_in_ptr<const char> _name, size_t name_len,
                               uint32_t options,
                               user_out_handle* proc_handle,
                               user_out_handle* vmar_handle) {
    LTRACEF("job handle %x, options %#x\n", job_handle, options);

    // currently, the only valid option value is 0
    if (options != 0)
        return ZX_ERR_INVALID_ARGS;

    auto up = ProcessDispatcher::GetCurrent();

    // We check the policy against the process calling zx_process_create, which
    // is the operative policy, rather than against |job_handle|. Access to
    // |job_handle| is controlled by the rights associated with the handle.
    zx_status_t result = up->QueryPolicy(ZX_POL_NEW_PROCESS);
    if (result != ZX_OK)
        return result;

    // copy out the name
    char buf[ZX_MAX_NAME_LEN];
    fbl::StringPiece sp;
    // Silently truncate the given name.
    if (name_len > sizeof(buf))
        name_len = sizeof(buf);
    result = copy_user_string(_name, name_len, buf, sizeof(buf), &sp);
    if (result != ZX_OK)
        return result;
    LTRACEF("name %s\n", buf);

    fbl::RefPtr<JobDispatcher> job;
    // TODO(ZX-968): define process creation job rights.
    auto status = up->GetDispatcherWithRights(job_handle, ZX_RIGHT_WRITE, &job);
    if (status != ZX_OK)
        return status;

    // create a new process dispatcher
    fbl::RefPtr<Dispatcher> proc_dispatcher;
    fbl::RefPtr<VmAddressRegionDispatcher> vmar_dispatcher;
    zx_rights_t proc_rights, vmar_rights;
    result = ProcessDispatcher::Create(fbl::move(job), sp, options,
                                       &proc_dispatcher, &proc_rights,
                                       &vmar_dispatcher, &vmar_rights);
    if (result != ZX_OK)
        return result;

    uint32_t koid = (uint32_t)proc_dispatcher->get_koid();
    ktrace(TAG_PROC_CREATE, koid, 0, 0, 0);
    ktrace_name(TAG_PROC_NAME, koid, 0, buf);

    // Give arch-specific tracing a chance to record process creation.
    arch_trace_process_create(koid, vmar_dispatcher->vmar()->aspace()->arch_aspace().arch_table_phys());

    result = proc_handle->make(fbl::move(proc_dispatcher), proc_rights);
    if (result == ZX_OK)
        result = vmar_handle->make(fbl::move(vmar_dispatcher), vmar_rights);
    return result;
}

// Note: This is used to start the main thread (as opposed to using
// sys_thread_start for that) for a few reasons:
// - less easily exploitable
//   We want to make sure we can't generically transfer handles to a process.
//   This has the nice property of restricting the evil (transferring handle
//   to new process) to exactly one spot, and can be called exactly once per
//   process, since it also pushes it into a new state.
// - maintains the state machine invariant that 'started' processes have one
//   thread running

// zx_status_t zx_process_start
zx_status_t sys_process_start(zx_handle_t process_handle, zx_handle_t thread_handle,
                              zx_vaddr_t pc, zx_vaddr_t sp,
                              zx_handle_t arg_handle_value, uintptr_t arg2) {
    LTRACEF("phandle %x, thandle %x, pc %#" PRIxPTR ", sp %#" PRIxPTR
            ", arg_handle %x, arg2 %#" PRIxPTR "\n",
            process_handle, thread_handle, pc, sp, arg_handle_value, arg2);

    auto up = ProcessDispatcher::GetCurrent();

    // get process dispatcher
    fbl::RefPtr<ProcessDispatcher> process;
    zx_status_t status = get_process(up, process_handle, &process);
    if (status != ZX_OK) {
        up->RemoveHandle(arg_handle_value);
        return status;
    }

    // get thread_dispatcher
    fbl::RefPtr<ThreadDispatcher> thread;
    status = up->GetDispatcherWithRights(thread_handle, ZX_RIGHT_WRITE, &thread);
    if (status != ZX_OK) {
        up->RemoveHandle(arg_handle_value);
        return status;
    }

    HandleOwner arg_handle = up->RemoveHandle(arg_handle_value);

    // test that the thread belongs to the starting process
    if (thread->process() != process.get())
        return ZX_ERR_ACCESS_DENIED;
    if (!arg_handle)
        return ZX_ERR_BAD_HANDLE;
    if (!arg_handle->HasRights(ZX_RIGHT_TRANSFER))
        return ZX_ERR_ACCESS_DENIED;

    auto arg_nhv = process->MapHandleToValue(arg_handle);
    process->AddHandle(fbl::move(arg_handle));

    status = thread->Start(pc, sp, static_cast<uintptr_t>(arg_nhv),
                           arg2, /* initial_thread */ true);
    if (status != ZX_OK) {
        // Remove |arg_handle| from the process that failed to start.
        process->RemoveHandle(arg_nhv);
        return status;
    }

    ktrace(TAG_PROC_START, (uint32_t)thread->get_koid(),
           (uint32_t)process->get_koid(), 0, 0);

    return ZX_OK;
}

void sys_process_exit(int64_t retcode) {
    LTRACEF("retcode %" PRId64 "\n", retcode);
    ProcessDispatcher::GetCurrent()->Exit(retcode);
}

// zx_status_t zx_process_read_memory
zx_status_t sys_process_read_memory(zx_handle_t proc, zx_vaddr_t vaddr,
                                    user_out_ptr<void> _buffer,
                                    size_t len, user_out_ptr<size_t> _actual) {
    LTRACEF("vaddr 0x%" PRIxPTR ", size %zu\n", vaddr, len);

    if (!_buffer)
        return ZX_ERR_INVALID_ARGS;
    if (len == 0 || len > kMaxDebugReadBlock)
        return ZX_ERR_INVALID_ARGS;

    auto up = ProcessDispatcher::GetCurrent();

    fbl::RefPtr<ProcessDispatcher> process;
    zx_status_t status = up->GetDispatcherWithRights(proc, ZX_RIGHT_READ | ZX_RIGHT_WRITE,
                                                     &process);
    if (status != ZX_OK)
        return status;

    auto aspace = process->aspace();
    if (!aspace)
        return ZX_ERR_BAD_STATE;

    auto region = aspace->FindRegion(vaddr);
    if (!region)
        return ZX_ERR_NO_MEMORY;

    auto vm_mapping = region->as_vm_mapping();
    if (!vm_mapping)
        return ZX_ERR_NO_MEMORY;

    auto vmo = vm_mapping->vmo();
    if (!vmo)
        return ZX_ERR_NO_MEMORY;

    // Force map the range, even if it crosses multiple mappings.
    // TODO(ZX-730): This is a workaround for this bug.  If we start decommitting
    // things, the bug will come back.  We should fix this more properly.
    {
        uint8_t byte = 0;
        auto int_data = _buffer.reinterpret<uint8_t>();
        for (size_t i = 0; i < len; i += PAGE_SIZE) {
            status = int_data.copy_array_to_user(&byte, 1, i);
            if (status != ZX_OK) {
                return status;
            }
        }
        if (len > 0) {
            status = int_data.copy_array_to_user(&byte, 1, len - 1);
            if (status != ZX_OK) {
                return status;
            }
        }
    }

    uint64_t offset = vaddr - vm_mapping->base() + vm_mapping->object_offset();
    // TODO(ZX-1631): While this limits reading to the mapped address space of
    // this VMO, it should be reading from multiple VMOs, not a single one.
    // Additionally, it is racy with the mapping going away.
    len = MIN(len, vm_mapping->size() - (vaddr - vm_mapping->base()));
    zx_status_t st = vmo->ReadUser(_buffer, offset, len);

    if (st == ZX_OK) {
        zx_status_t status = _actual.copy_to_user(static_cast<size_t>(len));
        if (status != ZX_OK)
            return status;
    }
    return st;
}

// zx_status_t zx_process_write_memory
zx_status_t sys_process_write_memory(zx_handle_t proc, zx_vaddr_t vaddr,
                                     user_in_ptr<const void> _buffer,
                                     size_t len, user_out_ptr<size_t> _actual) {
    LTRACEF("vaddr 0x%" PRIxPTR ", size %zu\n", vaddr, len);

    if (!_buffer)
        return ZX_ERR_INVALID_ARGS;
    if (len == 0 || len > kMaxDebugWriteBlock)
        return ZX_ERR_INVALID_ARGS;

    auto up = ProcessDispatcher::GetCurrent();

    fbl::RefPtr<ProcessDispatcher> process;
    zx_status_t status = up->GetDispatcherWithRights(proc, ZX_RIGHT_WRITE, &process);
    if (status != ZX_OK)
        return status;

    auto aspace = process->aspace();
    if (!aspace)
        return ZX_ERR_BAD_STATE;

    auto region = aspace->FindRegion(vaddr);
    if (!region)
        return ZX_ERR_NO_MEMORY;

    auto vm_mapping = region->as_vm_mapping();
    if (!vm_mapping)
        return ZX_ERR_NO_MEMORY;

    auto vmo = vm_mapping->vmo();
    if (!vmo)
        return ZX_ERR_NO_MEMORY;

    // Force map the range, even if it crosses multiple mappings.
    // TODO(ZX-730): This is a workaround for this bug.  If we start decommitting
    // things, the bug will come back.  We should fix this more properly.
    {
        uint8_t byte = 0;
        auto int_data = _buffer.reinterpret<const uint8_t>();
        for (size_t i = 0; i < len; i += PAGE_SIZE) {
            status = int_data.copy_array_from_user(&byte, 1, i);
            if (status != ZX_OK) {
                return status;
            }
        }
        if (len > 0) {
            status = int_data.copy_array_from_user(&byte, 1, len - 1);
            if (status != ZX_OK) {
                return status;
            }
        }
    }

    uint64_t offset = vaddr - vm_mapping->base() + vm_mapping->object_offset();
    // TODO(ZX-1631): While this limits writing to the mapped address space of
    // this VMO, it should be writing to multiple VMOs, not a single one.
    // Additionally, it is racy with the mapping going away.
    len = MIN(len, vm_mapping->size() - (vaddr - vm_mapping->base()));
    zx_status_t st = vmo->WriteUser(_buffer, offset, len);

    if (st == ZX_OK) {
        zx_status_t status = _actual.copy_to_user(static_cast<size_t>(len));
        if (status != ZX_OK)
            return status;
    }
    return st;
}

// helper routine for sys_task_kill
template <typename T>
static zx_status_t kill_task(fbl::RefPtr<Dispatcher> dispatcher) {
    auto task = DownCastDispatcher<T>(&dispatcher);
    if (!task)
        return ZX_ERR_WRONG_TYPE;

    task->Kill();
    return ZX_OK;
}

// zx_status_t zx_task_kill
zx_status_t sys_task_kill(zx_handle_t task_handle) {
    LTRACEF("handle %x\n", task_handle);

    auto up = ProcessDispatcher::GetCurrent();

    fbl::RefPtr<Dispatcher> dispatcher;
    auto status = up->GetDispatcherWithRights(task_handle, ZX_RIGHT_DESTROY, &dispatcher);
    if (status != ZX_OK)
        return status;

    // see if it's a process or thread and dispatch accordingly
    switch (dispatcher->get_type()) {
    case ZX_OBJ_TYPE_PROCESS:
        return kill_task<ProcessDispatcher>(fbl::move(dispatcher));
    case ZX_OBJ_TYPE_THREAD:
        return kill_task<ThreadDispatcher>(fbl::move(dispatcher));
    case ZX_OBJ_TYPE_JOB:
        return kill_task<JobDispatcher>(fbl::move(dispatcher));
    default:
        return ZX_ERR_WRONG_TYPE;
    }
}

// zx_status_t zx_job_create
zx_status_t sys_job_create(zx_handle_t parent_job, uint32_t options,
                           user_out_handle* out) {
    LTRACEF("parent: %x\n", parent_job);

    if (options != 0u)
        return ZX_ERR_INVALID_ARGS;

    auto up = ProcessDispatcher::GetCurrent();

    fbl::RefPtr<JobDispatcher> parent;
    zx_status_t status = up->GetDispatcherWithRights(parent_job, ZX_RIGHT_MANAGE_JOB, &parent);
    if (status != ZX_OK) {
        // Try again, but with the WRITE right.
        // TODO(kulakowski) Remove this when all callers are using MANAGE_JOB.
        status = up->GetDispatcherWithRights(parent_job, ZX_RIGHT_WRITE, &parent);
        if (status != ZX_OK) {
            return status;
        }
    }

    fbl::RefPtr<Dispatcher> job;
    zx_rights_t rights;
    status = JobDispatcher::Create(options, fbl::move(parent), &job, &rights);
    if (status == ZX_OK)
        status = out->make(fbl::move(job), rights);
    return status;
}

// zx_status_t zx_job_set_policy
zx_status_t sys_job_set_policy(zx_handle_t job_handle, uint32_t options,
                               uint32_t topic, user_in_ptr<const void> _policy,
                               uint32_t count) {

    if ((options != ZX_JOB_POL_RELATIVE) && (options != ZX_JOB_POL_ABSOLUTE))
        return ZX_ERR_INVALID_ARGS;
    if (!_policy || (count == 0u))
        return ZX_ERR_INVALID_ARGS;

    if (topic != ZX_JOB_POL_BASIC)
        return ZX_ERR_INVALID_ARGS;

    fbl::AllocChecker ac;
    fbl::InlineArray<
        zx_policy_basic, kPolicyBasicInlineCount>
        policy(&ac, count);
    if (!ac.check())
        return ZX_ERR_NO_MEMORY;

    auto status = _policy.copy_array_from_user(policy.get(), sizeof(zx_policy_basic) * count);
    if (status != ZX_OK)
        return ZX_ERR_INVALID_ARGS;

    auto up = ProcessDispatcher::GetCurrent();

    fbl::RefPtr<JobDispatcher> job;
    status = up->GetDispatcherWithRights(job_handle, ZX_RIGHT_SET_POLICY, &job);
    if (status != ZX_OK)
        return status;

    return job->SetPolicy(options, policy.get(), policy.size());
}
