diff --git a/sys/TODO.md b/sys/TODO.md index fdf188d..7bf787a 100644 --- a/sys/TODO.md +++ b/sys/TODO.md @@ -2,8 +2,6 @@ ## Yellowstone -- Add registration to the base yellowstone yunq service - - Requires: Adding ability to pass capabilities in endpoint calls. - Store registered services in a hashmap. - Requires: Adding hashmap to Glacier. - Start the next service from a configuration file. diff --git a/sys/denali/denali.cpp b/sys/denali/denali.cpp index d4aa72c..2811e6f 100644 --- a/sys/denali/denali.cpp +++ b/sys/denali/denali.cpp @@ -29,16 +29,13 @@ uint64_t main(uint64_t init_port_cap) { ASSIGN_OR_RETURN(glcr::UniquePtr client, server->CreateClient()); - RegisterInfo reg; - Empty empty2; - check(stub.GetRegister(empty2, reg)); - - PortClient register_port = PortClient::AdoptPort(reg.register_port()); - - check(register_port.WriteString("denali", client->GetCap())); - Thread server_thread = server->RunServer(); + RegisterEndpointRequest req; + req.set_endpoint_name("denali"); + req.set_endpoint_capability(client->GetCap()); + check(stub.RegisterEndpoint(req, empty)); + check(server_thread.Join()); return 0; } diff --git a/sys/yellowstone/include/yellowstone/yellowstone.yunq b/sys/yellowstone/include/yellowstone/yellowstone.yunq index 530c3f1..9c2b134 100644 --- a/sys/yellowstone/include/yellowstone/yellowstone.yunq +++ b/sys/yellowstone/include/yellowstone/yellowstone.yunq @@ -1,17 +1,18 @@ interface Yellowstone { - method GetRegister(Empty) -> (RegisterInfo); + method RegisterEndpoint(RegisterEndpointRequest) -> (Empty); method GetAhciInfo(Empty) -> (AhciInfo); method GetDenali(Empty) -> (DenaliInfo); } +message RegisterEndpointRequest { + string endpoint_name; + capability endpoint_capability; + } + message Empty { } -message RegisterInfo { - capability register_port; -} - message AhciInfo { capability ahci_region; u64 region_length; diff --git a/sys/yellowstone/include/yellowstone/yellowstone.yunq.client.cpp b/sys/yellowstone/include/yellowstone/yellowstone.yunq.client.cpp index 2b47570..fa0ec17 100644 --- a/sys/yellowstone/include/yellowstone/yellowstone.yunq.client.cpp +++ b/sys/yellowstone/include/yellowstone/yellowstone.yunq.client.cpp @@ -8,7 +8,7 @@ -glcr::ErrorCode YellowstoneClient::GetRegister(const Empty& request, RegisterInfo& response) { +glcr::ErrorCode YellowstoneClient::RegisterEndpoint(const RegisterEndpointRequest& request, Empty& response) { uint64_t buffer_size = kBufferSize; uint64_t cap_size = kCapBufferSize; @@ -16,7 +16,7 @@ glcr::ErrorCode YellowstoneClient::GetRegister(const Empty& request, RegisterInf buffer_.WriteAt(0, kSentinel); buffer_.WriteAt(8, 0); - // FIXME: We need to reset the cap buffer here. + cap_buffer_.Reset(); uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); buffer_.WriteAt(4, 16 + length); @@ -48,7 +48,7 @@ glcr::ErrorCode YellowstoneClient::GetAhciInfo(const Empty& request, AhciInfo& r buffer_.WriteAt(0, kSentinel); buffer_.WriteAt(8, 1); - // FIXME: We need to reset the cap buffer here. + cap_buffer_.Reset(); uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); buffer_.WriteAt(4, 16 + length); @@ -80,7 +80,7 @@ glcr::ErrorCode YellowstoneClient::GetDenali(const Empty& request, DenaliInfo& r buffer_.WriteAt(0, kSentinel); buffer_.WriteAt(8, 2); - // FIXME: We need to reset the cap buffer here. + cap_buffer_.Reset(); uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); buffer_.WriteAt(4, 16 + length); diff --git a/sys/yellowstone/include/yellowstone/yellowstone.yunq.client.h b/sys/yellowstone/include/yellowstone/yellowstone.yunq.client.h index 225b351..56ca541 100644 --- a/sys/yellowstone/include/yellowstone/yellowstone.yunq.client.h +++ b/sys/yellowstone/include/yellowstone/yellowstone.yunq.client.h @@ -17,7 +17,7 @@ class YellowstoneClient { z_cap_t Capability() { return endpoint_; } - [[nodiscard]] glcr::ErrorCode GetRegister(const Empty& request, RegisterInfo& response); + [[nodiscard]] glcr::ErrorCode RegisterEndpoint(const RegisterEndpointRequest& request, Empty& response); [[nodiscard]] glcr::ErrorCode GetAhciInfo(const Empty& request, AhciInfo& response); diff --git a/sys/yellowstone/include/yellowstone/yellowstone.yunq.cpp b/sys/yellowstone/include/yellowstone/yellowstone.yunq.cpp index 41dacd1..c2e8e26 100644 --- a/sys/yellowstone/include/yellowstone/yellowstone.yunq.cpp +++ b/sys/yellowstone/include/yellowstone/yellowstone.yunq.cpp @@ -27,6 +27,77 @@ void WriteHeader(glcr::ByteBuffer& bytes, uint64_t offset, uint32_t core_size, u } } // namespace +void RegisterEndpointRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) { + CheckHeader(bytes); + // Parse endpoint_name. + auto endpoint_name_pointer = bytes.At(offset + header_size + (8 * 0)); + + set_endpoint_name(bytes.StringAt(offset + endpoint_name_pointer.offset, endpoint_name_pointer.length)); + // Parse endpoint_capability. + // FIXME: Implement in-buffer capabilities for inprocess serialization. + set_endpoint_capability(0); +} + +void RegisterEndpointRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) { + CheckHeader(bytes); + // Parse endpoint_name. + auto endpoint_name_pointer = bytes.At(offset + header_size + (8 * 0)); + + set_endpoint_name(bytes.StringAt(offset + endpoint_name_pointer.offset, endpoint_name_pointer.length)); + // Parse endpoint_capability. + uint64_t endpoint_capability_ptr = bytes.At(offset + header_size + (8 * 1)); + + set_endpoint_capability(caps.At(endpoint_capability_ptr)); +} + +uint64_t RegisterEndpointRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { + uint32_t next_extension = header_size + 8 * 2; + const uint32_t core_size = next_extension; + // Write endpoint_name. + ExtPointer endpoint_name_ptr{ + .offset = next_extension, + // FIXME: Check downcast of str length. + .length = (uint32_t)endpoint_name().length(), + }; + + bytes.WriteStringAt(offset + next_extension, endpoint_name()); + next_extension += endpoint_name_ptr.length; + + bytes.WriteAt(offset + header_size + (8 * 0), endpoint_name_ptr); + // Write endpoint_capability. + // FIXME: Implement inbuffer capabilities. + bytes.WriteAt(offset + header_size + (8 * 1), 0); + + // The next extension pointer is the length of the message. + WriteHeader(bytes, offset, core_size, next_extension); + + return next_extension; +} + +uint64_t RegisterEndpointRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { + uint32_t next_extension = header_size + 8 * 2; + const uint32_t core_size = next_extension; + uint64_t next_cap = 0; + // Write endpoint_name. + ExtPointer endpoint_name_ptr{ + .offset = next_extension, + // FIXME: Check downcast of str length. + .length = (uint32_t)endpoint_name().length(), + }; + + bytes.WriteStringAt(offset + next_extension, endpoint_name()); + next_extension += endpoint_name_ptr.length; + + bytes.WriteAt(offset + header_size + (8 * 0), endpoint_name_ptr); + // Write endpoint_capability. + caps.WriteAt(next_cap, endpoint_capability()); + bytes.WriteAt(offset + header_size + (8 * 1), next_cap++); + + // The next extension pointer is the length of the message. + WriteHeader(bytes, offset, core_size, next_extension); + + return next_extension; +} void Empty::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) { CheckHeader(bytes); } @@ -55,47 +126,6 @@ uint64_t Empty::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr: return next_extension; } -void RegisterInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) { - CheckHeader(bytes); - // Parse register_port. - // FIXME: Implement in-buffer capabilities for inprocess serialization. - set_register_port(0); -} - -void RegisterInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) { - CheckHeader(bytes); - // Parse register_port. - uint64_t register_port_ptr = bytes.At(offset + header_size + (8 * 0)); - - set_register_port(caps.At(register_port_ptr)); -} - -uint64_t RegisterInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { - uint32_t next_extension = header_size + 8 * 1; - const uint32_t core_size = next_extension; - // Write register_port. - // FIXME: Implement inbuffer capabilities. - bytes.WriteAt(offset + header_size + (8 * 0), 0); - - // The next extension pointer is the length of the message. - WriteHeader(bytes, offset, core_size, next_extension); - - return next_extension; -} - -uint64_t RegisterInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { - uint32_t next_extension = header_size + 8 * 1; - const uint32_t core_size = next_extension; - uint64_t next_cap = 0; - // Write register_port. - caps.WriteAt(next_cap, register_port()); - bytes.WriteAt(offset + header_size + (8 * 0), next_cap++); - - // The next extension pointer is the length of the message. - WriteHeader(bytes, offset, core_size, next_extension); - - return next_extension; -} void AhciInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) { CheckHeader(bytes); // Parse ahci_region. diff --git a/sys/yellowstone/include/yellowstone/yellowstone.yunq.h b/sys/yellowstone/include/yellowstone/yellowstone.yunq.h index b66b35f..ffea85e 100644 --- a/sys/yellowstone/include/yellowstone/yellowstone.yunq.h +++ b/sys/yellowstone/include/yellowstone/yellowstone.yunq.h @@ -5,6 +5,27 @@ #include #include #include +class RegisterEndpointRequest { + public: + RegisterEndpointRequest() {} + // Delete copy and move until implemented. + RegisterEndpointRequest(const RegisterEndpointRequest&) = delete; + RegisterEndpointRequest(RegisterEndpointRequest&&) = delete; + + void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset); + void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&); + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; + glcr::String endpoint_name() const { return endpoint_name_; } + void set_endpoint_name(const glcr::String& value) { endpoint_name_ = value; } + z_cap_t endpoint_capability() const { return endpoint_capability_; } + void set_endpoint_capability(const z_cap_t& value) { endpoint_capability_ = value; } + + private: + glcr::String endpoint_name_; + z_cap_t endpoint_capability_; + +}; class Empty { public: Empty() {} @@ -19,24 +40,6 @@ class Empty { private: -}; -class RegisterInfo { - public: - RegisterInfo() {} - // Delete copy and move until implemented. - RegisterInfo(const RegisterInfo&) = delete; - RegisterInfo(RegisterInfo&&) = delete; - - void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset); - void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&); - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; - z_cap_t register_port() const { return register_port_; } - void set_register_port(const z_cap_t& value) { register_port_ = value; } - - private: - z_cap_t register_port_; - }; class AhciInfo { public: diff --git a/sys/yellowstone/include/yellowstone/yellowstone.yunq.server.cpp b/sys/yellowstone/include/yellowstone/yellowstone.yunq.server.cpp index ea98ce0..c9660fe 100644 --- a/sys/yellowstone/include/yellowstone/yellowstone.yunq.server.cpp +++ b/sys/yellowstone/include/yellowstone/yellowstone.yunq.server.cpp @@ -86,12 +86,12 @@ glcr::ErrorCode YellowstoneServerBase::HandleRequest(const glcr::ByteBuffer& req switch(method_select) { case 0: { - Empty yunq_request; - RegisterInfo yunq_response; + RegisterEndpointRequest yunq_request; + Empty yunq_response; yunq_request.ParseFromBytes(request, kHeaderSize, req_caps); - RET_ERR(HandleGetRegister(yunq_request, yunq_response)); + RET_ERR(HandleRegisterEndpoint(yunq_request, yunq_response)); resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); break; diff --git a/sys/yellowstone/include/yellowstone/yellowstone.yunq.server.h b/sys/yellowstone/include/yellowstone/yellowstone.yunq.server.h index 0d49ef2..13c3da3 100644 --- a/sys/yellowstone/include/yellowstone/yellowstone.yunq.server.h +++ b/sys/yellowstone/include/yellowstone/yellowstone.yunq.server.h @@ -21,7 +21,7 @@ class YellowstoneServerBase { [[nodiscard]] Thread RunServer(); - [[nodiscard]] virtual glcr::ErrorCode HandleGetRegister(const Empty&, RegisterInfo&) = 0; + [[nodiscard]] virtual glcr::ErrorCode HandleRegisterEndpoint(const RegisterEndpointRequest&, Empty&) = 0; [[nodiscard]] virtual glcr::ErrorCode HandleGetAhciInfo(const Empty&, AhciInfo&) = 0; diff --git a/sys/yellowstone/yellowstone.cpp b/sys/yellowstone/yellowstone.cpp index e367359..5a2f34e 100644 --- a/sys/yellowstone/yellowstone.cpp +++ b/sys/yellowstone/yellowstone.cpp @@ -13,7 +13,6 @@ uint64_t main(uint64_t port_cap) { check(ParseInitPort(port_cap)); ASSIGN_OR_RETURN(auto server, YellowstoneServer::Create()); - Thread registration_thread = server->RunRegistration(); Thread server_thread = server->RunServer(); uint64_t vaddr; @@ -22,7 +21,6 @@ uint64_t main(uint64_t port_cap) { check(SpawnProcessFromElfRegion(vaddr, client.Capability())); check(server_thread.Join()); - check(registration_thread.Join()); dbgln("Yellowstone Finished Successfully."); return 0; } diff --git a/sys/yellowstone/yellowstone_server.cpp b/sys/yellowstone/yellowstone_server.cpp index 133c38e..cfa02a9 100644 --- a/sys/yellowstone/yellowstone_server.cpp +++ b/sys/yellowstone/yellowstone_server.cpp @@ -13,11 +13,6 @@ namespace { -void RegistrationThreadBootstrap(void* yellowstone) { - dbgln("Yellowstone registration starting"); - static_cast(yellowstone)->RegistrationThread(); -} - struct PartitionInfo { uint64_t device_id; uint64_t partition_lba; @@ -38,16 +33,11 @@ glcr::ErrorOr HandleDenaliRegistration(z_cap_t endpoint_cap) { glcr::ErrorOr> YellowstoneServer::Create() { z_cap_t cap; RET_ERR(ZEndpointCreate(&cap)); - ASSIGN_OR_RETURN(PortServer port, PortServer::Create()); - return glcr::UniquePtr(new YellowstoneServer(cap, port)); + return glcr::UniquePtr(new YellowstoneServer(cap)); } -YellowstoneServer::YellowstoneServer(z_cap_t endpoint_cap, PortServer port) - : YellowstoneServerBase(endpoint_cap), register_port_(port) {} - -Thread YellowstoneServer::RunRegistration() { - return Thread(RegistrationThreadBootstrap, this); -} +YellowstoneServer::YellowstoneServer(z_cap_t endpoint_cap) + : YellowstoneServerBase(endpoint_cap) {} glcr::ErrorCode YellowstoneServer::HandleGetAhciInfo(const Empty&, AhciInfo& info) { @@ -65,51 +55,30 @@ glcr::ErrorCode YellowstoneServer::HandleGetDenali(const Empty&, info.set_lba_offset(lba_offset_); return glcr::OK; } -glcr::ErrorCode YellowstoneServer::HandleGetRegister(const Empty&, - RegisterInfo& info) { - auto client_or = register_port_.CreateClient(); - if (!client_or.ok()) { - dbgln("Error creating register client: %u", client_or.error()); - return glcr::INTERNAL; + +glcr::ErrorCode YellowstoneServer::HandleRegisterEndpoint( + const RegisterEndpointRequest& req, Empty&) { + dbgln("Registering."); + if (req.endpoint_name() == "denali") { + denali_cap_ = req.endpoint_capability(); + auto part_info_or = HandleDenaliRegistration(denali_cap_); + if (!part_info_or.ok()) { + check(part_info_or.error()); + } + device_id_ = part_info_or.value().device_id; + lba_offset_ = part_info_or.value().partition_lba; + + uint64_t vaddr; + check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootVictoriaFallsVmmoCap, &vaddr)); + auto client_or = CreateClient(); + if (!client_or.ok()) { + check(client_or.error()); + } + check(SpawnProcessFromElfRegion(vaddr, client_or.value().Capability())); + } else if (req.endpoint_name() == "victoriafalls") { + victoria_falls_cap_ = req.endpoint_capability(); + } else { + dbgln("[WARN] Got endpoint cap type: %s", req.endpoint_name().cstr()); } - info.set_register_port(client_or.value().cap()); return glcr::OK; } - -void YellowstoneServer::RegistrationThread() { - while (true) { - uint64_t num_bytes = kBufferSize; - z_cap_t endpoint_cap; - // FIXME: Better error handling here. - check(register_port_.RecvCap(&num_bytes, registration_buffer_, - &endpoint_cap)); - glcr::String name(registration_buffer_); - if (name == "denali") { - denali_cap_ = endpoint_cap; - auto part_info_or = HandleDenaliRegistration(denali_cap_); - if (!part_info_or.ok()) { - check(part_info_or.error()); - } - device_id_ = part_info_or.value().device_id; - lba_offset_ = part_info_or.value().partition_lba; - - uint64_t vaddr; - check( - ZAddressSpaceMap(gSelfVmasCap, 0, gBootVictoriaFallsVmmoCap, &vaddr)); - auto client_or = CreateClient(); - if (!client_or.ok()) { - check(client_or.error()); - } - check(SpawnProcessFromElfRegion(vaddr, client_or.value().Capability())); - continue; - } - - if (name == "victoriafalls") { - victoria_falls_cap_ = endpoint_cap; - continue; - } - - dbgln("[WARN] Got endpoint cap type:"); - dbgln(name.cstr()); - } -} diff --git a/sys/yellowstone/yellowstone_server.h b/sys/yellowstone/yellowstone_server.h index afe0113..633ab2d 100644 --- a/sys/yellowstone/yellowstone_server.h +++ b/sys/yellowstone/yellowstone_server.h @@ -13,22 +13,12 @@ class YellowstoneServer : public YellowstoneServerBase { public: static glcr::ErrorOr> Create(); - Thread RunRegistration(); - - void RegistrationThread(); - glcr::ErrorCode HandleGetAhciInfo(const Empty&, AhciInfo&) override; glcr::ErrorCode HandleGetDenali(const Empty&, DenaliInfo&) override; - glcr::ErrorCode HandleGetRegister(const Empty&, RegisterInfo&) override; + glcr::ErrorCode HandleRegisterEndpoint(const RegisterEndpointRequest&, + Empty&) override; private: - // FIXME: Separate this to its own service. - PortServer register_port_; - - static const uint64_t kBufferSize = 128; - uint8_t server_buffer_[kBufferSize]; - char registration_buffer_[kBufferSize]; - // TODO: Store these in a data structure. z_cap_t denali_cap_ = 0; uint64_t device_id_ = 0; @@ -37,5 +27,5 @@ class YellowstoneServer : public YellowstoneServerBase { PciReader pci_reader_; - YellowstoneServer(z_cap_t endpoint_cap, PortServer port); + YellowstoneServer(z_cap_t endpoint_cap); }; diff --git a/zion/TODO.md b/zion/TODO.md index ba4a384..6ceda09 100644 --- a/zion/TODO.md +++ b/zion/TODO.md @@ -38,6 +38,7 @@ ## Capabilities - Add syscalls for inspecting capabilities. +- Add syscalls for restricting capabilities' permissions. - Randomize/obfuscate capability numbers passed to user space. - Remove ReplyPort capabilities once the response is sent.