From 1364fbed9f9fcdd4fc372303357a678f424fca30 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Tue, 1 Aug 2023 18:22:41 -0700 Subject: [PATCH] [zion] Move to default permissions being supplied by KernelObjects --- zion/capability/capability.h | 4 ++++ zion/capability/capability_table.h | 9 +++++--- zion/include/ztypes.h | 15 ++++++++----- zion/loader/init_loader.cpp | 14 +++++------- zion/object/address_space.h | 3 +++ zion/object/channel.h | 4 ++++ zion/object/endpoint.h | 4 ++++ zion/object/memory_object.h | 5 +++++ zion/object/port.h | 3 +++ zion/object/process.h | 9 ++++++++ zion/object/thread.h | 5 +++++ zion/syscall/address_space.cpp | 4 ++-- zion/syscall/ipc.cpp | 35 +++++++++++++++--------------- zion/syscall/memory_object.cpp | 16 +++++++------- zion/syscall/process.cpp | 7 +++--- zion/syscall/thread.cpp | 8 +++---- 16 files changed, 91 insertions(+), 54 deletions(-) diff --git a/zion/capability/capability.h b/zion/capability/capability.h index 713c9db..8f2c7fc 100644 --- a/zion/capability/capability.h +++ b/zion/capability/capability.h @@ -20,6 +20,10 @@ class Capability : public glcr::RefCounted { Capability(const glcr::RefPtr& obj, uint64_t permissions) : Capability(StaticCastRefPtr(obj), permissions) {} + template + Capability(const glcr::RefPtr& obj) + : Capability(obj, T::DefaultPermissions()) {} + template glcr::RefPtr obj(); diff --git a/zion/capability/capability_table.h b/zion/capability/capability_table.h index fadb84f..5b59e5a 100644 --- a/zion/capability/capability_table.h +++ b/zion/capability/capability_table.h @@ -14,9 +14,12 @@ class CapabilityTable { CapabilityTable& operator=(CapabilityTable&) = delete; template - uint64_t AddNewCapability(const glcr::RefPtr& object, - uint64_t permissions); - uint64_t AddExistingCapability(const glcr::RefPtr& cap); + z_cap_t AddNewCapability(const glcr::RefPtr& object, uint64_t permissions); + template + z_cap_t AddNewCapability(const glcr::RefPtr& object) { + return AddNewCapability(object, T::DefaultPermissions()); + } + z_cap_t AddExistingCapability(const glcr::RefPtr& cap); glcr::RefPtr GetCapability(uint64_t id); glcr::RefPtr ReleaseCapability(uint64_t id); diff --git a/zion/include/ztypes.h b/zion/include/ztypes.h index f6f124b..fda973b 100644 --- a/zion/include/ztypes.h +++ b/zion/include/ztypes.h @@ -63,15 +63,18 @@ const uint64_t kZionDebug = 0x1'0000; typedef uint64_t z_cap_t; -#define Z_INVALID 0x0 - // General Capability Permissions -#define ZC_WRITE 0x01 -#define ZC_READ 0x02 +const uint64_t kZionPerm_Write = 0x1; +const uint64_t kZionPerm_Read = 0x2; + +const uint64_t kZionPerm_Transmit = 0x10; +const uint64_t kZionPerm_Duplicate = 0x20; // Capability Specific Permissions -#define ZC_PROC_SPAWN_PROC 0x100 -#define ZC_PROC_SPAWN_THREAD 0x200 + +// Permissions held on process capabilities. +const uint64_t kZionPerm_SpawnProcess = 0x100; +const uint64_t kZionPerm_SpawnThread = 0x200; /* ------------------------------ * Process Init Types diff --git a/zion/loader/init_loader.cpp b/zion/loader/init_loader.cpp index 14677ed..24aba03 100644 --- a/zion/loader/init_loader.cpp +++ b/zion/loader/init_loader.cpp @@ -124,8 +124,7 @@ void WriteInitProgram(glcr::RefPtr port, glcr::String name, uint64_t id) { glcr::MakeRefCounted(prog.size); prog_vmmo->CopyBytesToObject(reinterpret_cast(prog.address), prog.size); - port->WriteKernel(id, - MakeRefCounted(prog_vmmo, ZC_READ | ZC_WRITE)); + port->WriteKernel(id, MakeRefCounted(prog_vmmo)); } glcr::ErrorCode WritePciVmmo(glcr::RefPtr port, uint64_t id) { @@ -133,7 +132,7 @@ glcr::ErrorCode WritePciVmmo(glcr::RefPtr port, uint64_t id) { auto vmmo = glcr::MakeRefCounted(config.base, config.offset); - port->WriteKernel(id, MakeRefCounted(vmmo, ZC_READ | ZC_WRITE)); + port->WriteKernel(id, MakeRefCounted(vmmo)); return glcr::OK; } @@ -149,12 +148,9 @@ void LoadInitProgram() { // Write init data. auto port = glcr::MakeRefCounted(); - uint64_t port_cap = proc->AddNewCapability(port, ZC_READ | ZC_WRITE); - port->WriteKernel(Z_INIT_SELF_PROC, - MakeRefCounted( - proc, ZC_PROC_SPAWN_PROC | ZC_PROC_SPAWN_THREAD)); - port->WriteKernel(Z_INIT_SELF_VMAS, - MakeRefCounted(proc->vmas(), ZC_WRITE)); + uint64_t port_cap = proc->AddNewCapability(port); + port->WriteKernel(Z_INIT_SELF_PROC, MakeRefCounted(proc)); + port->WriteKernel(Z_INIT_SELF_VMAS, MakeRefCounted(proc->vmas())); WriteInitProgram(port, "/sys/denali", Z_BOOT_DENALI_VMMO); WriteInitProgram(port, "/sys/victoriafalls", Z_BOOT_VICTORIA_FALLS_VMMO); diff --git a/zion/object/address_space.h b/zion/object/address_space.h index 304fc21..ee2ff36 100644 --- a/zion/object/address_space.h +++ b/zion/object/address_space.h @@ -4,6 +4,7 @@ #include #include +#include "include/ztypes.h" #include "memory/user_stack_manager.h" #include "object/memory_object.h" @@ -36,6 +37,8 @@ class AddressSpace : public KernelObject { public: uint64_t TypeTag() override { return KernelObject::ADDRESS_SPACE; } + static uint64_t DefaultPermissions() { return kZionPerm_Write; } + enum MemoryType { UNSPECIFIED, UNMAPPED, diff --git a/zion/object/channel.h b/zion/object/channel.h index 6203487..f3cfdbb 100644 --- a/zion/object/channel.h +++ b/zion/object/channel.h @@ -21,6 +21,10 @@ struct KernelObjectTag { class Channel : public IpcObject { public: uint64_t TypeTag() override { return KernelObject::CHANNEL; } + static uint64_t DefaultPermissions() { + return kZionPerm_Read | kZionPerm_Write; + } + static glcr::Pair, glcr::RefPtr> CreateChannelPair(); diff --git a/zion/object/endpoint.h b/zion/object/endpoint.h index 5aa6ca5..f5c465c 100644 --- a/zion/object/endpoint.h +++ b/zion/object/endpoint.h @@ -20,6 +20,10 @@ struct KernelObjectTag { class Endpoint : public IpcObject { public: uint64_t TypeTag() override { return KernelObject::ENDPOINT; } + static uint64_t DefaultPermissions() { + return kZionPerm_Read | kZionPerm_Write; + } + static glcr::RefPtr Create(); glcr::ErrorCode Read(uint64_t* num_bytes, void* data, diff --git a/zion/object/memory_object.h b/zion/object/memory_object.h index aa63c77..590c3f4 100644 --- a/zion/object/memory_object.h +++ b/zion/object/memory_object.h @@ -4,6 +4,7 @@ #include #include +#include "include/ztypes.h" #include "object/kernel_object.h" class MemoryObject; @@ -21,6 +22,10 @@ struct KernelObjectTag { class MemoryObject : public KernelObject { public: uint64_t TypeTag() override { return KernelObject::MEMORY_OBJECT; } + static uint64_t DefaultPermissions() { + return kZionPerm_Write | kZionPerm_Read; + } + MemoryObject(uint64_t size); uint64_t size() { return size_; } diff --git a/zion/object/port.h b/zion/object/port.h index d757d4d..01a501a 100644 --- a/zion/object/port.h +++ b/zion/object/port.h @@ -21,6 +21,9 @@ struct KernelObjectTag { class Port : public IpcObject { public: uint64_t TypeTag() override { return KernelObject::PORT; } + static uint64_t DefaultPermissions() { + return kZionPerm_Write | kZionPerm_Read; + } Port() = default; diff --git a/zion/object/process.h b/zion/object/process.h index 06e3dc1..3ec2fa7 100644 --- a/zion/object/process.h +++ b/zion/object/process.h @@ -22,6 +22,11 @@ struct KernelObjectTag { class Process : public KernelObject { public: uint64_t TypeTag() override { return KernelObject::PROCESS; } + static uint64_t DefaultPermissions() { + return kZionPerm_Write | kZionPerm_Read | kZionPerm_SpawnThread | + kZionPerm_SpawnProcess; + } + enum State { UNSPECIFIED, SETUP, @@ -44,6 +49,10 @@ class Process : public KernelObject { uint64_t AddNewCapability(const glcr::RefPtr& obj, uint64_t permissions) { return caps_.AddNewCapability(obj, permissions); } + template + uint64_t AddNewCapability(const glcr::RefPtr& obj) { + return caps_.AddNewCapability(obj); + } uint64_t AddExistingCapability(const glcr::RefPtr& cap); // Checks the state of all child threads and transitions to diff --git a/zion/object/thread.h b/zion/object/thread.h index 154098f..c486ff6 100644 --- a/zion/object/thread.h +++ b/zion/object/thread.h @@ -4,6 +4,7 @@ #include #include +#include "include/ztypes.h" #include "object/kernel_object.h" // Forward decl due to cyclic dependency. @@ -18,6 +19,10 @@ struct KernelObjectTag { class Thread : public KernelObject, public glcr::IntrusiveListNode { public: uint64_t TypeTag() override { return KernelObject::THREAD; } + static uint64_t DefaultPermissions() { + return kZionPerm_Read | kZionPerm_Write; + } + enum State { UNSPECIFIED, CREATED, diff --git a/zion/syscall/address_space.cpp b/zion/syscall/address_space.cpp index 7d24320..1582dcd 100644 --- a/zion/syscall/address_space.cpp +++ b/zion/syscall/address_space.cpp @@ -7,8 +7,8 @@ z_err_t AddressSpaceMap(ZAddressSpaceMapReq* req) { auto& curr_proc = gScheduler->CurrentProcess(); auto vmas_cap = curr_proc.GetCapability(req->vmas_cap); auto vmmo_cap = curr_proc.GetCapability(req->vmmo_cap); - RET_ERR(ValidateCapability(vmas_cap, ZC_WRITE)); - RET_ERR(ValidateCapability(vmmo_cap, ZC_WRITE)); + RET_ERR(ValidateCapability(vmas_cap, kZionPerm_Write)); + RET_ERR(ValidateCapability(vmmo_cap, kZionPerm_Write)); auto vmas = vmas_cap->obj(); auto vmmo = vmmo_cap->obj(); diff --git a/zion/syscall/ipc.cpp b/zion/syscall/ipc.cpp index 226ee0a..1c306fd 100644 --- a/zion/syscall/ipc.cpp +++ b/zion/syscall/ipc.cpp @@ -9,16 +9,15 @@ z_err_t ChannelCreate(ZChannelCreateReq* req) { auto& proc = gScheduler->CurrentProcess(); auto chan_pair = Channel::CreateChannelPair(); - *req->channel1 = proc.AddNewCapability(chan_pair.first(), ZC_WRITE | ZC_READ); - *req->channel2 = - proc.AddNewCapability(chan_pair.second(), ZC_WRITE | ZC_READ); + *req->channel1 = proc.AddNewCapability(chan_pair.first()); + *req->channel2 = proc.AddNewCapability(chan_pair.second()); return glcr::OK; } z_err_t ChannelSend(ZChannelSendReq* req) { auto& proc = gScheduler->CurrentProcess(); auto chan_cap = proc.GetCapability(req->chan_cap); - RET_ERR(ValidateCapability(chan_cap, ZC_WRITE)); + RET_ERR(ValidateCapability(chan_cap, kZionPerm_Write)); auto chan = chan_cap->obj(); return chan->Send(req->num_bytes, req->data, req->num_caps, req->caps); @@ -27,7 +26,7 @@ z_err_t ChannelSend(ZChannelSendReq* req) { z_err_t ChannelRecv(ZChannelRecvReq* req) { auto& proc = gScheduler->CurrentProcess(); auto chan_cap = proc.GetCapability(req->chan_cap); - RET_ERR(ValidateCapability(chan_cap, ZC_READ)); + RET_ERR(ValidateCapability(chan_cap, kZionPerm_Read)); auto chan = chan_cap->obj(); return chan->Recv(req->num_bytes, req->data, req->num_caps, req->caps); @@ -36,14 +35,14 @@ z_err_t ChannelRecv(ZChannelRecvReq* req) { z_err_t PortCreate(ZPortCreateReq* req) { auto& proc = gScheduler->CurrentProcess(); auto port = glcr::MakeRefCounted(); - *req->port_cap = proc.AddNewCapability(port, ZC_WRITE | ZC_READ); + *req->port_cap = proc.AddNewCapability(port); return glcr::OK; } z_err_t PortSend(ZPortSendReq* req) { auto& proc = gScheduler->CurrentProcess(); auto port_cap = proc.GetCapability(req->port_cap); - RET_ERR(ValidateCapability(port_cap, ZC_WRITE)); + RET_ERR(ValidateCapability(port_cap, kZionPerm_Write)); auto port = port_cap->obj(); return port->Send(req->num_bytes, req->data, req->num_caps, req->caps); @@ -52,7 +51,7 @@ z_err_t PortSend(ZPortSendReq* req) { z_err_t PortRecv(ZPortRecvReq* req) { auto& proc = gScheduler->CurrentProcess(); auto port_cap = proc.GetCapability(req->port_cap); - RET_ERR(ValidateCapability(port_cap, ZC_READ)); + RET_ERR(ValidateCapability(port_cap, kZionPerm_Read)); auto port = port_cap->obj(); ZMessage message{ @@ -67,7 +66,7 @@ z_err_t PortRecv(ZPortRecvReq* req) { z_err_t PortPoll(ZPortPollReq* req) { auto& proc = gScheduler->CurrentProcess(); auto port_cap = proc.GetCapability(req->port_cap); - RET_ERR(ValidateCapability(port_cap, ZC_READ)); + RET_ERR(ValidateCapability(port_cap, kZionPerm_Read)); auto port = port_cap->obj(); // FIXME: Race condition here where this call could block if the last message @@ -85,15 +84,14 @@ z_err_t IrqRegister(ZIrqRegisterReq* req) { return glcr::UNIMPLEMENTED; } glcr::RefPtr port = glcr::MakeRefCounted(); - *req->port_cap = proc.AddNewCapability(port, ZC_READ | ZC_WRITE); + *req->port_cap = proc.AddNewCapability(port); RegisterPciPort(port); return glcr::OK; } glcr::ErrorCode EndpointCreate(ZEndpointCreateReq* req) { auto& proc = gScheduler->CurrentProcess(); - *req->endpoint_cap = - proc.AddNewCapability(Endpoint::Create(), ZC_READ | ZC_WRITE); + *req->endpoint_cap = proc.AddNewCapability(Endpoint::Create()); return glcr::OK; } @@ -101,12 +99,13 @@ glcr::ErrorCode EndpointSend(ZEndpointSendReq* req) { auto& proc = gScheduler->CurrentProcess(); auto endpoint_cap = proc.GetCapability(req->endpoint_cap); - ValidateCapability(endpoint_cap, ZC_WRITE); + ValidateCapability(endpoint_cap, kZionPerm_Write); auto endpoint = endpoint_cap->obj(); auto reply_port = ReplyPort::Create(); - *req->reply_port_cap = proc.AddNewCapability(reply_port, ZC_READ); - uint64_t reply_port_cap_to_send = proc.AddNewCapability(reply_port, ZC_WRITE); + *req->reply_port_cap = proc.AddNewCapability(reply_port, kZionPerm_Read); + uint64_t reply_port_cap_to_send = + proc.AddNewCapability(reply_port, kZionPerm_Write); return endpoint->Send(req->num_bytes, req->data, 1, &reply_port_cap_to_send); } @@ -114,7 +113,7 @@ glcr::ErrorCode EndpointRecv(ZEndpointRecvReq* req) { auto& proc = gScheduler->CurrentProcess(); auto endpoint_cap = proc.GetCapability(req->endpoint_cap); - ValidateCapability(endpoint_cap, ZC_READ); + ValidateCapability(endpoint_cap, kZionPerm_Read); auto endpoint = endpoint_cap->obj(); uint64_t num_caps = 1; @@ -129,7 +128,7 @@ glcr::ErrorCode EndpointRecv(ZEndpointRecvReq* req) { glcr::ErrorCode ReplyPortSend(ZReplyPortSendReq* req) { auto& proc = gScheduler->CurrentProcess(); auto reply_port_cap = proc.GetCapability(req->reply_port_cap); - ValidateCapability(reply_port_cap, ZC_WRITE); + ValidateCapability(reply_port_cap, kZionPerm_Read); auto reply_port = reply_port_cap->obj(); return reply_port->Send(req->num_bytes, req->data, req->num_caps, req->caps); @@ -138,7 +137,7 @@ glcr::ErrorCode ReplyPortRecv(ZReplyPortRecvReq* req) { auto& proc = gScheduler->CurrentProcess(); auto reply_port_cap = proc.GetCapability(req->reply_port_cap); - ValidateCapability(reply_port_cap, ZC_READ); + ValidateCapability(reply_port_cap, kZionPerm_Read); auto reply_port = reply_port_cap->obj(); return reply_port->Recv(req->num_bytes, req->data, req->num_caps, req->caps); diff --git a/zion/syscall/memory_object.cpp b/zion/syscall/memory_object.cpp index 6e58afc..5d78ad3 100644 --- a/zion/syscall/memory_object.cpp +++ b/zion/syscall/memory_object.cpp @@ -6,8 +6,8 @@ z_err_t MemoryObjectCreate(ZMemoryObjectCreateReq* req) { auto& curr_proc = gScheduler->CurrentProcess(); - *req->vmmo_cap = curr_proc.AddNewCapability( - glcr::MakeRefCounted(req->size), ZC_WRITE); + *req->vmmo_cap = + curr_proc.AddNewCapability(glcr::MakeRefCounted(req->size)); return glcr::OK; } @@ -15,8 +15,8 @@ z_err_t MemoryObjectCreatePhysical(ZMemoryObjectCreatePhysicalReq* req) { auto& curr_proc = gScheduler->CurrentProcess(); uint64_t paddr = req->paddr; auto vmmo_ref = glcr::MakeRefCounted(paddr, req->size); - *req->vmmo_cap = curr_proc.AddNewCapability( - StaticCastRefPtr(vmmo_ref), ZC_WRITE); + *req->vmmo_cap = + curr_proc.AddNewCapability(StaticCastRefPtr(vmmo_ref)); return glcr::OK; } @@ -24,8 +24,8 @@ z_err_t MemoryObjectCreateContiguous(ZMemoryObjectCreateContiguousReq* req) { auto& curr_proc = gScheduler->CurrentProcess(); uint64_t paddr = phys_mem::AllocateContinuous(((req->size - 1) / 0x1000) + 1); auto vmmo_ref = glcr::MakeRefCounted(paddr, req->size); - *req->vmmo_cap = curr_proc.AddNewCapability( - StaticCastRefPtr(vmmo_ref), ZC_WRITE); + *req->vmmo_cap = + curr_proc.AddNewCapability(StaticCastRefPtr(vmmo_ref)); *req->paddr = paddr; return glcr::OK; } @@ -34,11 +34,11 @@ z_err_t MemoryObjectDuplicate(ZMemoryObjectDuplicateReq* req) { auto& curr_proc = gScheduler->CurrentProcess(); auto vmmo_cap = curr_proc.GetCapability(req->vmmo_cap); // FIXME: Check a duplication permission here. - RET_ERR(ValidateCapability(vmmo_cap, ZC_WRITE)); + RET_ERR(ValidateCapability(vmmo_cap, kZionPerm_Write)); ASSIGN_OR_RETURN( glcr::RefPtr new_vmmo, vmmo_cap->obj()->Duplicate(req->base_offset, req->length)); - *req->new_vmmo_cap = curr_proc.AddNewCapability(new_vmmo, ZC_WRITE | ZC_READ); + *req->new_vmmo_cap = curr_proc.AddNewCapability(new_vmmo); return glcr::OK; } diff --git a/zion/syscall/process.cpp b/zion/syscall/process.cpp index e445239..77c7b7f 100644 --- a/zion/syscall/process.cpp +++ b/zion/syscall/process.cpp @@ -17,14 +17,13 @@ z_err_t ProcessExit(ZProcessExitReq* req) { z_err_t ProcessSpawn(ZProcessSpawnReq* req) { auto& curr_proc = gScheduler->CurrentProcess(); auto cap = curr_proc.GetCapability(req->proc_cap); - RET_ERR(ValidateCapability(cap, ZC_PROC_SPAWN_PROC)); + RET_ERR(ValidateCapability(cap, kZionPerm_SpawnProcess)); glcr::RefPtr proc = Process::Create(); gProcMan->InsertProcess(proc); - *req->new_proc_cap = curr_proc.AddNewCapability( - proc, ZC_PROC_SPAWN_PROC | ZC_PROC_SPAWN_THREAD | ZC_WRITE); - *req->new_vmas_cap = curr_proc.AddNewCapability(proc->vmas(), ZC_WRITE); + *req->new_proc_cap = curr_proc.AddNewCapability(proc); + *req->new_vmas_cap = curr_proc.AddNewCapability(proc->vmas()); if (req->bootstrap_cap != 0) { auto cap = curr_proc.ReleaseCapability(req->bootstrap_cap); diff --git a/zion/syscall/thread.cpp b/zion/syscall/thread.cpp index 7f78e37..a5c5d95 100644 --- a/zion/syscall/thread.cpp +++ b/zion/syscall/thread.cpp @@ -7,18 +7,18 @@ glcr::ErrorCode ThreadCreate(ZThreadCreateReq* req) { auto& curr_proc = gScheduler->CurrentProcess(); auto cap = curr_proc.GetCapability(req->proc_cap); - RET_ERR(ValidateCapability(cap, ZC_PROC_SPAWN_THREAD)); + RET_ERR(ValidateCapability(cap, kZionPerm_SpawnThread)); auto parent_proc = cap->obj(); auto thread = parent_proc->CreateThread(); - *req->thread_cap = curr_proc.AddNewCapability(thread, ZC_WRITE | ZC_READ); + *req->thread_cap = curr_proc.AddNewCapability(thread); return glcr::OK; } glcr::ErrorCode ThreadStart(ZThreadStartReq* req) { auto& curr_proc = gScheduler->CurrentProcess(); auto cap = curr_proc.GetCapability(req->thread_cap); - RET_ERR(ValidateCapability(cap, ZC_WRITE)); + RET_ERR(ValidateCapability(cap, kZionPerm_Write)); auto thread = cap->obj(); // FIXME: validate entry point is in user space. @@ -36,7 +36,7 @@ glcr::ErrorCode ThreadExit(ZThreadExitReq*) { glcr::ErrorCode ThreadWait(ZThreadWaitReq* req) { auto& curr_proc = gScheduler->CurrentProcess(); auto cap = curr_proc.GetCapability(req->thread_cap); - RET_ERR(ValidateCapability(cap, ZC_READ)); + RET_ERR(ValidateCapability(cap, kZionPerm_Read)); auto thread = cap->obj(); thread->Wait(); return glcr::OK;