[kernel] Pass objects not handles to syscall impls

This commit contains a couple large, interdependent changes:

- In preparation for capability checking, the _syscall_verify_*
  functions now load most handles passed in, and verify that they exist
  and are of the correct type. Lists and out-handles are not converted
  to objects.
- Also in preparation for capability checking, the internal
  representation of handles has changed. j6_handle_t is now 32 bits, and
  a new j6_cap_t (also 32 bits) is added. Handles of a process are now a
  util::map<j6_handle_t, handle> where handle is a new struct containing
  the id, capabilities, and object pointer.
- The kernel object definition DSL gained a few changes to support auto
  generating the handle -> object conversion in the _syscall_verify_*
  functions, mostly knowing the object type, and an optional "cname"
  attribute on objects where their names differ from C++ code.
  (Specifically vma/vm_area)
- Kernel object code and other code under kernel/objects is now in a new
  obj:: namespace, because fuck you <cstdlib> for putting "system" in
  the global namespace. Why even have that header then?
- Kernel object types constructed with the construct_handle helper now
  have a creation_caps static member to declare what capabilities a
  newly created object's handle should have.
This commit is contained in:
Justin C. Miller
2022-01-17 23:23:04 -08:00
parent e0246df26b
commit 1d30322820
50 changed files with 492 additions and 300 deletions

View File

@@ -7,19 +7,22 @@
#include "objects/vm_area.h"
#include "scheduler.h"
// This object is initialized _before_ global constructors are called,
// so we don't want it to have a global constructor at all, lest it
// overwrite the previous initialization.
static util::no_construct<process> __g_kernel_process_storage;
process &g_kernel_process = __g_kernel_process_storage.value;
static util::no_construct<obj::process> __g_kernel_process_storage;
obj::process &g_kernel_process = __g_kernel_process_storage.value;
namespace obj {
process::process() :
kobject {kobject::type::process},
m_next_handle {1},
m_state {state::running}
{
j6_handle_t self = add_handle(this);
j6_handle_t self = add_handle(this, process::self_caps);
kassert(self == self_handle(), "Process self-handle is not 1");
}
@@ -34,8 +37,6 @@ process::process(page_table *kpml4) :
process::~process()
{
for (auto &it : m_handles)
if (it.val) it.val->handle_release();
}
process & process::current() { return *current_cpu().process; }
@@ -123,27 +124,27 @@ process::thread_exited(thread *th)
}
j6_handle_t
process::add_handle(kobject *obj)
process::add_handle(kobject *obj, j6_cap_t caps)
{
if (!obj)
return j6_handle_invalid;
obj->handle_retain();
j6_handle_t handle = m_next_handle++;
m_handles.insert(handle, obj);
return handle;
j6_handle_t id = m_next_handle++;
m_handles.insert(id, {id, obj, caps});
return id;
}
bool
process::remove_handle(j6_handle_t handle)
process::remove_handle(j6_handle_t id)
{
kobject *obj = m_handles.find(handle);
if (obj) obj->handle_release();
return m_handles.erase(handle);
return m_handles.erase(id);
}
kobject *
process::lookup_handle(j6_handle_t handle)
handle *
process::lookup_handle(j6_handle_t id)
{
return m_handles.find(handle);
return m_handles.find(id);
}
} // namespace obj