sched: enforce ref-counting on current task/thread pointers

This commit is contained in:
2026-04-01 18:17:05 +01:00
parent 15c2207ab9
commit 512356ac2d
28 changed files with 364 additions and 103 deletions
+47 -9
View File
@@ -7,13 +7,15 @@
kern_status_t sys_channel_create(unsigned int id, kern_handle_t *out)
{
struct task *self = current_task();
struct task *self = get_current_task();
if (!validate_access_w(self, out, sizeof *out)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
struct channel *channel = channel_create();
if (!channel) {
put_current_task(self);
return KERN_NO_MEMORY;
}
@@ -22,6 +24,7 @@ kern_status_t sys_channel_create(unsigned int id, kern_handle_t *out)
if (task_get_channel(self, id)) {
task_unlock_irqrestore(self, irq_flags);
put_current_task(self);
return KERN_NAME_EXISTS;
}
@@ -31,11 +34,13 @@ kern_status_t sys_channel_create(unsigned int id, kern_handle_t *out)
if (status != KERN_OK) {
task_unlock_irqrestore(self, irq_flags);
object_unref(&channel->c_base);
put_current_task(self);
return status;
}
task_add_channel(self, channel, id);
task_unlock_irqrestore(self, irq_flags);
put_current_task(self);
*out = handle;
return KERN_OK;
@@ -43,13 +48,15 @@ kern_status_t sys_channel_create(unsigned int id, kern_handle_t *out)
kern_status_t sys_port_create(kern_handle_t *out)
{
struct task *self = current_task();
struct task *self = get_current_task();
if (!validate_access_w(self, out, sizeof *out)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
struct port *port = port_create();
if (!port) {
put_current_task(self);
return KERN_NO_MEMORY;
}
@@ -61,6 +68,7 @@ kern_status_t sys_port_create(kern_handle_t *out)
= task_open_handle(self, &port->p_base, 0, &handle);
task_unlock_irqrestore(self, irq_flags);
object_unref(&port->p_base);
put_current_task(self);
if (status != KERN_OK) {
return status;
@@ -77,7 +85,7 @@ kern_status_t sys_port_connect(
{
unsigned long flags;
struct task *self = current_task();
struct task *self = get_current_task();
task_lock_irqsave(self, &flags);
struct object *port_obj = NULL;
@@ -88,6 +96,7 @@ kern_status_t sys_port_connect(
&port_obj,
&port_handle_flags);
if (status != KERN_OK) {
put_current_task(self);
return status;
}
@@ -96,6 +105,7 @@ kern_status_t sys_port_connect(
struct task *remote_task = task_from_tid(task_id);
if (!remote_task) {
put_current_task(self);
return KERN_NO_ENTRY;
}
@@ -104,6 +114,7 @@ kern_status_t sys_port_connect(
struct channel *remote = task_get_channel(remote_task, channel_id);
if (!remote) {
task_unlock_irqrestore(remote_task, flags);
put_current_task(self);
return KERN_NO_ENTRY;
}
@@ -115,6 +126,7 @@ kern_status_t sys_port_connect(
port_unlock_irqrestore(port, flags);
object_unref(&remote->c_base);
object_unref(port_obj);
put_current_task(self);
return KERN_OK;
}
@@ -123,7 +135,7 @@ kern_status_t sys_port_disconnect(kern_handle_t port_handle)
{
unsigned long flags;
struct task *self = current_task();
struct task *self = get_current_task();
task_lock_irqsave(self, &flags);
struct object *port_obj = NULL;
@@ -134,6 +146,7 @@ kern_status_t sys_port_disconnect(kern_handle_t port_handle)
&port_obj,
&port_handle_flags);
if (status != KERN_OK) {
put_current_task(self);
return status;
}
@@ -142,6 +155,7 @@ kern_status_t sys_port_disconnect(kern_handle_t port_handle)
struct port *port = port_cast(port_obj);
if (!port) {
object_unref(port_obj);
put_current_task(self);
return KERN_INVALID_ARGUMENT;
}
@@ -149,6 +163,7 @@ kern_status_t sys_port_disconnect(kern_handle_t port_handle)
port_lock_irqsave(port, &flags);
status = port_disconnect(port);
port_unlock_irqrestore(port, flags);
put_current_task(self);
return status;
}
@@ -219,13 +234,15 @@ kern_status_t sys_msg_send(
const kern_msg_t *msg,
kern_msg_t *out_reply)
{
struct task *self = current_task();
struct task *self = get_current_task();
if (!validate_msg(self, msg, false)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
if (!validate_msg(self, out_reply, true)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
@@ -243,12 +260,14 @@ kern_status_t sys_msg_send(
task_unlock_irqrestore(self, flags);
if (status != KERN_OK) {
put_current_task(self);
return status;
}
struct port *port = port_cast(port_obj);
if (!port) {
object_unref(port_obj);
put_current_task(self);
return KERN_INVALID_ARGUMENT;
}
@@ -256,15 +275,17 @@ kern_status_t sys_msg_send(
status = port_send_msg(port, msg, out_reply, &flags);
port_unlock_irqrestore(port, flags);
object_unref(port_obj);
put_current_task(self);
return status;
}
kern_status_t sys_msg_recv(kern_handle_t channel_handle, kern_msg_t *out_msg)
{
struct task *self = current_task();
struct task *self = get_current_task();
if (!validate_msg(self, out_msg, true)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
@@ -280,6 +301,7 @@ kern_status_t sys_msg_recv(kern_handle_t channel_handle, kern_msg_t *out_msg)
&channel_obj,
&channel_handle_flags);
if (status != KERN_OK) {
put_current_task(self);
return status;
}
@@ -288,6 +310,7 @@ kern_status_t sys_msg_recv(kern_handle_t channel_handle, kern_msg_t *out_msg)
struct channel *channel = channel_cast(channel_obj);
if (!channel) {
object_unref(channel_obj);
put_current_task(self);
return KERN_INVALID_ARGUMENT;
}
@@ -295,6 +318,7 @@ kern_status_t sys_msg_recv(kern_handle_t channel_handle, kern_msg_t *out_msg)
status = channel_recv_msg(channel, out_msg, &flags);
channel_unlock_irqrestore(channel, flags);
object_unref(channel_obj);
put_current_task(self);
return status;
}
@@ -304,9 +328,10 @@ kern_status_t sys_msg_reply(
msgid_t id,
const kern_msg_t *reply)
{
struct task *self = current_task();
struct task *self = get_current_task();
if (!validate_msg(self, reply, true)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
@@ -322,6 +347,7 @@ kern_status_t sys_msg_reply(
&channel_obj,
&channel_handle_flags);
if (status != KERN_OK) {
put_current_task(self);
return status;
}
@@ -330,6 +356,7 @@ kern_status_t sys_msg_reply(
struct channel *channel = channel_cast(channel_obj);
if (!channel) {
object_unref(channel_obj);
put_current_task(self);
return KERN_INVALID_ARGUMENT;
}
@@ -337,6 +364,7 @@ kern_status_t sys_msg_reply(
status = channel_reply_msg(channel, id, reply, &flags);
channel_unlock_irqrestore(channel, flags);
object_unref(channel_obj);
put_current_task(self);
return status;
}
@@ -349,13 +377,15 @@ kern_status_t sys_msg_read(
size_t iov_count,
size_t *nr_read)
{
struct task *self = current_task();
struct task *self = get_current_task();
if (nr_read && !validate_access_w(self, nr_read, sizeof *nr_read)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
if (!validate_iovec(self, iov, iov_count, true)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
@@ -371,6 +401,7 @@ kern_status_t sys_msg_read(
&channel_obj,
&channel_handle_flags);
if (status != KERN_OK) {
put_current_task(self);
return status;
}
@@ -379,6 +410,7 @@ kern_status_t sys_msg_read(
struct channel *channel = channel_cast(channel_obj);
if (!channel) {
object_unref(channel_obj);
put_current_task(self);
return KERN_INVALID_ARGUMENT;
}
@@ -393,6 +425,7 @@ kern_status_t sys_msg_read(
nr_read);
channel_unlock_irqrestore(channel, flags);
object_unref(channel_obj);
put_current_task(self);
return status;
}
@@ -405,14 +438,16 @@ kern_status_t sys_msg_write(
size_t iov_count,
size_t *nr_written)
{
struct task *self = current_task();
struct task *self = get_current_task();
if (nr_written
&& !validate_access_w(self, nr_written, sizeof *nr_written)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
if (!validate_iovec(self, iov, iov_count, false)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
@@ -428,6 +463,7 @@ kern_status_t sys_msg_write(
&channel_obj,
&channel_handle_flags);
if (status != KERN_OK) {
put_current_task(self);
return status;
}
@@ -436,6 +472,7 @@ kern_status_t sys_msg_write(
struct channel *channel = channel_cast(channel_obj);
if (!channel) {
object_unref(channel_obj);
put_current_task(self);
return KERN_INVALID_ARGUMENT;
}
@@ -450,6 +487,7 @@ kern_status_t sys_msg_write(
nr_written);
channel_unlock_irqrestore(channel, flags);
object_unref(channel_obj);
put_current_task(self);
return status;
}