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
+45 -10
View File
@@ -9,8 +9,9 @@
extern kern_status_t sys_task_exit(int status)
{
#if defined(TRACE)
struct task *self = current_task();
struct task *self = get_current_task();
printk("%s[%d]: task_exit(%d)", self->t_name, self->t_id, status);
put_current_task(self);
#endif
task_exit(status);
return KERN_FATAL_ERROR;
@@ -18,8 +19,9 @@ extern kern_status_t sys_task_exit(int status)
kern_status_t sys_task_self(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;
}
@@ -36,11 +38,13 @@ kern_status_t sys_task_self(kern_handle_t *out)
task_unlock_irqrestore(self, flags);
if (status != KERN_OK) {
put_current_task(self);
return status;
}
object_ref(&self->t_base);
handle_slot->h_object = &self->t_base;
put_current_task(self);
*out = handle;
return KERN_OK;
@@ -54,13 +58,15 @@ kern_status_t sys_task_create(
kern_handle_t *out_address_space)
{
unsigned long flags;
struct task *self = current_task();
struct task *self = get_current_task();
if (name_len && !validate_access_r(self, name, name_len)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
if (!validate_access_w(self, out_task, sizeof *out_task)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
@@ -68,6 +74,7 @@ kern_status_t sys_task_create(
self,
out_address_space,
sizeof *out_address_space)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
@@ -81,6 +88,7 @@ kern_status_t sys_task_create(
&parent_flags);
if (status != KERN_OK) {
task_unlock_irqrestore(self, flags);
put_current_task(self);
return status;
}
@@ -96,6 +104,7 @@ kern_status_t sys_task_create(
if (status != KERN_OK) {
object_unref(parent_obj);
task_unlock_irqrestore(self, flags);
put_current_task(self);
return status;
}
@@ -108,6 +117,7 @@ kern_status_t sys_task_create(
object_unref(parent_obj);
handle_table_free_handle(self->t_handles, child_handle);
task_unlock_irqrestore(self, flags);
put_current_task(self);
return status;
}
@@ -121,6 +131,7 @@ kern_status_t sys_task_create(
handle_table_free_handle(self->t_handles, child_handle);
handle_table_free_handle(self->t_handles, space_handle);
task_unlock_irqrestore(self, flags);
put_current_task(self);
return KERN_NO_MEMORY;
}
@@ -136,6 +147,7 @@ kern_status_t sys_task_create(
object_ref(&child->t_address_space->s_base);
object_unref(parent_obj);
put_current_task(self);
*out_task = child_handle;
*out_address_space = space_handle;
@@ -152,13 +164,15 @@ kern_status_t sys_task_create_thread(
kern_handle_t *out_thread)
{
unsigned long flags;
struct task *self = current_task();
struct task *self = get_current_task();
if (!validate_access_r(self, args, nr_args * sizeof(uintptr_t))) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
if (!validate_access_w(self, out_thread, sizeof *out_thread)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
@@ -169,6 +183,7 @@ kern_status_t sys_task_create_thread(
= task_resolve_handle(self, task, &target_obj, &target_flags);
if (status != KERN_OK) {
task_unlock_irqrestore(self, flags);
put_current_task(self);
return status;
}
@@ -184,6 +199,7 @@ kern_status_t sys_task_create_thread(
if (status != KERN_OK) {
object_unref(target_obj);
task_unlock_irqrestore(self, flags);
put_current_task(self);
return status;
}
@@ -198,6 +214,7 @@ kern_status_t sys_task_create_thread(
task_lock_irqsave(self, &flags);
handle_table_free_handle(self->t_handles, out_handle);
task_unlock_irqrestore(self, flags);
put_current_task(self);
return KERN_NO_MEMORY;
}
@@ -207,6 +224,7 @@ kern_status_t sys_task_create_thread(
task_unlock_irqrestore(target, flags);
object_unref(target_obj);
put_current_task(self);
*out_thread = out_handle;
return KERN_OK;
@@ -216,8 +234,9 @@ kern_status_t sys_task_get_address_space(
kern_handle_t task_handle,
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;
}
@@ -235,6 +254,7 @@ kern_status_t sys_task_get_address_space(
&handle_flags);
if (status != KERN_OK) {
task_unlock_irqrestore(self, flags);
put_current_task(self);
return status;
}
@@ -246,6 +266,7 @@ kern_status_t sys_task_get_address_space(
if (status != KERN_OK) {
object_unref(task_obj);
task_unlock_irqrestore(self, flags);
put_current_task(self);
return status;
}
@@ -255,6 +276,7 @@ kern_status_t sys_task_get_address_space(
object_unref(task_obj);
handle_table_free_handle(self->t_handles, handle);
task_unlock_irqrestore(self, flags);
put_current_task(self);
return KERN_INVALID_ARGUMENT;
}
@@ -262,6 +284,7 @@ kern_status_t sys_task_get_address_space(
object_ref(&task->t_address_space->s_base);
task_unlock_irqrestore(self, flags);
object_unref(task_obj);
put_current_task(self);
*out = handle;
return KERN_OK;
@@ -269,12 +292,13 @@ kern_status_t sys_task_get_address_space(
kern_status_t sys_thread_self(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 thread *self_thread = current_thread();
struct thread *self_thread = get_current_thread();
unsigned long flags;
task_lock_irqsave(self, &flags);
@@ -289,11 +313,15 @@ kern_status_t sys_thread_self(kern_handle_t *out)
task_unlock_irqrestore(self, flags);
if (status != KERN_OK) {
put_current_thread(self_thread);
put_current_task(self);
return status;
}
object_ref(&self_thread->tr_base);
handle_slot->h_object = &self_thread->tr_base;
put_current_thread(self_thread);
put_current_task(self);
*out = handle;
return KERN_OK;
@@ -302,7 +330,7 @@ kern_status_t sys_thread_self(kern_handle_t *out)
kern_status_t sys_thread_start(kern_handle_t thread_handle)
{
unsigned long flags;
struct task *self = current_task();
struct task *self = get_current_task();
struct object *thread_obj;
handle_flags_t thread_flags;
@@ -314,6 +342,7 @@ kern_status_t sys_thread_start(kern_handle_t thread_handle)
&thread_flags);
if (status != KERN_OK) {
task_unlock_irqrestore(self, flags);
put_current_task(self);
return status;
}
@@ -322,6 +351,7 @@ kern_status_t sys_thread_start(kern_handle_t thread_handle)
schedule_thread_on_cpu(thread);
object_unref(thread_obj);
put_current_task(self);
return KERN_OK;
}
@@ -340,9 +370,10 @@ kern_status_t sys_thread_config_get(
size_t len)
{
unsigned long flags;
struct task *self = current_task();
struct task *self = get_current_task();
if (!validate_access_w(self, ptr, len)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
@@ -356,6 +387,7 @@ kern_status_t sys_thread_config_get(
&thread_flags);
if (status != KERN_OK) {
task_unlock_irqrestore(self, flags);
put_current_task(self);
return status;
}
@@ -365,6 +397,7 @@ kern_status_t sys_thread_config_get(
status = thread_config_get(thread, key, ptr, len);
object_unref(thread_obj);
put_current_task(self);
return status;
}
@@ -376,9 +409,10 @@ kern_status_t sys_thread_config_set(
size_t len)
{
unsigned long flags;
struct task *self = current_task();
struct task *self = get_current_task();
if (!validate_access_w(self, ptr, len)) {
put_current_task(self);
return KERN_MEMORY_FAULT;
}
@@ -392,6 +426,7 @@ kern_status_t sys_thread_config_set(
&thread_flags);
if (status != KERN_OK) {
task_unlock_irqrestore(self, flags);
put_current_task(self);
return status;
}