sched: enforce ref-counting on current task/thread pointers
This commit is contained in:
+47
-9
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user