[kernel] Make capabilities/handles global

Instead of handles / capabilities having numeric ids that are only valid
for the owning process, they are now global in a system capabilities
table. This will allow for specifying capabilities in IPC that doesn't
need to be kernel-controlled.

Processes will still need to be granted access to given capabilities,
but that can become a simpler system call than the current method of
sending them through mailbox messages (and worse, having to translate
every one into a new capability like was the case before). In order to
track which handles a process has access to, a new node_set based on
node_map allows for an efficient storage and lookup of handles.
This commit is contained in:
Justin C. Miller
2022-10-10 21:19:25 -07:00
parent 41bb97b179
commit 9ac4e51224
27 changed files with 337 additions and 383 deletions

View File

@@ -4,6 +4,7 @@
#include <j6/types.h>
#include "capabilities.h"
#include "objects/kobject.h"
#include "objects/process.h"
@@ -12,41 +13,43 @@ namespace syscalls {
template <typename T, typename... Args>
T * construct_handle(j6_handle_t *id, Args... args)
{
obj::process &p = obj::process::current();
T *o = new T {args...};
*id = p.add_handle(o, T::creation_caps);
*id = g_cap_table.create(o, T::creation_caps);
obj::process &p = obj::process::current();
p.add_handle(*id);
return o;
}
template <typename T>
obj::handle * get_handle(j6_handle_t id)
j6_status_t get_handle(j6_handle_t id, j6_cap_t caps, T *&object)
{
capability *capdata = g_cap_table.find(id);
if (!capdata || capdata->type != T::type)
return j6_err_invalid_arg;
obj::process &p = obj::process::current();
obj::handle *h = p.lookup_handle(id);
if (!h || h->type() != T::type)
return nullptr;
return h;
if (!p.has_handle(id) || (capdata->caps & caps) != caps)
return j6_err_denied;
object = static_cast<T*>(capdata->object);
return j6_status_ok;
}
template <>
inline obj::handle * get_handle<obj::kobject>(j6_handle_t id)
inline j6_status_t get_handle<obj::kobject>(j6_handle_t id, j6_cap_t caps, obj::kobject *&object)
{
capability *capdata = g_cap_table.find(id);
if (!capdata)
return j6_err_invalid_arg;
obj::process &p = obj::process::current();
return p.lookup_handle(id);
if (!p.has_handle(id) || (capdata->caps & caps) != caps)
return j6_err_denied;
object = capdata->object;
return j6_status_ok;
}
template <typename T>
T * remove_handle(j6_handle_t id)
{
obj::handle *h = get_handle<T>(id);
T *o = nullptr;
if (h) {
o = h->object;
obj::process &p = obj::process::current();
p.remove_handle(id);
}
return o;
}
}
} // namespace syscalls