[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:
@@ -60,16 +60,15 @@ channel_pump_loop()
|
||||
return 3;
|
||||
|
||||
uint64_t tag = j6_proto_sl_register;
|
||||
uint64_t data = "jsix.protocol.stream.ouput"_id;
|
||||
size_t data_len = sizeof(data);
|
||||
uint64_t proto_id = "jsix.protocol.stream.ouput"_id;
|
||||
size_t handle_count = 1;
|
||||
result = j6_mailbox_call(slp, &tag,
|
||||
&data, &data_len,
|
||||
result = j6_mailbox_call(slp,
|
||||
&tag, &proto_id,
|
||||
&cout_write, &handle_count);
|
||||
if (result != j6_status_ok)
|
||||
return 4;
|
||||
|
||||
if (tag != j6_proto_base_status || data != j6_status_ok)
|
||||
if (tag != j6_proto_base_status)
|
||||
return 5;
|
||||
|
||||
result = j6_system_request_iopl(g_handle_sys, 3);
|
||||
|
||||
@@ -57,13 +57,13 @@ load_program(
|
||||
return false;
|
||||
}
|
||||
|
||||
res = j6_process_give_handle(proc, sys, nullptr);
|
||||
res = j6_process_give_handle(proc, sys);
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': giving system handle: %lx", prog.filename, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
res = j6_process_give_handle(proc, slp, nullptr);
|
||||
res = j6_process_give_handle(proc, slp);
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': giving SLP handle: %lx", prog.filename, res);
|
||||
return false;
|
||||
|
||||
@@ -5,71 +5,72 @@
|
||||
#include <j6/types.h>
|
||||
#include <j6/protocols/service_locator.h>
|
||||
#include <j6/syscalls.h>
|
||||
#include <util/map.h>
|
||||
#include <util/node_map.h>
|
||||
|
||||
#include "service_locator.h"
|
||||
|
||||
struct handle_entry
|
||||
{
|
||||
uint64_t protocol;
|
||||
j6_handle_t handle;
|
||||
};
|
||||
|
||||
uint64_t & get_map_key(handle_entry &e) { return e.protocol; }
|
||||
|
||||
void
|
||||
service_locator_start(j6_handle_t mb)
|
||||
{
|
||||
// TODO: This should be a multimap
|
||||
util::map<uint64_t, j6_handle_t> services;
|
||||
util::node_map<uint64_t, handle_entry> services;
|
||||
|
||||
uint64_t tag;
|
||||
uint64_t subtag;
|
||||
uint16_t reply_tag;
|
||||
|
||||
uint8_t data[100];
|
||||
size_t data_len = sizeof(data);
|
||||
|
||||
j6_handle_t handles[10];
|
||||
size_t handles_count = sizeof(handles)/sizeof(j6_handle_t);
|
||||
|
||||
j6_status_t s = j6_mailbox_receive(mb, &tag,
|
||||
data, &data_len,
|
||||
j6_status_t s = j6_mailbox_receive(mb,
|
||||
&tag, &subtag,
|
||||
handles, &handles_count,
|
||||
&reply_tag, nullptr,
|
||||
&reply_tag,
|
||||
j6_mailbox_block);
|
||||
|
||||
uint64_t proto_id;
|
||||
uint64_t *data_words = reinterpret_cast<uint64_t*>(data);
|
||||
|
||||
while (true) {
|
||||
j6_handle_t *found = nullptr;
|
||||
handle_entry *found = nullptr;
|
||||
|
||||
switch (tag) {
|
||||
case j6_proto_base_get_proto_id:
|
||||
tag = j6_proto_base_proto_id;
|
||||
*data_words = j6_proto_sl_id;
|
||||
data_len = sizeof(j6_status_t);
|
||||
subtag = j6_proto_sl_id;
|
||||
handles_count = 0;
|
||||
break;
|
||||
|
||||
case j6_proto_sl_register:
|
||||
proto_id = *data_words;
|
||||
proto_id = subtag;
|
||||
if (handles_count != 1) {
|
||||
tag = j6_proto_base_status;
|
||||
*data_words = j6_err_invalid_arg;
|
||||
data_len = sizeof(j6_status_t);
|
||||
subtag = j6_err_invalid_arg;
|
||||
handles_count = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
services.insert( proto_id, handles[0] );
|
||||
services.insert( {proto_id, handles[0]} );
|
||||
tag = j6_proto_base_status;
|
||||
*data_words = j6_status_ok;
|
||||
data_len = sizeof(j6_status_t);
|
||||
subtag = j6_status_ok;
|
||||
handles_count = 0;
|
||||
break;
|
||||
|
||||
case j6_proto_sl_find:
|
||||
proto_id = *data_words;
|
||||
proto_id = subtag;
|
||||
tag = j6_proto_sl_result;
|
||||
data_len = 0;
|
||||
|
||||
found = services.find(proto_id);
|
||||
if (found) {
|
||||
handles_count = 1;
|
||||
handles[0] = *found;
|
||||
handles[0] = found->handle;
|
||||
} else {
|
||||
handles_count = 0;
|
||||
}
|
||||
@@ -77,21 +78,18 @@ service_locator_start(j6_handle_t mb)
|
||||
|
||||
default:
|
||||
tag = j6_proto_base_status;
|
||||
*data_words = j6_err_invalid_arg;
|
||||
data_len = sizeof(j6_status_t);
|
||||
subtag = j6_err_invalid_arg;
|
||||
handles_count = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
size_t data_in = data_len;
|
||||
size_t handles_in = handles_count;
|
||||
data_len = sizeof(data);
|
||||
handles_count = sizeof(handles)/sizeof(j6_handle_t);
|
||||
|
||||
s = j6_mailbox_respond_receive(mb, &tag,
|
||||
data, &data_len, data_in,
|
||||
s = j6_mailbox_respond_receive(mb,
|
||||
&tag, &subtag,
|
||||
handles, &handles_count, handles_in,
|
||||
&reply_tag, nullptr,
|
||||
&reply_tag,
|
||||
j6_mailbox_block);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,6 @@ main(int argc, const char **argv)
|
||||
{
|
||||
j6_log("logging server starting");
|
||||
|
||||
j6_status_t result = j6_status_ok;
|
||||
|
||||
g_handle_sys = j6_find_first_handle(j6_object_type_system);
|
||||
if (g_handle_sys == j6_handle_invalid)
|
||||
@@ -123,22 +122,20 @@ main(int argc, const char **argv)
|
||||
|
||||
j6_handle_t cout = j6_handle_invalid;
|
||||
|
||||
for (unsigned i = 0; i < 5; ++i) {
|
||||
for (unsigned i = 0; i < 100; ++i) {
|
||||
uint64_t tag = j6_proto_sl_find;
|
||||
uint64_t proto_id = "jsix.protocol.stream.ouput"_id;
|
||||
size_t data_len = sizeof(proto_id);
|
||||
size_t handle_count = 0;
|
||||
|
||||
result = j6_mailbox_call(slp, &tag,
|
||||
&proto_id, &data_len,
|
||||
&cout, &handle_count);
|
||||
if (result == j6_status_ok &&
|
||||
j6_status_t s = j6_mailbox_call(slp, &tag,
|
||||
&proto_id, &cout, &handle_count);
|
||||
if (s == j6_status_ok &&
|
||||
tag == j6_proto_sl_result &&
|
||||
handle_count == 1)
|
||||
break;
|
||||
|
||||
cout = j6_handle_invalid;
|
||||
j6_thread_sleep(1000); // 1ms
|
||||
j6_thread_sleep(10000); // 10ms
|
||||
}
|
||||
|
||||
if (cout == j6_handle_invalid)
|
||||
|
||||
@@ -24,19 +24,16 @@ TEST_CASE( mailbox_tests, would_block )
|
||||
CHECK( s == j6_status_ok, "Could not create a mailbox" );
|
||||
|
||||
uint64_t tag = 12345;
|
||||
uint8_t buffer[128];
|
||||
size_t buffer_size = 128;
|
||||
uint64_t subtag = 67890;
|
||||
j6_handle_t handles[10];
|
||||
size_t handle_count = 10;
|
||||
uint16_t reply_tag = 0;
|
||||
uint64_t badge = 0;
|
||||
uint64_t flags = 0;
|
||||
|
||||
s = j6_mailbox_receive( mb, &tag,
|
||||
buffer, &buffer_size,
|
||||
s = j6_mailbox_receive( mb,
|
||||
&tag, &subtag,
|
||||
handles, &handle_count,
|
||||
&reply_tag, &badge,
|
||||
flags );
|
||||
&reply_tag, flags );
|
||||
CHECK( s == j6_status_would_block, "Should have gotten would block error" );
|
||||
|
||||
j6_mailbox_close(mb);
|
||||
@@ -51,37 +48,29 @@ TEST_CASE( mailbox_tests, send_receive )
|
||||
CHECK( s == j6_status_ok, "Could not create a mailbox" );
|
||||
|
||||
uint64_t out_tag = 12345;
|
||||
uint8_t out_buffer[128] = {2, 4, 6, 8, 10, 12, 14};
|
||||
size_t out_buffer_size = 7;
|
||||
uint64_t out_subtag = 67890;
|
||||
j6_handle_t out_handles[10];
|
||||
size_t out_handle_count = 0;
|
||||
|
||||
s = j6_mailbox_send( mb, out_tag,
|
||||
out_buffer, out_buffer_size,
|
||||
s = j6_mailbox_send( mb, out_tag, out_subtag,
|
||||
out_handles, out_handle_count );
|
||||
CHECK( s == j6_status_ok, "Did not send successfully" );
|
||||
|
||||
uint64_t in_tag = 0;
|
||||
uint8_t in_buffer[128];
|
||||
size_t in_buffer_size = 128;
|
||||
uint64_t in_subtag = 0;
|
||||
j6_handle_t in_handles[10];
|
||||
size_t in_handle_count = 10;
|
||||
uint16_t in_reply_tag = 0;
|
||||
uint64_t in_badge = 0;
|
||||
uint64_t in_flags = 0;
|
||||
|
||||
s = j6_mailbox_receive( mb, &in_tag,
|
||||
in_buffer, &in_buffer_size,
|
||||
s = j6_mailbox_receive( mb, &in_tag, &in_subtag,
|
||||
in_handles, &in_handle_count,
|
||||
&in_reply_tag, &in_badge,
|
||||
in_flags );
|
||||
&in_reply_tag, in_flags );
|
||||
CHECK( s == j6_status_ok, "Did not receive successfully" );
|
||||
|
||||
CHECK_BARE( in_tag == out_tag );
|
||||
CHECK_BARE( in_buffer_size == out_buffer_size );
|
||||
CHECK_BARE( in_subtag == out_subtag );
|
||||
CHECK_BARE( in_handle_count == out_handle_count );
|
||||
|
||||
CHECK_BARE( memcmp(out_buffer, in_buffer, in_buffer_size) == 0 );
|
||||
|
||||
j6_mailbox_close(mb);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user