From f0add6e0c37001ca150e83e478f4b41888b013a0 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Tue, 1 Aug 2023 18:43:48 -0700 Subject: [PATCH] [zion] Enforce cap transmit permissions in more places. --- zion/lib/message_queue.cpp | 15 +++++++++++++-- zion/object/address_space.h | 4 +++- zion/object/channel.h | 3 ++- zion/object/endpoint.h | 3 ++- zion/object/memory_object.h | 3 ++- zion/object/process.h | 2 +- zion/syscall/ipc.cpp | 2 +- 7 files changed, 24 insertions(+), 8 deletions(-) diff --git a/zion/lib/message_queue.cpp b/zion/lib/message_queue.cpp index 8575e4d..e712d0d 100644 --- a/zion/lib/message_queue.cpp +++ b/zion/lib/message_queue.cpp @@ -20,10 +20,17 @@ z_err_t UnboundedMessageQueue::PushBack(uint64_t num_bytes, const void* bytes, for (uint64_t i = 0; i < num_caps; i++) { // FIXME: This would feel safer closer to the relevant syscall. - auto cap = gScheduler->CurrentProcess().ReleaseCapability(caps[i]); + // FIXME: Race conditions on get->check->release here. Would be better to + // have that as a single call on the process. (This pattern repeats other + // places too). + auto cap = gScheduler->CurrentProcess().GetCapability(caps[i]); if (!cap) { return glcr::CAP_NOT_FOUND; } + if (!cap->HasPermissions(kZionPerm_Transmit)) { + return glcr::CAP_PERMISSION_DENIED; + } + cap = gScheduler->CurrentProcess().ReleaseCapability(caps[i]); message->caps.PushBack(cap); } @@ -109,10 +116,14 @@ glcr::ErrorCode SingleMessageQueue::PushBack(uint64_t num_bytes, for (uint64_t i = 0; i < num_caps; i++) { // FIXME: This would feel safer closer to the relevant syscall. - auto cap = gScheduler->CurrentProcess().ReleaseCapability(caps[i]); + auto cap = gScheduler->CurrentProcess().GetCapability(caps[i]); if (!cap) { return glcr::CAP_NOT_FOUND; } + if (!cap->HasPermissions(kZionPerm_Transmit)) { + return glcr::CAP_PERMISSION_DENIED; + } + cap = gScheduler->CurrentProcess().ReleaseCapability(caps[i]); caps_.PushBack(cap); } diff --git a/zion/object/address_space.h b/zion/object/address_space.h index ee2ff36..e02ae4d 100644 --- a/zion/object/address_space.h +++ b/zion/object/address_space.h @@ -37,7 +37,9 @@ class AddressSpace : public KernelObject { public: uint64_t TypeTag() override { return KernelObject::ADDRESS_SPACE; } - static uint64_t DefaultPermissions() { return kZionPerm_Write; } + static uint64_t DefaultPermissions() { + return kZionPerm_Write | kZionPerm_Transmit; + } enum MemoryType { UNSPECIFIED, diff --git a/zion/object/channel.h b/zion/object/channel.h index 2990091..8f32cd6 100644 --- a/zion/object/channel.h +++ b/zion/object/channel.h @@ -22,7 +22,8 @@ class Channel : public IpcObject { public: uint64_t TypeTag() override { return KernelObject::CHANNEL; } static uint64_t DefaultPermissions() { - return kZionPerm_Read | kZionPerm_Write | kZionPerm_Duplicate; + return kZionPerm_Read | kZionPerm_Write | kZionPerm_Duplicate | + kZionPerm_Transmit; } static glcr::Pair, glcr::RefPtr> diff --git a/zion/object/endpoint.h b/zion/object/endpoint.h index ab357f8..92c35cb 100644 --- a/zion/object/endpoint.h +++ b/zion/object/endpoint.h @@ -21,7 +21,8 @@ class Endpoint : public IpcObject { public: uint64_t TypeTag() override { return KernelObject::ENDPOINT; } static uint64_t DefaultPermissions() { - return kZionPerm_Read | kZionPerm_Write | kZionPerm_Duplicate; + return kZionPerm_Read | kZionPerm_Write | kZionPerm_Duplicate | + kZionPerm_Transmit; } static glcr::RefPtr Create(); diff --git a/zion/object/memory_object.h b/zion/object/memory_object.h index 03dcb48..027563e 100644 --- a/zion/object/memory_object.h +++ b/zion/object/memory_object.h @@ -23,7 +23,8 @@ class MemoryObject : public KernelObject { public: uint64_t TypeTag() override { return KernelObject::MEMORY_OBJECT; } static uint64_t DefaultPermissions() { - return kZionPerm_Write | kZionPerm_Read | kZionPerm_Duplicate; + return kZionPerm_Write | kZionPerm_Read | kZionPerm_Duplicate | + kZionPerm_Transmit; } MemoryObject(uint64_t size); diff --git a/zion/object/process.h b/zion/object/process.h index eb273f1..d0bc3b4 100644 --- a/zion/object/process.h +++ b/zion/object/process.h @@ -24,7 +24,7 @@ class Process : public KernelObject { uint64_t TypeTag() override { return KernelObject::PROCESS; } static uint64_t DefaultPermissions() { return kZionPerm_Write | kZionPerm_Read | kZionPerm_SpawnThread | - kZionPerm_SpawnProcess | kZionPerm_Duplicate; + kZionPerm_SpawnProcess | kZionPerm_Duplicate | kZionPerm_Transmit; } enum State { diff --git a/zion/syscall/ipc.cpp b/zion/syscall/ipc.cpp index 1c306fd..476bfd8 100644 --- a/zion/syscall/ipc.cpp +++ b/zion/syscall/ipc.cpp @@ -105,7 +105,7 @@ glcr::ErrorCode EndpointSend(ZEndpointSendReq* req) { auto reply_port = ReplyPort::Create(); *req->reply_port_cap = proc.AddNewCapability(reply_port, kZionPerm_Read); uint64_t reply_port_cap_to_send = - proc.AddNewCapability(reply_port, kZionPerm_Write); + proc.AddNewCapability(reply_port, kZionPerm_Write | kZionPerm_Transmit); return endpoint->Send(req->num_bytes, req->data, 1, &reply_port_cap_to_send); }