[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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user