kernel: remove support for sending kernel handles via port/channel

This commit is contained in:
2026-02-26 20:50:34 +00:00
parent b59d0d8948
commit 634f4517c8
17 changed files with 231 additions and 370 deletions

View File

@@ -35,9 +35,7 @@ static const virt_addr_t syscall_table[] = {
SYSCALL_TABLE_ENTRY(MSG_RECV, msg_recv),
SYSCALL_TABLE_ENTRY(MSG_REPLY, msg_reply),
SYSCALL_TABLE_ENTRY(MSG_READ, msg_read),
SYSCALL_TABLE_ENTRY(MSG_READ_HANDLES, msg_read_handles),
SYSCALL_TABLE_ENTRY(MSG_WRITE, msg_write),
SYSCALL_TABLE_ENTRY(MSG_WRITE_HANDLES, msg_write_handles),
};
static const size_t syscall_table_count
= sizeof syscall_table / sizeof syscall_table[0];

View File

@@ -4,6 +4,6 @@
kern_status_t sys_kern_log(const char *s)
{
struct task *task = current_task();
printk("%s: %s", task->t_name, s);
printk("%s[%d]: %s", task->t_name, task->t_id, s);
return KERN_OK;
}

View File

@@ -5,10 +5,7 @@
#include <kernel/syscall.h>
#include <kernel/vm-region.h>
kern_status_t sys_channel_create(
unsigned int id,
channel_flags_t flags,
kern_handle_t *out)
kern_status_t sys_channel_create(unsigned int id, kern_handle_t *out)
{
struct task *self = current_task();
if (!validate_access_w(self, out, sizeof *out)) {
@@ -185,69 +182,21 @@ static bool validate_iovec(
return true;
}
static bool validate_msg(struct task *task, const struct msg *msg, bool rw)
{
if (!validate_access_r(task, msg, sizeof *msg)) {
return false;
}
if (msg->msg_data_count
&& !validate_access_r(
task,
msg->msg_data,
sizeof(struct iovec) * msg->msg_data_count)) {
return false;
}
if (msg->msg_handles_count
&& !validate_access_r(
task,
msg->msg_handles,
sizeof(struct handle_list) * msg->msg_handles_count)) {
return false;
}
if (!validate_iovec(task, msg->msg_data, msg->msg_data_count, rw)) {
return false;
}
for (size_t i = 0; i < msg->msg_handles_count; i++) {
bool ok = false;
const struct handle_list *list = &msg->msg_handles[i];
if (rw) {
ok = validate_access_w(
task,
list->l_handles,
list->l_nr_handles * sizeof(kern_handle_t));
} else {
ok = validate_access_r(
task,
list->l_handles,
list->l_nr_handles * sizeof(kern_handle_t));
}
if (!ok) {
return false;
}
}
return true;
}
kern_status_t sys_msg_send(
kern_handle_t port_handle,
msg_flags_t msg_flags,
const struct msg *req,
struct msg *resp)
const struct iovec *req_data,
size_t req_data_count,
struct iovec *resp_data,
size_t resp_data_count)
{
struct task *self = current_task();
if (!validate_msg(self, req, false)) {
return KERN_MEMORY_FAULT;
if (!validate_iovec(self, req_data, req_data_count, false)) {
return false;
}
if (!validate_msg(self, resp, true)) {
return KERN_MEMORY_FAULT;
if (!validate_iovec(self, resp_data, resp_data_count, true)) {
return false;
}
unsigned long flags;
@@ -277,7 +226,13 @@ kern_status_t sys_msg_send(
}
port_lock_irqsave(port, &flags);
status = port_send_msg(port, req, resp, &flags);
status = port_send_msg(
port,
req_data,
req_data_count,
resp_data,
resp_data_count,
&flags);
port_unlock_irqrestore(port, flags);
object_unref(port_obj);
@@ -286,9 +241,9 @@ kern_status_t sys_msg_send(
kern_status_t sys_msg_recv(
kern_handle_t channel_handle,
msg_flags_t msg_flags,
msgid_t *out_id,
struct msg *out_msg)
struct iovec *out_data,
size_t out_data_count)
{
struct task *self = current_task();
@@ -296,7 +251,7 @@ kern_status_t sys_msg_recv(
return KERN_MEMORY_FAULT;
}
if (!validate_msg(self, out_msg, true)) {
if (!validate_iovec(self, out_data, out_data_count, true)) {
return KERN_MEMORY_FAULT;
}
@@ -327,7 +282,12 @@ kern_status_t sys_msg_recv(
}
channel_lock_irqsave(channel, &flags);
status = channel_recv_msg(channel, out_msg, out_id, &flags);
status = channel_recv_msg(
channel,
out_id,
out_data,
out_data_count,
&flags);
channel_unlock_irqrestore(channel, flags);
object_unref(channel_obj);
@@ -336,13 +296,13 @@ kern_status_t sys_msg_recv(
kern_status_t sys_msg_reply(
kern_handle_t channel_handle,
msg_flags_t msg_flags,
msgid_t id,
const struct msg *reply)
const struct iovec *reply_data,
size_t reply_data_count)
{
struct task *self = current_task();
if (!validate_msg(self, reply, false)) {
if (!validate_iovec(self, reply_data, reply_data_count, false)) {
return KERN_MEMORY_FAULT;
}
@@ -373,7 +333,12 @@ kern_status_t sys_msg_reply(
}
channel_lock_irqsave(channel, &flags);
status = channel_reply_msg(channel, id, reply, &flags);
status = channel_reply_msg(
channel,
id,
reply_data,
reply_data_count,
&flags);
channel_unlock_irqrestore(channel, flags);
object_unref(channel_obj);
@@ -390,6 +355,14 @@ kern_status_t sys_msg_read(
{
struct task *self = current_task();
if (nr_read && !validate_access_w(self, nr_read, sizeof *nr_read)) {
return KERN_MEMORY_FAULT;
}
if (!validate_iovec(self, iov, iov_count, true)) {
return KERN_MEMORY_FAULT;
}
unsigned long flags;
task_lock_irqsave(self, &flags);
@@ -431,32 +404,62 @@ kern_status_t sys_msg_read(
return status;
}
kern_status_t sys_msg_read_handles(
kern_handle_t channel,
msgid_t id,
size_t offset,
struct handle_list *out,
size_t nr_out)
{
return KERN_UNIMPLEMENTED;
}
kern_status_t sys_msg_write(
kern_handle_t channel,
kern_handle_t channel_handle,
msgid_t id,
size_t offset,
const struct iovec *in,
size_t nr_in)
const struct iovec *iov,
size_t iov_count,
size_t *nr_written)
{
return KERN_UNIMPLEMENTED;
}
struct task *self = current_task();
kern_status_t sys_msg_write_handles(
kern_handle_t channel,
msgid_t id,
size_t offset,
const struct handle_list *in,
size_t nr_in)
{
return KERN_UNIMPLEMENTED;
if (nr_written
&& !validate_access_w(self, nr_written, sizeof *nr_written)) {
return KERN_MEMORY_FAULT;
}
if (!validate_iovec(self, iov, iov_count, false)) {
return KERN_MEMORY_FAULT;
}
unsigned long flags;
task_lock_irqsave(self, &flags);
struct object *channel_obj = NULL;
handle_flags_t channel_handle_flags = 0;
kern_status_t status = task_resolve_handle(
self,
channel_handle,
&channel_obj,
&channel_handle_flags);
if (status != KERN_OK) {
return status;
}
/* add a reference to the port object to make sure it isn't deleted
* while we're using it */
object_ref(channel_obj);
task_unlock_irqrestore(self, flags);
struct channel *channel = channel_cast(channel_obj);
if (!channel) {
object_unref(channel_obj);
return KERN_INVALID_ARGUMENT;
}
channel_lock_irqsave(channel, &flags);
status = channel_write_msg(
channel,
id,
offset,
self->t_address_space,
iov,
iov_count,
nr_written);
channel_unlock_irqrestore(channel, flags);
object_unref(channel_obj);
return status;
}

View File

@@ -6,9 +6,10 @@
extern kern_status_t sys_task_exit(int status)
{
struct task *self = current_task();
printk("%s[%d]: task_exit(%d)", self->t_name, self->t_id, status);
while (1) {
printk("sys_exit(%d)", status);
milli_sleep(1000);
milli_sleep(5000);
}
return KERN_UNIMPLEMENTED;