From 393a7653e73d33dc91a1e5634bd74f3d57e08c06 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Wed, 22 Jun 2022 20:55:29 +0000 Subject: [PATCH] kata-os-camkes: wrap reply ipc buffer capability handling Add Camkes::set_reply_cap and Camkes:set_reply_cap_release to attach an seL4 capability to a reply message. The latter ensures the attached capability is deleted after the seL4 rpc reply is done (this happens inside the CAmkES C code). Change-Id: I42fad2e70e6c02fcc0de5ab9a460c5a773041900 GitOrigin-RevId: 7f59e75b10697501a217f943672a40ff67f48229 --- .../kata-security-component/src/run.rs | 7 +++-- .../kata-os-common/src/camkes/src/lib.rs | 30 +++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/apps/system/components/SecurityCoordinator/kata-security-component/src/run.rs b/apps/system/components/SecurityCoordinator/kata-security-component/src/run.rs index 40d9f8f..09184eb 100644 --- a/apps/system/components/SecurityCoordinator/kata-security-component/src/run.rs +++ b/apps/system/components/SecurityCoordinator/kata-security-component/src/run.rs @@ -17,7 +17,6 @@ use log::trace; use SecurityRequestError::*; use sel4_sys::seL4_CPtr; -use sel4_sys::seL4_SetCap; static mut CAMKES: Camkes = Camkes::new("SecurityCoordinator"); static mut SECURITY_RECV_SLOT: seL4_CPtr = 0; @@ -162,7 +161,8 @@ fn load_application_request( reply_buffer ).map_err(serialize_failure)?; trace!("LOAD APPLICATION -> {}", bundle_frames); - unsafe { seL4_SetCap(0, bundle_frames.cnode) }; + // Cleanup allocated slot & mark cap for release after reply completes. + Camkes::set_reply_cap_release(bundle_frames.cnode); Ok(()) } @@ -184,7 +184,8 @@ fn load_model_request( reply_buffer ).map_err(serialize_failure)?; trace!("LOAD MODEL -> {}", model_frames); - unsafe { seL4_SetCap(0, model_frames.cnode) }; + // Cleanup allocated slot & mark cap for release after reply completes. + Camkes::set_reply_cap_release(model_frames.cnode); Ok(()) } diff --git a/apps/system/components/kata-os-common/src/camkes/src/lib.rs b/apps/system/components/kata-os-common/src/camkes/src/lib.rs index 0c5ad69..6ef447d 100644 --- a/apps/system/components/kata-os-common/src/camkes/src/lib.rs +++ b/apps/system/components/kata-os-common/src/camkes/src/lib.rs @@ -29,6 +29,13 @@ extern "C" { static SELF_CNODE_LAST_SLOT: seL4_CPtr; } +// Flag or'd into reply capability to indicate the cap should be +// deleted _after_ the reply is done. This depends on KataOS-specific +// CAmkES support enabled through build glue (cbindgen processes this +// crate to generate CamkesBindings.h which exports #define CAP_RELEASE +// that enables the necessaery #ifdef's). +pub const CAP_RELEASE: usize = 0x8000_0000; + // RAII wrapper for handling request cap cleanup. pub struct RequestCapCleanup {} impl Drop for RequestCapCleanup { @@ -132,6 +139,29 @@ impl Camkes { RequestCapCleanup{} } + // Attaches a capability to a CAmkES RPC reply msg. seL4 will copy + // the capabiltiy. + pub fn set_reply_cap(cptr: seL4_CPtr) { + unsafe { seL4_SetCap(0, cptr); } + } + + // Attaches a capability to a CAmkES RPC reply msg and arranges for + // the capability to be released after the reply completes. + pub fn set_reply_cap_release(cptr: seL4_CPtr) { + unsafe { + // NB: logically this belongs in the CAmkES code where the + // cap is deleted but that's not possible so do it here--there + // should be no race to re-purpose the slot since everything + // is assumed single-threaded (and CAmkES-generated code does + // not short-circuit the cap delete). + KATA_CSPACE_SLOTS.free(cptr, 1); + seL4_SetCap(0, cptr | CAP_RELEASE); + } + } + + // Clears any capability attached to a CAmkES RPC reply msg. + pub fn clear_reply_cap() { Camkes::set_reply_cap(0); } + // Wrappers for sel4_sys::debug_assert macros. pub fn debug_assert_slot_empty(tag: &str, path: &seL4_CPath) { sel4_sys::debug_assert_slot_empty!(path.1,