Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dev_tests/src/ratchet.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -40,10 +40,10 @@ fn ratchet_globals() -> Result<()> {
("litebox_platform_lvbs/", 24),
("litebox_platform_multiplex/", 1),
("litebox_platform_windows_userland/", 8),
("litebox_runner_lvbs/", 6),
("litebox_runner_lvbs/", 5),
("litebox_runner_snp/", 2),
("litebox_shim_linux/", 1),
("litebox_shim_optee/", 4),
("litebox_shim_optee/", 5),
],
|file| {
Ok(file
Expand Down
55 changes: 52 additions & 3 deletions litebox_common_optee/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -624,6 +624,17 @@ pub struct TeeUuid {
}

impl TeeUuid {
/// The nil UUID (all zeros, RFC 4122 S4.1.7).
///
/// Used for anonymous clients (e.g., `TeeLogin::Public`) that carry no
/// REE-derived identity.
pub const NIL: Self = Self {
time_low: 0,
time_mid: 0,
time_hi_and_version: 0,
clock_seq_and_node: [0; 8],
};

/// Converts a UUID from a 16-byte array in RFC 4122 format (big-endian for numeric fields).
///
/// The byte layout is:
Expand DownExpand Up@@ -750,7 +761,7 @@ pub struct TaHead {
pub const TA_HEAD_SECTION_NAME: &str = ".ta_head";

/// `TEE_Identity` from `optee_os/lib/libutee/include/tee_api_types.h`.
#[derive(Clone, Copy, PartialEq, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, Immutable, IntoBytes)]
#[repr(C)]
pub struct TeeIdentity {
pub login: TeeLogin,
Expand DownExpand Up@@ -832,9 +843,11 @@ const TEE_LOGIN_APPLICATION: u32 = 0x4;
const TEE_LOGIN_APPLICATION_USER: u32 = 0x5;
const TEE_LOGIN_APPLICATION_GROUP: u32 = 0x6;
const TEE_LOGIN_TRUSTED_APP: u32 = 0xf000_0000;
// Private OP-TEE login for in-kernel REE clients (`tee_api_defines_extensions.h`).
const TEE_LOGIN_REE_KERNEL: u32 = 0x8000_0000;

/// `TEE Login type` from `optee_os/lib/libutee/include/tee_api_defines.h`
#[derive(Clone, Copy, PartialEq, TryFromPrimitive, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, TryFromPrimitive, Immutable, IntoBytes)]
#[repr(u32)]
pub enum TeeLogin {
Public = TEE_LOGIN_PUBLIC,
Expand All@@ -843,6 +856,7 @@ pub enum TeeLogin {
Application = TEE_LOGIN_APPLICATION,
ApplicationUser = TEE_LOGIN_APPLICATION_USER,
ApplicationGroup = TEE_LOGIN_APPLICATION_GROUP,
ReeKernel = TEE_LOGIN_REE_KERNEL,
TrustedApp = TEE_LOGIN_TRUSTED_APP,
}

Expand DownExpand Up@@ -1469,6 +1483,10 @@ const OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: u8 = 0xb;
// Note: `OPTEE_MSG_ATTR_TYPE_FMEM_*` are aliases of `OPTEE_MSG_ATTR_TYPE_RMEM_*`.
// Whether it is RMEM of FMEM depends on the conduit.

/// Meta-parameter marker of the attribute word. Set on the `OpenSession`
/// TA-UUID and client-identity params.
const OPTEE_MSG_ATTR_META: u64 = 1 << 8;

#[non_exhaustive]
#[derive(Debug, PartialEq, TryFromPrimitive)]
#[repr(u8)]
Expand All@@ -1492,11 +1510,17 @@ pub enum OpteeMsgAttrType {
/// - bit 8 – meta
/// - bit 9 – noncontig
/// - bits \[63:10\] – reserved (zero)
#[derive(Clone, Copy, Default, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[derive(Clone, Copy, Default, PartialEq, Eq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(transparent)]
pub struct OpteeMsgAttr(u64);

impl OpteeMsgAttr {
/// The exact attribute word an `OpenSession` meta value parameter must carry
/// (`OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT`, all other bits
/// zero). See [`OpteeMsgArgs::get_meta_param_value`].
pub const META_VALUE_INPUT: Self =
Self(OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT as u64);

/// Returns the attribute type (bits 0–7).
#[allow(clippy::cast_possible_truncation)]
pub fn attr_type(&self) -> u8 {
Expand DownExpand Up@@ -1525,6 +1549,10 @@ impl OpteeMsgParam {
pub fn attr_type(&self) -> OpteeMsgAttrType {
OpteeMsgAttrType::try_from(self.attr.attr_type()).unwrap_or(OpteeMsgAttrType::None)
}
/// Returns `true` when the meta bit (bit 8) is set.
pub fn is_meta(&self) -> bool {
self.attr.meta()
}
pub fn get_param_tmem(&self) -> Option<OpteeMsgParamTmem> {
if matches!(
self.attr.attr_type(),
Expand DownExpand Up@@ -1757,6 +1785,27 @@ impl OpteeMsgArgs {
.ok_or(OpteeSmcReturnCode::EBadCmd)?)
}
}

/// Read a value parameter that must be tagged as an `OpenSession` meta parameter.
///
/// `OpenSession` conveys the TA UUID and client identity in the first two
/// params, each marked exactly [`OpteeMsgAttr::META_VALUE_INPUT`], mirroring
/// OP-TEE OS `get_open_session_meta()`. Plain `get_param_value` ignores
/// these bits, so it must not be used for this.
pub fn get_meta_param_value(
&self,
index: usize,
) -> Result<OpteeMsgParamValue, OpteeSmcReturnCode> {
if index >= self.num_params as usize {
return Err(OpteeSmcReturnCode::ENotAvail);
}
let param = &self.params[index];
if param.attr != OpteeMsgAttr::META_VALUE_INPUT {
return Err(OpteeSmcReturnCode::EBadCmd);
}
param.get_param_value().ok_or(OpteeSmcReturnCode::EBadCmd)
}

pub fn set_param_value(
&mut self,
index: usize,
Expand Down
1 change: 0 additions & 1 deletion litebox_runner_lvbs/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,6 @@ litebox_shim_optee = { path = "../litebox_shim_optee/", version = "0.1.0" }
litebox_util_log = { version = "0.1.0", path = "../litebox_util_log" }
log = { version = "0.4", default-features = false }
spin = { version = "0.10.0", default-features = false, features = ["spin_mutex"] }
once_cell = { version = "1.21.3", default-features = false, features = ["race", "alloc"] }

[target.'cfg(target_arch = "x86_64")'.dependencies]
x86_64 = { version = "0.15.2", default-features = false, features = ["instructions"] }
Expand Down
50 changes: 24 additions & 26 deletions litebox_runner_lvbs/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,9 +42,8 @@ use litebox_shim_optee::msg_handler::{
decode_ta_request, handle_optee_msg_args, handle_optee_smc_args, packed_msg_args_lock,
update_optee_msg_args,
};
use litebox_shim_optee::session::{OpenSessionTarget, SessionManager, TaInstance};
use litebox_shim_optee::session::{OpenSessionTarget, TaInstance, session_manager};
use litebox_shim_optee::{NormalWorldConstPtr, NormalWorldMutPtr, UserConstPtr};
use once_cell::race::OnceBox;

/// Seed the initial heap regions so the global allocator has enough memory
/// for slab-backed allocations (the slab needs >= 2 MB backing pages).
Expand DownExpand Up@@ -288,12 +287,6 @@ fn optee_smc_handler_entry_inner(
Ok(0)
}

/// Get the global session manager.
fn session_manager() -> &'static SessionManager {
static SESSION_MANAGER: OnceBox<SessionManager> = OnceBox::new();
SESSION_MANAGER.get_or_init(|| Box::new(SessionManager::new()))
}

/// Switch to the base page table.
///
/// This must be called before returning to VTL0 to ensure VTL1 reentry is
Expand DownExpand Up@@ -527,6 +520,7 @@ fn handle_open_session(
msg_args_phys_addr,
instance,
params,
client_identity,
&ta_req_info,
),
OpenSessionTarget::NewInstance => open_session_new_instance(
Expand DownExpand Up@@ -560,6 +554,7 @@ fn open_session_single_instance(
msg_args_phys_addr: u64,
instance: &TaInstance,
params: &[litebox_common_optee::UteeParamOwned],
client_identity: Option<litebox_common_optee::TeeIdentity>,
ta_req_info: &litebox_shim_optee::msg_handler::TaRequestInfo<PAGE_SIZE>,
) -> Result<(), OpteeSmcReturnCode> {
let task_pt_id = instance.task_page_table_id();
Expand All@@ -570,6 +565,9 @@ fn open_session_single_instance(
// Safe to unwrap: session ID has been just created.
let runner_session_id = session_token.session_id().unwrap();

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

debug_serial_println!(
"Reusing single-instance TA: uuid={:?}, task_pt_id={}, session_id={}",
ta_uuid,
Expand All@@ -588,7 +586,7 @@ fn open_session_single_instance(
.ok_or(OpteeSmcReturnCode::EBadCmd)?
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -686,6 +684,9 @@ fn open_session_single_instance(
teardown_ta_page_table(instance.shim(), task_pt_id);
};
} else {
// The session id is forgotten (never recycled), so the token's drop
// won't clear the recorded identity. Remove the client identity here.
session_manager().clear_session_client_identity(runner_session_id);
Comment thread
sangho2 marked this conversation as resolved.
session_token.disarm();
}
return Err(e);
Expand All@@ -704,7 +705,7 @@ fn open_session_single_instance(
}

/// Create a new TA instance for a session. Must be called from within a
/// [`SessionManager::with_ta`] closure.
/// [`litebox_shim_optee::session::SessionManager::with_ta`] closure.
///
/// If ldelf loading or OpenSession entry point fails, the page table is torn down.
/// Per OP-TEE OS semantics: if OpenSession returns non-success, cleanup happens.
Expand DownExpand Up@@ -741,19 +742,13 @@ fn open_session_new_instance(
// Load ldelf and TA - Box immediately to keep at fixed heap address
let shim = litebox_shim_optee::OpteeShimBuilder::new().build();
let loaded_program = Box::new(
shim.load_ldelf(
LDELF_BINARY,
ta_uuid,
Some(ta_bin),
client_identity,
runner_session_id,
)
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
shim.load_ldelf(LDELF_BINARY, ta_uuid, Some(ta_bin))
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
);

let ta_flags = loaded_program.ta_flags;
Expand DownExpand Up@@ -801,6 +796,9 @@ fn open_session_new_instance(
return Ok(());
}

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

// Load TA context with parameters for OpenSession - pass actual session_id
loaded_program.entrypoints.as_ref().ok_or_else(|| {
// Safety: We are about to tear down this TA instance;
Expand All@@ -814,7 +812,7 @@ fn open_session_new_instance(
.unwrap()
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -983,7 +981,7 @@ fn handle_invoke_command(
entrypoints_ref
.load_ta_context(
params.as_slice(),
Some(session_id),
session_id,
UteeEntryFunc::InvokeCommand as u32,
Some(cmd_id),
)
Expand DownExpand Up@@ -1095,7 +1093,7 @@ fn handle_close_session(
.unwrap()
.load_ta_context(
&[],
Some(session_id),
session_id,
UteeEntryFunc::CloseSession as u32,
None,
)
Expand Down
15 changes: 4 additions & 11 deletions litebox_runner_optee_on_linux_userland/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ use anyhow::{Context as _, Result};
use clap::Parser;
use litebox_common_optee::{TeeUuid, UteeEntryFunc, UteeParamOwned};
use litebox_platform_multiplex::Platform;
use litebox_shim_optee::session::SessionManager;
use litebox_shim_optee::session::session_manager;
use std::path::PathBuf;

mod tests;
Expand DownExpand Up@@ -109,21 +109,14 @@ fn run_ta_with_default_commands(
ldelf_bin: &[u8],
ta_bin: &[u8],
) {
let session_manager = SessionManager::new();
for func_id in [UteeEntryFunc::OpenSession, UteeEntryFunc::CloseSession] {
let params = [const { UteeParamOwned::None }; UteeParamOwned::TEE_NUM_PARAMS];

if func_id == UteeEntryFunc::OpenSession {
let session_token = session_manager.try_acquire_open_session_token().unwrap();
let session_token = session_manager().try_acquire_open_session_token().unwrap();
let session_id = session_token.session_id().unwrap();
let loaded_program = shim
.load_ldelf(
ldelf_bin,
TeeUuid::default(),
Some(ta_bin),
None,
session_id,
)
.load_ldelf(ldelf_bin, TeeUuid::default(), Some(ta_bin))
.map_err(|_| {
panic!("Failed to load ldelf");
})
Expand All@@ -140,7 +133,7 @@ fn run_ta_with_default_commands(
// loaded binary and heap. In that sense, we can create (and destroy) a stack
// for each command freely.
let _ = entrypoints
.load_ta_context(params.as_slice(), None, func_id as u32, None)
.load_ta_context(params.as_slice(), session_id, func_id as u32, None)
.map_err(|_| {
panic!("Failed to load TA context");
});
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Add per-session OP-TEE client identity handling by sangho2 · Pull Request #885 · microsoft/litebox · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dev_tests/src/ratchet.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -40,10 +40,10 @@ fn ratchet_globals() -> Result<()> {
("litebox_platform_lvbs/", 24),
("litebox_platform_multiplex/", 1),
("litebox_platform_windows_userland/", 8),
("litebox_runner_lvbs/", 6),
("litebox_runner_lvbs/", 5),
("litebox_runner_snp/", 2),
("litebox_shim_linux/", 1),
("litebox_shim_optee/", 4),
("litebox_shim_optee/", 5),
],
|file| {
Ok(file
Expand Down
55 changes: 52 additions & 3 deletions litebox_common_optee/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -624,6 +624,17 @@ pub struct TeeUuid {
}

impl TeeUuid {
/// The nil UUID (all zeros, RFC 4122 S4.1.7).
///
/// Used for anonymous clients (e.g., `TeeLogin::Public`) that carry no
/// REE-derived identity.
pub const NIL: Self = Self {
time_low: 0,
time_mid: 0,
time_hi_and_version: 0,
clock_seq_and_node: [0; 8],
};

/// Converts a UUID from a 16-byte array in RFC 4122 format (big-endian for numeric fields).
///
/// The byte layout is:
Expand DownExpand Up@@ -750,7 +761,7 @@ pub struct TaHead {
pub const TA_HEAD_SECTION_NAME: &str = ".ta_head";

/// `TEE_Identity` from `optee_os/lib/libutee/include/tee_api_types.h`.
#[derive(Clone, Copy, PartialEq, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, Immutable, IntoBytes)]
#[repr(C)]
pub struct TeeIdentity {
pub login: TeeLogin,
Expand DownExpand Up@@ -832,9 +843,11 @@ const TEE_LOGIN_APPLICATION: u32 = 0x4;
const TEE_LOGIN_APPLICATION_USER: u32 = 0x5;
const TEE_LOGIN_APPLICATION_GROUP: u32 = 0x6;
const TEE_LOGIN_TRUSTED_APP: u32 = 0xf000_0000;
// Private OP-TEE login for in-kernel REE clients (`tee_api_defines_extensions.h`).
const TEE_LOGIN_REE_KERNEL: u32 = 0x8000_0000;

/// `TEE Login type` from `optee_os/lib/libutee/include/tee_api_defines.h`
#[derive(Clone, Copy, PartialEq, TryFromPrimitive, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, TryFromPrimitive, Immutable, IntoBytes)]
#[repr(u32)]
pub enum TeeLogin {
Public = TEE_LOGIN_PUBLIC,
Expand All@@ -843,6 +856,7 @@ pub enum TeeLogin {
Application = TEE_LOGIN_APPLICATION,
ApplicationUser = TEE_LOGIN_APPLICATION_USER,
ApplicationGroup = TEE_LOGIN_APPLICATION_GROUP,
ReeKernel = TEE_LOGIN_REE_KERNEL,
TrustedApp = TEE_LOGIN_TRUSTED_APP,
}

Expand DownExpand Up@@ -1469,6 +1483,10 @@ const OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: u8 = 0xb;
// Note: `OPTEE_MSG_ATTR_TYPE_FMEM_*` are aliases of `OPTEE_MSG_ATTR_TYPE_RMEM_*`.
// Whether it is RMEM of FMEM depends on the conduit.

/// Meta-parameter marker of the attribute word. Set on the `OpenSession`
/// TA-UUID and client-identity params.
const OPTEE_MSG_ATTR_META: u64 = 1 << 8;

#[non_exhaustive]
#[derive(Debug, PartialEq, TryFromPrimitive)]
#[repr(u8)]
Expand All@@ -1492,11 +1510,17 @@ pub enum OpteeMsgAttrType {
/// - bit 8 – meta
/// - bit 9 – noncontig
/// - bits \[63:10\] – reserved (zero)
#[derive(Clone, Copy, Default, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[derive(Clone, Copy, Default, PartialEq, Eq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(transparent)]
pub struct OpteeMsgAttr(u64);

impl OpteeMsgAttr {
/// The exact attribute word an `OpenSession` meta value parameter must carry
/// (`OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT`, all other bits
/// zero). See [`OpteeMsgArgs::get_meta_param_value`].
pub const META_VALUE_INPUT: Self =
Self(OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT as u64);

/// Returns the attribute type (bits 0–7).
#[allow(clippy::cast_possible_truncation)]
pub fn attr_type(&self) -> u8 {
Expand DownExpand Up@@ -1525,6 +1549,10 @@ impl OpteeMsgParam {
pub fn attr_type(&self) -> OpteeMsgAttrType {
OpteeMsgAttrType::try_from(self.attr.attr_type()).unwrap_or(OpteeMsgAttrType::None)
}
/// Returns `true` when the meta bit (bit 8) is set.
pub fn is_meta(&self) -> bool {
self.attr.meta()
}
pub fn get_param_tmem(&self) -> Option<OpteeMsgParamTmem> {
if matches!(
self.attr.attr_type(),
Expand DownExpand Up@@ -1757,6 +1785,27 @@ impl OpteeMsgArgs {
.ok_or(OpteeSmcReturnCode::EBadCmd)?)
}
}

/// Read a value parameter that must be tagged as an `OpenSession` meta parameter.
///
/// `OpenSession` conveys the TA UUID and client identity in the first two
/// params, each marked exactly [`OpteeMsgAttr::META_VALUE_INPUT`], mirroring
/// OP-TEE OS `get_open_session_meta()`. Plain `get_param_value` ignores
/// these bits, so it must not be used for this.
pub fn get_meta_param_value(
&self,
index: usize,
) -> Result<OpteeMsgParamValue, OpteeSmcReturnCode> {
if index >= self.num_params as usize {
return Err(OpteeSmcReturnCode::ENotAvail);
}
let param = &self.params[index];
if param.attr != OpteeMsgAttr::META_VALUE_INPUT {
return Err(OpteeSmcReturnCode::EBadCmd);
}
param.get_param_value().ok_or(OpteeSmcReturnCode::EBadCmd)
}

pub fn set_param_value(
&mut self,
index: usize,
Expand Down
1 change: 0 additions & 1 deletion litebox_runner_lvbs/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,6 @@ litebox_shim_optee = { path = "../litebox_shim_optee/", version = "0.1.0" }
litebox_util_log = { version = "0.1.0", path = "../litebox_util_log" }
log = { version = "0.4", default-features = false }
spin = { version = "0.10.0", default-features = false, features = ["spin_mutex"] }
once_cell = { version = "1.21.3", default-features = false, features = ["race", "alloc"] }

[target.'cfg(target_arch = "x86_64")'.dependencies]
x86_64 = { version = "0.15.2", default-features = false, features = ["instructions"] }
Expand Down
50 changes: 24 additions & 26 deletions litebox_runner_lvbs/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,9 +42,8 @@ use litebox_shim_optee::msg_handler::{
decode_ta_request, handle_optee_msg_args, handle_optee_smc_args, packed_msg_args_lock,
update_optee_msg_args,
};
use litebox_shim_optee::session::{OpenSessionTarget, SessionManager, TaInstance};
use litebox_shim_optee::session::{OpenSessionTarget, TaInstance, session_manager};
use litebox_shim_optee::{NormalWorldConstPtr, NormalWorldMutPtr, UserConstPtr};
use once_cell::race::OnceBox;

/// Seed the initial heap regions so the global allocator has enough memory
/// for slab-backed allocations (the slab needs >= 2 MB backing pages).
Expand DownExpand Up@@ -288,12 +287,6 @@ fn optee_smc_handler_entry_inner(
Ok(0)
}

/// Get the global session manager.
fn session_manager() -> &'static SessionManager {
static SESSION_MANAGER: OnceBox<SessionManager> = OnceBox::new();
SESSION_MANAGER.get_or_init(|| Box::new(SessionManager::new()))
}

/// Switch to the base page table.
///
/// This must be called before returning to VTL0 to ensure VTL1 reentry is
Expand DownExpand Up@@ -527,6 +520,7 @@ fn handle_open_session(
msg_args_phys_addr,
instance,
params,
client_identity,
&ta_req_info,
),
OpenSessionTarget::NewInstance => open_session_new_instance(
Expand DownExpand Up@@ -560,6 +554,7 @@ fn open_session_single_instance(
msg_args_phys_addr: u64,
instance: &TaInstance,
params: &[litebox_common_optee::UteeParamOwned],
client_identity: Option<litebox_common_optee::TeeIdentity>,
ta_req_info: &litebox_shim_optee::msg_handler::TaRequestInfo<PAGE_SIZE>,
) -> Result<(), OpteeSmcReturnCode> {
let task_pt_id = instance.task_page_table_id();
Expand All@@ -570,6 +565,9 @@ fn open_session_single_instance(
// Safe to unwrap: session ID has been just created.
let runner_session_id = session_token.session_id().unwrap();

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

debug_serial_println!(
"Reusing single-instance TA: uuid={:?}, task_pt_id={}, session_id={}",
ta_uuid,
Expand All@@ -588,7 +586,7 @@ fn open_session_single_instance(
.ok_or(OpteeSmcReturnCode::EBadCmd)?
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -686,6 +684,9 @@ fn open_session_single_instance(
teardown_ta_page_table(instance.shim(), task_pt_id);
};
} else {
// The session id is forgotten (never recycled), so the token's drop
// won't clear the recorded identity. Remove the client identity here.
session_manager().clear_session_client_identity(runner_session_id);
Comment thread
sangho2 marked this conversation as resolved.
session_token.disarm();
}
return Err(e);
Expand All@@ -704,7 +705,7 @@ fn open_session_single_instance(
}

/// Create a new TA instance for a session. Must be called from within a
/// [`SessionManager::with_ta`] closure.
/// [`litebox_shim_optee::session::SessionManager::with_ta`] closure.
///
/// If ldelf loading or OpenSession entry point fails, the page table is torn down.
/// Per OP-TEE OS semantics: if OpenSession returns non-success, cleanup happens.
Expand DownExpand Up@@ -741,19 +742,13 @@ fn open_session_new_instance(
// Load ldelf and TA - Box immediately to keep at fixed heap address
let shim = litebox_shim_optee::OpteeShimBuilder::new().build();
let loaded_program = Box::new(
shim.load_ldelf(
LDELF_BINARY,
ta_uuid,
Some(ta_bin),
client_identity,
runner_session_id,
)
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
shim.load_ldelf(LDELF_BINARY, ta_uuid, Some(ta_bin))
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
);

let ta_flags = loaded_program.ta_flags;
Expand DownExpand Up@@ -801,6 +796,9 @@ fn open_session_new_instance(
return Ok(());
}

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

// Load TA context with parameters for OpenSession - pass actual session_id
loaded_program.entrypoints.as_ref().ok_or_else(|| {
// Safety: We are about to tear down this TA instance;
Expand All@@ -814,7 +812,7 @@ fn open_session_new_instance(
.unwrap()
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -983,7 +981,7 @@ fn handle_invoke_command(
entrypoints_ref
.load_ta_context(
params.as_slice(),
Some(session_id),
session_id,
UteeEntryFunc::InvokeCommand as u32,
Some(cmd_id),
)
Expand DownExpand Up@@ -1095,7 +1093,7 @@ fn handle_close_session(
.unwrap()
.load_ta_context(
&[],
Some(session_id),
session_id,
UteeEntryFunc::CloseSession as u32,
None,
)
Expand Down
15 changes: 4 additions & 11 deletions litebox_runner_optee_on_linux_userland/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ use anyhow::{Context as _, Result};
use clap::Parser;
use litebox_common_optee::{TeeUuid, UteeEntryFunc, UteeParamOwned};
use litebox_platform_multiplex::Platform;
use litebox_shim_optee::session::SessionManager;
use litebox_shim_optee::session::session_manager;
use std::path::PathBuf;

mod tests;
Expand DownExpand Up@@ -109,21 +109,14 @@ fn run_ta_with_default_commands(
ldelf_bin: &[u8],
ta_bin: &[u8],
) {
let session_manager = SessionManager::new();
for func_id in [UteeEntryFunc::OpenSession, UteeEntryFunc::CloseSession] {
let params = [const { UteeParamOwned::None }; UteeParamOwned::TEE_NUM_PARAMS];

if func_id == UteeEntryFunc::OpenSession {
let session_token = session_manager.try_acquire_open_session_token().unwrap();
let session_token = session_manager().try_acquire_open_session_token().unwrap();
let session_id = session_token.session_id().unwrap();
let loaded_program = shim
.load_ldelf(
ldelf_bin,
TeeUuid::default(),
Some(ta_bin),
None,
session_id,
)
.load_ldelf(ldelf_bin, TeeUuid::default(), Some(ta_bin))
.map_err(|_| {
panic!("Failed to load ldelf");
})
Expand All@@ -140,7 +133,7 @@ fn run_ta_with_default_commands(
// loaded binary and heap. In that sense, we can create (and destroy) a stack
// for each command freely.
let _ = entrypoints
.load_ta_context(params.as_slice(), None, func_id as u32, None)
.load_ta_context(params.as_slice(), session_id, func_id as u32, None)
.map_err(|_| {
panic!("Failed to load TA context");
});
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add per-session OP-TEE client identity handling by sangho2 · Pull Request #885 · microsoft/litebox · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dev_tests/src/ratchet.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -40,10 +40,10 @@ fn ratchet_globals() -> Result<()> {
("litebox_platform_lvbs/", 24),
("litebox_platform_multiplex/", 1),
("litebox_platform_windows_userland/", 8),
("litebox_runner_lvbs/", 6),
("litebox_runner_lvbs/", 5),
("litebox_runner_snp/", 2),
("litebox_shim_linux/", 1),
("litebox_shim_optee/", 4),
("litebox_shim_optee/", 5),
],
|file| {
Ok(file
Expand Down
55 changes: 52 additions & 3 deletions litebox_common_optee/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -624,6 +624,17 @@ pub struct TeeUuid {
}

impl TeeUuid {
/// The nil UUID (all zeros, RFC 4122 S4.1.7).
///
/// Used for anonymous clients (e.g., `TeeLogin::Public`) that carry no
/// REE-derived identity.
pub const NIL: Self = Self {
time_low: 0,
time_mid: 0,
time_hi_and_version: 0,
clock_seq_and_node: [0; 8],
};

/// Converts a UUID from a 16-byte array in RFC 4122 format (big-endian for numeric fields).
///
/// The byte layout is:
Expand DownExpand Up@@ -750,7 +761,7 @@ pub struct TaHead {
pub const TA_HEAD_SECTION_NAME: &str = ".ta_head";

/// `TEE_Identity` from `optee_os/lib/libutee/include/tee_api_types.h`.
#[derive(Clone, Copy, PartialEq, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, Immutable, IntoBytes)]
#[repr(C)]
pub struct TeeIdentity {
pub login: TeeLogin,
Expand DownExpand Up@@ -832,9 +843,11 @@ const TEE_LOGIN_APPLICATION: u32 = 0x4;
const TEE_LOGIN_APPLICATION_USER: u32 = 0x5;
const TEE_LOGIN_APPLICATION_GROUP: u32 = 0x6;
const TEE_LOGIN_TRUSTED_APP: u32 = 0xf000_0000;
// Private OP-TEE login for in-kernel REE clients (`tee_api_defines_extensions.h`).
const TEE_LOGIN_REE_KERNEL: u32 = 0x8000_0000;

/// `TEE Login type` from `optee_os/lib/libutee/include/tee_api_defines.h`
#[derive(Clone, Copy, PartialEq, TryFromPrimitive, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, TryFromPrimitive, Immutable, IntoBytes)]
#[repr(u32)]
pub enum TeeLogin {
Public = TEE_LOGIN_PUBLIC,
Expand All@@ -843,6 +856,7 @@ pub enum TeeLogin {
Application = TEE_LOGIN_APPLICATION,
ApplicationUser = TEE_LOGIN_APPLICATION_USER,
ApplicationGroup = TEE_LOGIN_APPLICATION_GROUP,
ReeKernel = TEE_LOGIN_REE_KERNEL,
TrustedApp = TEE_LOGIN_TRUSTED_APP,
}

Expand DownExpand Up@@ -1469,6 +1483,10 @@ const OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: u8 = 0xb;
// Note: `OPTEE_MSG_ATTR_TYPE_FMEM_*` are aliases of `OPTEE_MSG_ATTR_TYPE_RMEM_*`.
// Whether it is RMEM of FMEM depends on the conduit.

/// Meta-parameter marker of the attribute word. Set on the `OpenSession`
/// TA-UUID and client-identity params.
const OPTEE_MSG_ATTR_META: u64 = 1 << 8;

#[non_exhaustive]
#[derive(Debug, PartialEq, TryFromPrimitive)]
#[repr(u8)]
Expand All@@ -1492,11 +1510,17 @@ pub enum OpteeMsgAttrType {
/// - bit 8 – meta
/// - bit 9 – noncontig
/// - bits \[63:10\] – reserved (zero)
#[derive(Clone, Copy, Default, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[derive(Clone, Copy, Default, PartialEq, Eq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(transparent)]
pub struct OpteeMsgAttr(u64);

impl OpteeMsgAttr {
/// The exact attribute word an `OpenSession` meta value parameter must carry
/// (`OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT`, all other bits
/// zero). See [`OpteeMsgArgs::get_meta_param_value`].
pub const META_VALUE_INPUT: Self =
Self(OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT as u64);

/// Returns the attribute type (bits 0–7).
#[allow(clippy::cast_possible_truncation)]
pub fn attr_type(&self) -> u8 {
Expand DownExpand Up@@ -1525,6 +1549,10 @@ impl OpteeMsgParam {
pub fn attr_type(&self) -> OpteeMsgAttrType {
OpteeMsgAttrType::try_from(self.attr.attr_type()).unwrap_or(OpteeMsgAttrType::None)
}
/// Returns `true` when the meta bit (bit 8) is set.
pub fn is_meta(&self) -> bool {
self.attr.meta()
}
pub fn get_param_tmem(&self) -> Option<OpteeMsgParamTmem> {
if matches!(
self.attr.attr_type(),
Expand DownExpand Up@@ -1757,6 +1785,27 @@ impl OpteeMsgArgs {
.ok_or(OpteeSmcReturnCode::EBadCmd)?)
}
}

/// Read a value parameter that must be tagged as an `OpenSession` meta parameter.
///
/// `OpenSession` conveys the TA UUID and client identity in the first two
/// params, each marked exactly [`OpteeMsgAttr::META_VALUE_INPUT`], mirroring
/// OP-TEE OS `get_open_session_meta()`. Plain `get_param_value` ignores
/// these bits, so it must not be used for this.
pub fn get_meta_param_value(
&self,
index: usize,
) -> Result<OpteeMsgParamValue, OpteeSmcReturnCode> {
if index >= self.num_params as usize {
return Err(OpteeSmcReturnCode::ENotAvail);
}
let param = &self.params[index];
if param.attr != OpteeMsgAttr::META_VALUE_INPUT {
return Err(OpteeSmcReturnCode::EBadCmd);
}
param.get_param_value().ok_or(OpteeSmcReturnCode::EBadCmd)
}

pub fn set_param_value(
&mut self,
index: usize,
Expand Down
1 change: 0 additions & 1 deletion litebox_runner_lvbs/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,6 @@ litebox_shim_optee = { path = "../litebox_shim_optee/", version = "0.1.0" }
litebox_util_log = { version = "0.1.0", path = "../litebox_util_log" }
log = { version = "0.4", default-features = false }
spin = { version = "0.10.0", default-features = false, features = ["spin_mutex"] }
once_cell = { version = "1.21.3", default-features = false, features = ["race", "alloc"] }

[target.'cfg(target_arch = "x86_64")'.dependencies]
x86_64 = { version = "0.15.2", default-features = false, features = ["instructions"] }
Expand Down
50 changes: 24 additions & 26 deletions litebox_runner_lvbs/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,9 +42,8 @@ use litebox_shim_optee::msg_handler::{
decode_ta_request, handle_optee_msg_args, handle_optee_smc_args, packed_msg_args_lock,
update_optee_msg_args,
};
use litebox_shim_optee::session::{OpenSessionTarget, SessionManager, TaInstance};
use litebox_shim_optee::session::{OpenSessionTarget, TaInstance, session_manager};
use litebox_shim_optee::{NormalWorldConstPtr, NormalWorldMutPtr, UserConstPtr};
use once_cell::race::OnceBox;

/// Seed the initial heap regions so the global allocator has enough memory
/// for slab-backed allocations (the slab needs >= 2 MB backing pages).
Expand DownExpand Up@@ -288,12 +287,6 @@ fn optee_smc_handler_entry_inner(
Ok(0)
}

/// Get the global session manager.
fn session_manager() -> &'static SessionManager {
static SESSION_MANAGER: OnceBox<SessionManager> = OnceBox::new();
SESSION_MANAGER.get_or_init(|| Box::new(SessionManager::new()))
}

/// Switch to the base page table.
///
/// This must be called before returning to VTL0 to ensure VTL1 reentry is
Expand DownExpand Up@@ -527,6 +520,7 @@ fn handle_open_session(
msg_args_phys_addr,
instance,
params,
client_identity,
&ta_req_info,
),
OpenSessionTarget::NewInstance => open_session_new_instance(
Expand DownExpand Up@@ -560,6 +554,7 @@ fn open_session_single_instance(
msg_args_phys_addr: u64,
instance: &TaInstance,
params: &[litebox_common_optee::UteeParamOwned],
client_identity: Option<litebox_common_optee::TeeIdentity>,
ta_req_info: &litebox_shim_optee::msg_handler::TaRequestInfo<PAGE_SIZE>,
) -> Result<(), OpteeSmcReturnCode> {
let task_pt_id = instance.task_page_table_id();
Expand All@@ -570,6 +565,9 @@ fn open_session_single_instance(
// Safe to unwrap: session ID has been just created.
let runner_session_id = session_token.session_id().unwrap();

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

debug_serial_println!(
"Reusing single-instance TA: uuid={:?}, task_pt_id={}, session_id={}",
ta_uuid,
Expand All@@ -588,7 +586,7 @@ fn open_session_single_instance(
.ok_or(OpteeSmcReturnCode::EBadCmd)?
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -686,6 +684,9 @@ fn open_session_single_instance(
teardown_ta_page_table(instance.shim(), task_pt_id);
};
} else {
// The session id is forgotten (never recycled), so the token's drop
// won't clear the recorded identity. Remove the client identity here.
session_manager().clear_session_client_identity(runner_session_id);
Comment thread
sangho2 marked this conversation as resolved.
session_token.disarm();
}
return Err(e);
Expand All@@ -704,7 +705,7 @@ fn open_session_single_instance(
}

/// Create a new TA instance for a session. Must be called from within a
/// [`SessionManager::with_ta`] closure.
/// [`litebox_shim_optee::session::SessionManager::with_ta`] closure.
///
/// If ldelf loading or OpenSession entry point fails, the page table is torn down.
/// Per OP-TEE OS semantics: if OpenSession returns non-success, cleanup happens.
Expand DownExpand Up@@ -741,19 +742,13 @@ fn open_session_new_instance(
// Load ldelf and TA - Box immediately to keep at fixed heap address
let shim = litebox_shim_optee::OpteeShimBuilder::new().build();
let loaded_program = Box::new(
shim.load_ldelf(
LDELF_BINARY,
ta_uuid,
Some(ta_bin),
client_identity,
runner_session_id,
)
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
shim.load_ldelf(LDELF_BINARY, ta_uuid, Some(ta_bin))
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
);

let ta_flags = loaded_program.ta_flags;
Expand DownExpand Up@@ -801,6 +796,9 @@ fn open_session_new_instance(
return Ok(());
}

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

// Load TA context with parameters for OpenSession - pass actual session_id
loaded_program.entrypoints.as_ref().ok_or_else(|| {
// Safety: We are about to tear down this TA instance;
Expand All@@ -814,7 +812,7 @@ fn open_session_new_instance(
.unwrap()
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -983,7 +981,7 @@ fn handle_invoke_command(
entrypoints_ref
.load_ta_context(
params.as_slice(),
Some(session_id),
session_id,
UteeEntryFunc::InvokeCommand as u32,
Some(cmd_id),
)
Expand DownExpand Up@@ -1095,7 +1093,7 @@ fn handle_close_session(
.unwrap()
.load_ta_context(
&[],
Some(session_id),
session_id,
UteeEntryFunc::CloseSession as u32,
None,
)
Expand Down
15 changes: 4 additions & 11 deletions litebox_runner_optee_on_linux_userland/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ use anyhow::{Context as _, Result};
use clap::Parser;
use litebox_common_optee::{TeeUuid, UteeEntryFunc, UteeParamOwned};
use litebox_platform_multiplex::Platform;
use litebox_shim_optee::session::SessionManager;
use litebox_shim_optee::session::session_manager;
use std::path::PathBuf;

mod tests;
Expand DownExpand Up@@ -109,21 +109,14 @@ fn run_ta_with_default_commands(
ldelf_bin: &[u8],
ta_bin: &[u8],
) {
let session_manager = SessionManager::new();
for func_id in [UteeEntryFunc::OpenSession, UteeEntryFunc::CloseSession] {
let params = [const { UteeParamOwned::None }; UteeParamOwned::TEE_NUM_PARAMS];

if func_id == UteeEntryFunc::OpenSession {
let session_token = session_manager.try_acquire_open_session_token().unwrap();
let session_token = session_manager().try_acquire_open_session_token().unwrap();
let session_id = session_token.session_id().unwrap();
let loaded_program = shim
.load_ldelf(
ldelf_bin,
TeeUuid::default(),
Some(ta_bin),
None,
session_id,
)
.load_ldelf(ldelf_bin, TeeUuid::default(), Some(ta_bin))
.map_err(|_| {
panic!("Failed to load ldelf");
})
Expand All@@ -140,7 +133,7 @@ fn run_ta_with_default_commands(
// loaded binary and heap. In that sense, we can create (and destroy) a stack
// for each command freely.
let _ = entrypoints
.load_ta_context(params.as_slice(), None, func_id as u32, None)
.load_ta_context(params.as_slice(), session_id, func_id as u32, None)
.map_err(|_| {
panic!("Failed to load TA context");
});
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add per-session OP-TEE client identity handling by sangho2 · Pull Request #885 · microsoft/litebox · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dev_tests/src/ratchet.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -40,10 +40,10 @@ fn ratchet_globals() -> Result<()> {
("litebox_platform_lvbs/", 24),
("litebox_platform_multiplex/", 1),
("litebox_platform_windows_userland/", 8),
("litebox_runner_lvbs/", 6),
("litebox_runner_lvbs/", 5),
("litebox_runner_snp/", 2),
("litebox_shim_linux/", 1),
("litebox_shim_optee/", 4),
("litebox_shim_optee/", 5),
],
|file| {
Ok(file
Expand Down
55 changes: 52 additions & 3 deletions litebox_common_optee/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -624,6 +624,17 @@ pub struct TeeUuid {
}

impl TeeUuid {
/// The nil UUID (all zeros, RFC 4122 S4.1.7).
///
/// Used for anonymous clients (e.g., `TeeLogin::Public`) that carry no
/// REE-derived identity.
pub const NIL: Self = Self {
time_low: 0,
time_mid: 0,
time_hi_and_version: 0,
clock_seq_and_node: [0; 8],
};

/// Converts a UUID from a 16-byte array in RFC 4122 format (big-endian for numeric fields).
///
/// The byte layout is:
Expand DownExpand Up@@ -750,7 +761,7 @@ pub struct TaHead {
pub const TA_HEAD_SECTION_NAME: &str = ".ta_head";

/// `TEE_Identity` from `optee_os/lib/libutee/include/tee_api_types.h`.
#[derive(Clone, Copy, PartialEq, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, Immutable, IntoBytes)]
#[repr(C)]
pub struct TeeIdentity {
pub login: TeeLogin,
Expand DownExpand Up@@ -832,9 +843,11 @@ const TEE_LOGIN_APPLICATION: u32 = 0x4;
const TEE_LOGIN_APPLICATION_USER: u32 = 0x5;
const TEE_LOGIN_APPLICATION_GROUP: u32 = 0x6;
const TEE_LOGIN_TRUSTED_APP: u32 = 0xf000_0000;
// Private OP-TEE login for in-kernel REE clients (`tee_api_defines_extensions.h`).
const TEE_LOGIN_REE_KERNEL: u32 = 0x8000_0000;

/// `TEE Login type` from `optee_os/lib/libutee/include/tee_api_defines.h`
#[derive(Clone, Copy, PartialEq, TryFromPrimitive, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, TryFromPrimitive, Immutable, IntoBytes)]
#[repr(u32)]
pub enum TeeLogin {
Public = TEE_LOGIN_PUBLIC,
Expand All@@ -843,6 +856,7 @@ pub enum TeeLogin {
Application = TEE_LOGIN_APPLICATION,
ApplicationUser = TEE_LOGIN_APPLICATION_USER,
ApplicationGroup = TEE_LOGIN_APPLICATION_GROUP,
ReeKernel = TEE_LOGIN_REE_KERNEL,
TrustedApp = TEE_LOGIN_TRUSTED_APP,
}

Expand DownExpand Up@@ -1469,6 +1483,10 @@ const OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: u8 = 0xb;
// Note: `OPTEE_MSG_ATTR_TYPE_FMEM_*` are aliases of `OPTEE_MSG_ATTR_TYPE_RMEM_*`.
// Whether it is RMEM of FMEM depends on the conduit.

/// Meta-parameter marker of the attribute word. Set on the `OpenSession`
/// TA-UUID and client-identity params.
const OPTEE_MSG_ATTR_META: u64 = 1 << 8;

#[non_exhaustive]
#[derive(Debug, PartialEq, TryFromPrimitive)]
#[repr(u8)]
Expand All@@ -1492,11 +1510,17 @@ pub enum OpteeMsgAttrType {
/// - bit 8 – meta
/// - bit 9 – noncontig
/// - bits \[63:10\] – reserved (zero)
#[derive(Clone, Copy, Default, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[derive(Clone, Copy, Default, PartialEq, Eq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(transparent)]
pub struct OpteeMsgAttr(u64);

impl OpteeMsgAttr {
/// The exact attribute word an `OpenSession` meta value parameter must carry
/// (`OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT`, all other bits
/// zero). See [`OpteeMsgArgs::get_meta_param_value`].
pub const META_VALUE_INPUT: Self =
Self(OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT as u64);

/// Returns the attribute type (bits 0–7).
#[allow(clippy::cast_possible_truncation)]
pub fn attr_type(&self) -> u8 {
Expand DownExpand Up@@ -1525,6 +1549,10 @@ impl OpteeMsgParam {
pub fn attr_type(&self) -> OpteeMsgAttrType {
OpteeMsgAttrType::try_from(self.attr.attr_type()).unwrap_or(OpteeMsgAttrType::None)
}
/// Returns `true` when the meta bit (bit 8) is set.
pub fn is_meta(&self) -> bool {
self.attr.meta()
}
pub fn get_param_tmem(&self) -> Option<OpteeMsgParamTmem> {
if matches!(
self.attr.attr_type(),
Expand DownExpand Up@@ -1757,6 +1785,27 @@ impl OpteeMsgArgs {
.ok_or(OpteeSmcReturnCode::EBadCmd)?)
}
}

/// Read a value parameter that must be tagged as an `OpenSession` meta parameter.
///
/// `OpenSession` conveys the TA UUID and client identity in the first two
/// params, each marked exactly [`OpteeMsgAttr::META_VALUE_INPUT`], mirroring
/// OP-TEE OS `get_open_session_meta()`. Plain `get_param_value` ignores
/// these bits, so it must not be used for this.
pub fn get_meta_param_value(
&self,
index: usize,
) -> Result<OpteeMsgParamValue, OpteeSmcReturnCode> {
if index >= self.num_params as usize {
return Err(OpteeSmcReturnCode::ENotAvail);
}
let param = &self.params[index];
if param.attr != OpteeMsgAttr::META_VALUE_INPUT {
return Err(OpteeSmcReturnCode::EBadCmd);
}
param.get_param_value().ok_or(OpteeSmcReturnCode::EBadCmd)
}

pub fn set_param_value(
&mut self,
index: usize,
Expand Down
1 change: 0 additions & 1 deletion litebox_runner_lvbs/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,6 @@ litebox_shim_optee = { path = "../litebox_shim_optee/", version = "0.1.0" }
litebox_util_log = { version = "0.1.0", path = "../litebox_util_log" }
log = { version = "0.4", default-features = false }
spin = { version = "0.10.0", default-features = false, features = ["spin_mutex"] }
once_cell = { version = "1.21.3", default-features = false, features = ["race", "alloc"] }

[target.'cfg(target_arch = "x86_64")'.dependencies]
x86_64 = { version = "0.15.2", default-features = false, features = ["instructions"] }
Expand Down
50 changes: 24 additions & 26 deletions litebox_runner_lvbs/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,9 +42,8 @@ use litebox_shim_optee::msg_handler::{
decode_ta_request, handle_optee_msg_args, handle_optee_smc_args, packed_msg_args_lock,
update_optee_msg_args,
};
use litebox_shim_optee::session::{OpenSessionTarget, SessionManager, TaInstance};
use litebox_shim_optee::session::{OpenSessionTarget, TaInstance, session_manager};
use litebox_shim_optee::{NormalWorldConstPtr, NormalWorldMutPtr, UserConstPtr};
use once_cell::race::OnceBox;

/// Seed the initial heap regions so the global allocator has enough memory
/// for slab-backed allocations (the slab needs >= 2 MB backing pages).
Expand DownExpand Up@@ -288,12 +287,6 @@ fn optee_smc_handler_entry_inner(
Ok(0)
}

/// Get the global session manager.
fn session_manager() -> &'static SessionManager {
static SESSION_MANAGER: OnceBox<SessionManager> = OnceBox::new();
SESSION_MANAGER.get_or_init(|| Box::new(SessionManager::new()))
}

/// Switch to the base page table.
///
/// This must be called before returning to VTL0 to ensure VTL1 reentry is
Expand DownExpand Up@@ -527,6 +520,7 @@ fn handle_open_session(
msg_args_phys_addr,
instance,
params,
client_identity,
&ta_req_info,
),
OpenSessionTarget::NewInstance => open_session_new_instance(
Expand DownExpand Up@@ -560,6 +554,7 @@ fn open_session_single_instance(
msg_args_phys_addr: u64,
instance: &TaInstance,
params: &[litebox_common_optee::UteeParamOwned],
client_identity: Option<litebox_common_optee::TeeIdentity>,
ta_req_info: &litebox_shim_optee::msg_handler::TaRequestInfo<PAGE_SIZE>,
) -> Result<(), OpteeSmcReturnCode> {
let task_pt_id = instance.task_page_table_id();
Expand All@@ -570,6 +565,9 @@ fn open_session_single_instance(
// Safe to unwrap: session ID has been just created.
let runner_session_id = session_token.session_id().unwrap();

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

debug_serial_println!(
"Reusing single-instance TA: uuid={:?}, task_pt_id={}, session_id={}",
ta_uuid,
Expand All@@ -588,7 +586,7 @@ fn open_session_single_instance(
.ok_or(OpteeSmcReturnCode::EBadCmd)?
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -686,6 +684,9 @@ fn open_session_single_instance(
teardown_ta_page_table(instance.shim(), task_pt_id);
};
} else {
// The session id is forgotten (never recycled), so the token's drop
// won't clear the recorded identity. Remove the client identity here.
session_manager().clear_session_client_identity(runner_session_id);
Comment thread
sangho2 marked this conversation as resolved.
session_token.disarm();
}
return Err(e);
Expand All@@ -704,7 +705,7 @@ fn open_session_single_instance(
}

/// Create a new TA instance for a session. Must be called from within a
/// [`SessionManager::with_ta`] closure.
/// [`litebox_shim_optee::session::SessionManager::with_ta`] closure.
///
/// If ldelf loading or OpenSession entry point fails, the page table is torn down.
/// Per OP-TEE OS semantics: if OpenSession returns non-success, cleanup happens.
Expand DownExpand Up@@ -741,19 +742,13 @@ fn open_session_new_instance(
// Load ldelf and TA - Box immediately to keep at fixed heap address
let shim = litebox_shim_optee::OpteeShimBuilder::new().build();
let loaded_program = Box::new(
shim.load_ldelf(
LDELF_BINARY,
ta_uuid,
Some(ta_bin),
client_identity,
runner_session_id,
)
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
shim.load_ldelf(LDELF_BINARY, ta_uuid, Some(ta_bin))
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
);

let ta_flags = loaded_program.ta_flags;
Expand DownExpand Up@@ -801,6 +796,9 @@ fn open_session_new_instance(
return Ok(());
}

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

// Load TA context with parameters for OpenSession - pass actual session_id
loaded_program.entrypoints.as_ref().ok_or_else(|| {
// Safety: We are about to tear down this TA instance;
Expand All@@ -814,7 +812,7 @@ fn open_session_new_instance(
.unwrap()
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -983,7 +981,7 @@ fn handle_invoke_command(
entrypoints_ref
.load_ta_context(
params.as_slice(),
Some(session_id),
session_id,
UteeEntryFunc::InvokeCommand as u32,
Some(cmd_id),
)
Expand DownExpand Up@@ -1095,7 +1093,7 @@ fn handle_close_session(
.unwrap()
.load_ta_context(
&[],
Some(session_id),
session_id,
UteeEntryFunc::CloseSession as u32,
None,
)
Expand Down
15 changes: 4 additions & 11 deletions litebox_runner_optee_on_linux_userland/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ use anyhow::{Context as _, Result};
use clap::Parser;
use litebox_common_optee::{TeeUuid, UteeEntryFunc, UteeParamOwned};
use litebox_platform_multiplex::Platform;
use litebox_shim_optee::session::SessionManager;
use litebox_shim_optee::session::session_manager;
use std::path::PathBuf;

mod tests;
Expand DownExpand Up@@ -109,21 +109,14 @@ fn run_ta_with_default_commands(
ldelf_bin: &[u8],
ta_bin: &[u8],
) {
let session_manager = SessionManager::new();
for func_id in [UteeEntryFunc::OpenSession, UteeEntryFunc::CloseSession] {
let params = [const { UteeParamOwned::None }; UteeParamOwned::TEE_NUM_PARAMS];

if func_id == UteeEntryFunc::OpenSession {
let session_token = session_manager.try_acquire_open_session_token().unwrap();
let session_token = session_manager().try_acquire_open_session_token().unwrap();
let session_id = session_token.session_id().unwrap();
let loaded_program = shim
.load_ldelf(
ldelf_bin,
TeeUuid::default(),
Some(ta_bin),
None,
session_id,
)
.load_ldelf(ldelf_bin, TeeUuid::default(), Some(ta_bin))
.map_err(|_| {
panic!("Failed to load ldelf");
})
Expand All@@ -140,7 +133,7 @@ fn run_ta_with_default_commands(
// loaded binary and heap. In that sense, we can create (and destroy) a stack
// for each command freely.
let _ = entrypoints
.load_ta_context(params.as_slice(), None, func_id as u32, None)
.load_ta_context(params.as_slice(), session_id, func_id as u32, None)
.map_err(|_| {
panic!("Failed to load TA context");
});
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Add per-session OP-TEE client identity handling by sangho2 · Pull Request #885 · microsoft/litebox · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dev_tests/src/ratchet.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -40,10 +40,10 @@ fn ratchet_globals() -> Result<()> {
("litebox_platform_lvbs/", 24),
("litebox_platform_multiplex/", 1),
("litebox_platform_windows_userland/", 8),
("litebox_runner_lvbs/", 6),
("litebox_runner_lvbs/", 5),
("litebox_runner_snp/", 2),
("litebox_shim_linux/", 1),
("litebox_shim_optee/", 4),
("litebox_shim_optee/", 5),
],
|file| {
Ok(file
Expand Down
55 changes: 52 additions & 3 deletions litebox_common_optee/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -624,6 +624,17 @@ pub struct TeeUuid {
}

impl TeeUuid {
/// The nil UUID (all zeros, RFC 4122 S4.1.7).
///
/// Used for anonymous clients (e.g., `TeeLogin::Public`) that carry no
/// REE-derived identity.
pub const NIL: Self = Self {
time_low: 0,
time_mid: 0,
time_hi_and_version: 0,
clock_seq_and_node: [0; 8],
};

/// Converts a UUID from a 16-byte array in RFC 4122 format (big-endian for numeric fields).
///
/// The byte layout is:
Expand DownExpand Up@@ -750,7 +761,7 @@ pub struct TaHead {
pub const TA_HEAD_SECTION_NAME: &str = ".ta_head";

/// `TEE_Identity` from `optee_os/lib/libutee/include/tee_api_types.h`.
#[derive(Clone, Copy, PartialEq, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, Immutable, IntoBytes)]
#[repr(C)]
pub struct TeeIdentity {
pub login: TeeLogin,
Expand DownExpand Up@@ -832,9 +843,11 @@ const TEE_LOGIN_APPLICATION: u32 = 0x4;
const TEE_LOGIN_APPLICATION_USER: u32 = 0x5;
const TEE_LOGIN_APPLICATION_GROUP: u32 = 0x6;
const TEE_LOGIN_TRUSTED_APP: u32 = 0xf000_0000;
// Private OP-TEE login for in-kernel REE clients (`tee_api_defines_extensions.h`).
const TEE_LOGIN_REE_KERNEL: u32 = 0x8000_0000;

/// `TEE Login type` from `optee_os/lib/libutee/include/tee_api_defines.h`
#[derive(Clone, Copy, PartialEq, TryFromPrimitive, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, TryFromPrimitive, Immutable, IntoBytes)]
#[repr(u32)]
pub enum TeeLogin {
Public = TEE_LOGIN_PUBLIC,
Expand All@@ -843,6 +856,7 @@ pub enum TeeLogin {
Application = TEE_LOGIN_APPLICATION,
ApplicationUser = TEE_LOGIN_APPLICATION_USER,
ApplicationGroup = TEE_LOGIN_APPLICATION_GROUP,
ReeKernel = TEE_LOGIN_REE_KERNEL,
TrustedApp = TEE_LOGIN_TRUSTED_APP,
}

Expand DownExpand Up@@ -1469,6 +1483,10 @@ const OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: u8 = 0xb;
// Note: `OPTEE_MSG_ATTR_TYPE_FMEM_*` are aliases of `OPTEE_MSG_ATTR_TYPE_RMEM_*`.
// Whether it is RMEM of FMEM depends on the conduit.

/// Meta-parameter marker of the attribute word. Set on the `OpenSession`
/// TA-UUID and client-identity params.
const OPTEE_MSG_ATTR_META: u64 = 1 << 8;

#[non_exhaustive]
#[derive(Debug, PartialEq, TryFromPrimitive)]
#[repr(u8)]
Expand All@@ -1492,11 +1510,17 @@ pub enum OpteeMsgAttrType {
/// - bit 8 – meta
/// - bit 9 – noncontig
/// - bits \[63:10\] – reserved (zero)
#[derive(Clone, Copy, Default, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[derive(Clone, Copy, Default, PartialEq, Eq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(transparent)]
pub struct OpteeMsgAttr(u64);

impl OpteeMsgAttr {
/// The exact attribute word an `OpenSession` meta value parameter must carry
/// (`OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT`, all other bits
/// zero). See [`OpteeMsgArgs::get_meta_param_value`].
pub const META_VALUE_INPUT: Self =
Self(OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT as u64);

/// Returns the attribute type (bits 0–7).
#[allow(clippy::cast_possible_truncation)]
pub fn attr_type(&self) -> u8 {
Expand DownExpand Up@@ -1525,6 +1549,10 @@ impl OpteeMsgParam {
pub fn attr_type(&self) -> OpteeMsgAttrType {
OpteeMsgAttrType::try_from(self.attr.attr_type()).unwrap_or(OpteeMsgAttrType::None)
}
/// Returns `true` when the meta bit (bit 8) is set.
pub fn is_meta(&self) -> bool {
self.attr.meta()
}
pub fn get_param_tmem(&self) -> Option<OpteeMsgParamTmem> {
if matches!(
self.attr.attr_type(),
Expand DownExpand Up@@ -1757,6 +1785,27 @@ impl OpteeMsgArgs {
.ok_or(OpteeSmcReturnCode::EBadCmd)?)
}
}

/// Read a value parameter that must be tagged as an `OpenSession` meta parameter.
///
/// `OpenSession` conveys the TA UUID and client identity in the first two
/// params, each marked exactly [`OpteeMsgAttr::META_VALUE_INPUT`], mirroring
/// OP-TEE OS `get_open_session_meta()`. Plain `get_param_value` ignores
/// these bits, so it must not be used for this.
pub fn get_meta_param_value(
&self,
index: usize,
) -> Result<OpteeMsgParamValue, OpteeSmcReturnCode> {
if index >= self.num_params as usize {
return Err(OpteeSmcReturnCode::ENotAvail);
}
let param = &self.params[index];
if param.attr != OpteeMsgAttr::META_VALUE_INPUT {
return Err(OpteeSmcReturnCode::EBadCmd);
}
param.get_param_value().ok_or(OpteeSmcReturnCode::EBadCmd)
}

pub fn set_param_value(
&mut self,
index: usize,
Expand Down
1 change: 0 additions & 1 deletion litebox_runner_lvbs/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,6 @@ litebox_shim_optee = { path = "../litebox_shim_optee/", version = "0.1.0" }
litebox_util_log = { version = "0.1.0", path = "../litebox_util_log" }
log = { version = "0.4", default-features = false }
spin = { version = "0.10.0", default-features = false, features = ["spin_mutex"] }
once_cell = { version = "1.21.3", default-features = false, features = ["race", "alloc"] }

[target.'cfg(target_arch = "x86_64")'.dependencies]
x86_64 = { version = "0.15.2", default-features = false, features = ["instructions"] }
Expand Down
50 changes: 24 additions & 26 deletions litebox_runner_lvbs/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,9 +42,8 @@ use litebox_shim_optee::msg_handler::{
decode_ta_request, handle_optee_msg_args, handle_optee_smc_args, packed_msg_args_lock,
update_optee_msg_args,
};
use litebox_shim_optee::session::{OpenSessionTarget, SessionManager, TaInstance};
use litebox_shim_optee::session::{OpenSessionTarget, TaInstance, session_manager};
use litebox_shim_optee::{NormalWorldConstPtr, NormalWorldMutPtr, UserConstPtr};
use once_cell::race::OnceBox;

/// Seed the initial heap regions so the global allocator has enough memory
/// for slab-backed allocations (the slab needs >= 2 MB backing pages).
Expand DownExpand Up@@ -288,12 +287,6 @@ fn optee_smc_handler_entry_inner(
Ok(0)
}

/// Get the global session manager.
fn session_manager() -> &'static SessionManager {
static SESSION_MANAGER: OnceBox<SessionManager> = OnceBox::new();
SESSION_MANAGER.get_or_init(|| Box::new(SessionManager::new()))
}

/// Switch to the base page table.
///
/// This must be called before returning to VTL0 to ensure VTL1 reentry is
Expand DownExpand Up@@ -527,6 +520,7 @@ fn handle_open_session(
msg_args_phys_addr,
instance,
params,
client_identity,
&ta_req_info,
),
OpenSessionTarget::NewInstance => open_session_new_instance(
Expand DownExpand Up@@ -560,6 +554,7 @@ fn open_session_single_instance(
msg_args_phys_addr: u64,
instance: &TaInstance,
params: &[litebox_common_optee::UteeParamOwned],
client_identity: Option<litebox_common_optee::TeeIdentity>,
ta_req_info: &litebox_shim_optee::msg_handler::TaRequestInfo<PAGE_SIZE>,
) -> Result<(), OpteeSmcReturnCode> {
let task_pt_id = instance.task_page_table_id();
Expand All@@ -570,6 +565,9 @@ fn open_session_single_instance(
// Safe to unwrap: session ID has been just created.
let runner_session_id = session_token.session_id().unwrap();

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

debug_serial_println!(
"Reusing single-instance TA: uuid={:?}, task_pt_id={}, session_id={}",
ta_uuid,
Expand All@@ -588,7 +586,7 @@ fn open_session_single_instance(
.ok_or(OpteeSmcReturnCode::EBadCmd)?
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -686,6 +684,9 @@ fn open_session_single_instance(
teardown_ta_page_table(instance.shim(), task_pt_id);
};
} else {
// The session id is forgotten (never recycled), so the token's drop
// won't clear the recorded identity. Remove the client identity here.
session_manager().clear_session_client_identity(runner_session_id);
Comment thread
sangho2 marked this conversation as resolved.
session_token.disarm();
}
return Err(e);
Expand All@@ -704,7 +705,7 @@ fn open_session_single_instance(
}

/// Create a new TA instance for a session. Must be called from within a
/// [`SessionManager::with_ta`] closure.
/// [`litebox_shim_optee::session::SessionManager::with_ta`] closure.
///
/// If ldelf loading or OpenSession entry point fails, the page table is torn down.
/// Per OP-TEE OS semantics: if OpenSession returns non-success, cleanup happens.
Expand DownExpand Up@@ -741,19 +742,13 @@ fn open_session_new_instance(
// Load ldelf and TA - Box immediately to keep at fixed heap address
let shim = litebox_shim_optee::OpteeShimBuilder::new().build();
let loaded_program = Box::new(
shim.load_ldelf(
LDELF_BINARY,
ta_uuid,
Some(ta_bin),
client_identity,
runner_session_id,
)
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
shim.load_ldelf(LDELF_BINARY, ta_uuid, Some(ta_bin))
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
);

let ta_flags = loaded_program.ta_flags;
Expand DownExpand Up@@ -801,6 +796,9 @@ fn open_session_new_instance(
return Ok(());
}

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

// Load TA context with parameters for OpenSession - pass actual session_id
loaded_program.entrypoints.as_ref().ok_or_else(|| {
// Safety: We are about to tear down this TA instance;
Expand All@@ -814,7 +812,7 @@ fn open_session_new_instance(
.unwrap()
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -983,7 +981,7 @@ fn handle_invoke_command(
entrypoints_ref
.load_ta_context(
params.as_slice(),
Some(session_id),
session_id,
UteeEntryFunc::InvokeCommand as u32,
Some(cmd_id),
)
Expand DownExpand Up@@ -1095,7 +1093,7 @@ fn handle_close_session(
.unwrap()
.load_ta_context(
&[],
Some(session_id),
session_id,
UteeEntryFunc::CloseSession as u32,
None,
)
Expand Down
15 changes: 4 additions & 11 deletions litebox_runner_optee_on_linux_userland/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ use anyhow::{Context as _, Result};
use clap::Parser;
use litebox_common_optee::{TeeUuid, UteeEntryFunc, UteeParamOwned};
use litebox_platform_multiplex::Platform;
use litebox_shim_optee::session::SessionManager;
use litebox_shim_optee::session::session_manager;
use std::path::PathBuf;

mod tests;
Expand DownExpand Up@@ -109,21 +109,14 @@ fn run_ta_with_default_commands(
ldelf_bin: &[u8],
ta_bin: &[u8],
) {
let session_manager = SessionManager::new();
for func_id in [UteeEntryFunc::OpenSession, UteeEntryFunc::CloseSession] {
let params = [const { UteeParamOwned::None }; UteeParamOwned::TEE_NUM_PARAMS];

if func_id == UteeEntryFunc::OpenSession {
let session_token = session_manager.try_acquire_open_session_token().unwrap();
let session_token = session_manager().try_acquire_open_session_token().unwrap();
let session_id = session_token.session_id().unwrap();
let loaded_program = shim
.load_ldelf(
ldelf_bin,
TeeUuid::default(),
Some(ta_bin),
None,
session_id,
)
.load_ldelf(ldelf_bin, TeeUuid::default(), Some(ta_bin))
.map_err(|_| {
panic!("Failed to load ldelf");
})
Expand All@@ -140,7 +133,7 @@ fn run_ta_with_default_commands(
// loaded binary and heap. In that sense, we can create (and destroy) a stack
// for each command freely.
let _ = entrypoints
.load_ta_context(params.as_slice(), None, func_id as u32, None)
.load_ta_context(params.as_slice(), session_id, func_id as u32, None)
.map_err(|_| {
panic!("Failed to load TA context");
});
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add per-session OP-TEE client identity handling by sangho2 · Pull Request #885 · microsoft/litebox · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dev_tests/src/ratchet.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -40,10 +40,10 @@ fn ratchet_globals() -> Result<()> {
("litebox_platform_lvbs/", 24),
("litebox_platform_multiplex/", 1),
("litebox_platform_windows_userland/", 8),
("litebox_runner_lvbs/", 6),
("litebox_runner_lvbs/", 5),
("litebox_runner_snp/", 2),
("litebox_shim_linux/", 1),
("litebox_shim_optee/", 4),
("litebox_shim_optee/", 5),
],
|file| {
Ok(file
Expand Down
55 changes: 52 additions & 3 deletions litebox_common_optee/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -624,6 +624,17 @@ pub struct TeeUuid {
}

impl TeeUuid {
/// The nil UUID (all zeros, RFC 4122 S4.1.7).
///
/// Used for anonymous clients (e.g., `TeeLogin::Public`) that carry no
/// REE-derived identity.
pub const NIL: Self = Self {
time_low: 0,
time_mid: 0,
time_hi_and_version: 0,
clock_seq_and_node: [0; 8],
};

/// Converts a UUID from a 16-byte array in RFC 4122 format (big-endian for numeric fields).
///
/// The byte layout is:
Expand DownExpand Up@@ -750,7 +761,7 @@ pub struct TaHead {
pub const TA_HEAD_SECTION_NAME: &str = ".ta_head";

/// `TEE_Identity` from `optee_os/lib/libutee/include/tee_api_types.h`.
#[derive(Clone, Copy, PartialEq, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, Immutable, IntoBytes)]
#[repr(C)]
pub struct TeeIdentity {
pub login: TeeLogin,
Expand DownExpand Up@@ -832,9 +843,11 @@ const TEE_LOGIN_APPLICATION: u32 = 0x4;
const TEE_LOGIN_APPLICATION_USER: u32 = 0x5;
const TEE_LOGIN_APPLICATION_GROUP: u32 = 0x6;
const TEE_LOGIN_TRUSTED_APP: u32 = 0xf000_0000;
// Private OP-TEE login for in-kernel REE clients (`tee_api_defines_extensions.h`).
const TEE_LOGIN_REE_KERNEL: u32 = 0x8000_0000;

/// `TEE Login type` from `optee_os/lib/libutee/include/tee_api_defines.h`
#[derive(Clone, Copy, PartialEq, TryFromPrimitive, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, TryFromPrimitive, Immutable, IntoBytes)]
#[repr(u32)]
pub enum TeeLogin {
Public = TEE_LOGIN_PUBLIC,
Expand All@@ -843,6 +856,7 @@ pub enum TeeLogin {
Application = TEE_LOGIN_APPLICATION,
ApplicationUser = TEE_LOGIN_APPLICATION_USER,
ApplicationGroup = TEE_LOGIN_APPLICATION_GROUP,
ReeKernel = TEE_LOGIN_REE_KERNEL,
TrustedApp = TEE_LOGIN_TRUSTED_APP,
}

Expand DownExpand Up@@ -1469,6 +1483,10 @@ const OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: u8 = 0xb;
// Note: `OPTEE_MSG_ATTR_TYPE_FMEM_*` are aliases of `OPTEE_MSG_ATTR_TYPE_RMEM_*`.
// Whether it is RMEM of FMEM depends on the conduit.

/// Meta-parameter marker of the attribute word. Set on the `OpenSession`
/// TA-UUID and client-identity params.
const OPTEE_MSG_ATTR_META: u64 = 1 << 8;

#[non_exhaustive]
#[derive(Debug, PartialEq, TryFromPrimitive)]
#[repr(u8)]
Expand All@@ -1492,11 +1510,17 @@ pub enum OpteeMsgAttrType {
/// - bit 8 – meta
/// - bit 9 – noncontig
/// - bits \[63:10\] – reserved (zero)
#[derive(Clone, Copy, Default, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[derive(Clone, Copy, Default, PartialEq, Eq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(transparent)]
pub struct OpteeMsgAttr(u64);

impl OpteeMsgAttr {
/// The exact attribute word an `OpenSession` meta value parameter must carry
/// (`OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT`, all other bits
/// zero). See [`OpteeMsgArgs::get_meta_param_value`].
pub const META_VALUE_INPUT: Self =
Self(OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT as u64);

/// Returns the attribute type (bits 0–7).
#[allow(clippy::cast_possible_truncation)]
pub fn attr_type(&self) -> u8 {
Expand DownExpand Up@@ -1525,6 +1549,10 @@ impl OpteeMsgParam {
pub fn attr_type(&self) -> OpteeMsgAttrType {
OpteeMsgAttrType::try_from(self.attr.attr_type()).unwrap_or(OpteeMsgAttrType::None)
}
/// Returns `true` when the meta bit (bit 8) is set.
pub fn is_meta(&self) -> bool {
self.attr.meta()
}
pub fn get_param_tmem(&self) -> Option<OpteeMsgParamTmem> {
if matches!(
self.attr.attr_type(),
Expand DownExpand Up@@ -1757,6 +1785,27 @@ impl OpteeMsgArgs {
.ok_or(OpteeSmcReturnCode::EBadCmd)?)
}
}

/// Read a value parameter that must be tagged as an `OpenSession` meta parameter.
///
/// `OpenSession` conveys the TA UUID and client identity in the first two
/// params, each marked exactly [`OpteeMsgAttr::META_VALUE_INPUT`], mirroring
/// OP-TEE OS `get_open_session_meta()`. Plain `get_param_value` ignores
/// these bits, so it must not be used for this.
pub fn get_meta_param_value(
&self,
index: usize,
) -> Result<OpteeMsgParamValue, OpteeSmcReturnCode> {
if index >= self.num_params as usize {
return Err(OpteeSmcReturnCode::ENotAvail);
}
let param = &self.params[index];
if param.attr != OpteeMsgAttr::META_VALUE_INPUT {
return Err(OpteeSmcReturnCode::EBadCmd);
}
param.get_param_value().ok_or(OpteeSmcReturnCode::EBadCmd)
}

pub fn set_param_value(
&mut self,
index: usize,
Expand Down
1 change: 0 additions & 1 deletion litebox_runner_lvbs/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,6 @@ litebox_shim_optee = { path = "../litebox_shim_optee/", version = "0.1.0" }
litebox_util_log = { version = "0.1.0", path = "../litebox_util_log" }
log = { version = "0.4", default-features = false }
spin = { version = "0.10.0", default-features = false, features = ["spin_mutex"] }
once_cell = { version = "1.21.3", default-features = false, features = ["race", "alloc"] }

[target.'cfg(target_arch = "x86_64")'.dependencies]
x86_64 = { version = "0.15.2", default-features = false, features = ["instructions"] }
Expand Down
50 changes: 24 additions & 26 deletions litebox_runner_lvbs/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,9 +42,8 @@ use litebox_shim_optee::msg_handler::{
decode_ta_request, handle_optee_msg_args, handle_optee_smc_args, packed_msg_args_lock,
update_optee_msg_args,
};
use litebox_shim_optee::session::{OpenSessionTarget, SessionManager, TaInstance};
use litebox_shim_optee::session::{OpenSessionTarget, TaInstance, session_manager};
use litebox_shim_optee::{NormalWorldConstPtr, NormalWorldMutPtr, UserConstPtr};
use once_cell::race::OnceBox;

/// Seed the initial heap regions so the global allocator has enough memory
/// for slab-backed allocations (the slab needs >= 2 MB backing pages).
Expand DownExpand Up@@ -288,12 +287,6 @@ fn optee_smc_handler_entry_inner(
Ok(0)
}

/// Get the global session manager.
fn session_manager() -> &'static SessionManager {
static SESSION_MANAGER: OnceBox<SessionManager> = OnceBox::new();
SESSION_MANAGER.get_or_init(|| Box::new(SessionManager::new()))
}

/// Switch to the base page table.
///
/// This must be called before returning to VTL0 to ensure VTL1 reentry is
Expand DownExpand Up@@ -527,6 +520,7 @@ fn handle_open_session(
msg_args_phys_addr,
instance,
params,
client_identity,
&ta_req_info,
),
OpenSessionTarget::NewInstance => open_session_new_instance(
Expand DownExpand Up@@ -560,6 +554,7 @@ fn open_session_single_instance(
msg_args_phys_addr: u64,
instance: &TaInstance,
params: &[litebox_common_optee::UteeParamOwned],
client_identity: Option<litebox_common_optee::TeeIdentity>,
ta_req_info: &litebox_shim_optee::msg_handler::TaRequestInfo<PAGE_SIZE>,
) -> Result<(), OpteeSmcReturnCode> {
let task_pt_id = instance.task_page_table_id();
Expand All@@ -570,6 +565,9 @@ fn open_session_single_instance(
// Safe to unwrap: session ID has been just created.
let runner_session_id = session_token.session_id().unwrap();

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

debug_serial_println!(
"Reusing single-instance TA: uuid={:?}, task_pt_id={}, session_id={}",
ta_uuid,
Expand All@@ -588,7 +586,7 @@ fn open_session_single_instance(
.ok_or(OpteeSmcReturnCode::EBadCmd)?
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -686,6 +684,9 @@ fn open_session_single_instance(
teardown_ta_page_table(instance.shim(), task_pt_id);
};
} else {
// The session id is forgotten (never recycled), so the token's drop
// won't clear the recorded identity. Remove the client identity here.
session_manager().clear_session_client_identity(runner_session_id);
Comment thread
sangho2 marked this conversation as resolved.
session_token.disarm();
}
return Err(e);
Expand All@@ -704,7 +705,7 @@ fn open_session_single_instance(
}

/// Create a new TA instance for a session. Must be called from within a
/// [`SessionManager::with_ta`] closure.
/// [`litebox_shim_optee::session::SessionManager::with_ta`] closure.
///
/// If ldelf loading or OpenSession entry point fails, the page table is torn down.
/// Per OP-TEE OS semantics: if OpenSession returns non-success, cleanup happens.
Expand DownExpand Up@@ -741,19 +742,13 @@ fn open_session_new_instance(
// Load ldelf and TA - Box immediately to keep at fixed heap address
let shim = litebox_shim_optee::OpteeShimBuilder::new().build();
let loaded_program = Box::new(
shim.load_ldelf(
LDELF_BINARY,
ta_uuid,
Some(ta_bin),
client_identity,
runner_session_id,
)
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
shim.load_ldelf(LDELF_BINARY, ta_uuid, Some(ta_bin))
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
);

let ta_flags = loaded_program.ta_flags;
Expand DownExpand Up@@ -801,6 +796,9 @@ fn open_session_new_instance(
return Ok(());
}

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

// Load TA context with parameters for OpenSession - pass actual session_id
loaded_program.entrypoints.as_ref().ok_or_else(|| {
// Safety: We are about to tear down this TA instance;
Expand All@@ -814,7 +812,7 @@ fn open_session_new_instance(
.unwrap()
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -983,7 +981,7 @@ fn handle_invoke_command(
entrypoints_ref
.load_ta_context(
params.as_slice(),
Some(session_id),
session_id,
UteeEntryFunc::InvokeCommand as u32,
Some(cmd_id),
)
Expand DownExpand Up@@ -1095,7 +1093,7 @@ fn handle_close_session(
.unwrap()
.load_ta_context(
&[],
Some(session_id),
session_id,
UteeEntryFunc::CloseSession as u32,
None,
)
Expand Down
15 changes: 4 additions & 11 deletions litebox_runner_optee_on_linux_userland/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ use anyhow::{Context as _, Result};
use clap::Parser;
use litebox_common_optee::{TeeUuid, UteeEntryFunc, UteeParamOwned};
use litebox_platform_multiplex::Platform;
use litebox_shim_optee::session::SessionManager;
use litebox_shim_optee::session::session_manager;
use std::path::PathBuf;

mod tests;
Expand DownExpand Up@@ -109,21 +109,14 @@ fn run_ta_with_default_commands(
ldelf_bin: &[u8],
ta_bin: &[u8],
) {
let session_manager = SessionManager::new();
for func_id in [UteeEntryFunc::OpenSession, UteeEntryFunc::CloseSession] {
let params = [const { UteeParamOwned::None }; UteeParamOwned::TEE_NUM_PARAMS];

if func_id == UteeEntryFunc::OpenSession {
let session_token = session_manager.try_acquire_open_session_token().unwrap();
let session_token = session_manager().try_acquire_open_session_token().unwrap();
let session_id = session_token.session_id().unwrap();
let loaded_program = shim
.load_ldelf(
ldelf_bin,
TeeUuid::default(),
Some(ta_bin),
None,
session_id,
)
.load_ldelf(ldelf_bin, TeeUuid::default(), Some(ta_bin))
.map_err(|_| {
panic!("Failed to load ldelf");
})
Expand All@@ -140,7 +133,7 @@ fn run_ta_with_default_commands(
// loaded binary and heap. In that sense, we can create (and destroy) a stack
// for each command freely.
let _ = entrypoints
.load_ta_context(params.as_slice(), None, func_id as u32, None)
.load_ta_context(params.as_slice(), session_id, func_id as u32, None)
.map_err(|_| {
panic!("Failed to load TA context");
});
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add per-session OP-TEE client identity handling by sangho2 · Pull Request #885 · microsoft/litebox · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dev_tests/src/ratchet.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -40,10 +40,10 @@ fn ratchet_globals() -> Result<()> {
("litebox_platform_lvbs/", 24),
("litebox_platform_multiplex/", 1),
("litebox_platform_windows_userland/", 8),
("litebox_runner_lvbs/", 6),
("litebox_runner_lvbs/", 5),
("litebox_runner_snp/", 2),
("litebox_shim_linux/", 1),
("litebox_shim_optee/", 4),
("litebox_shim_optee/", 5),
],
|file| {
Ok(file
Expand Down
55 changes: 52 additions & 3 deletions litebox_common_optee/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -624,6 +624,17 @@ pub struct TeeUuid {
}

impl TeeUuid {
/// The nil UUID (all zeros, RFC 4122 S4.1.7).
///
/// Used for anonymous clients (e.g., `TeeLogin::Public`) that carry no
/// REE-derived identity.
pub const NIL: Self = Self {
time_low: 0,
time_mid: 0,
time_hi_and_version: 0,
clock_seq_and_node: [0; 8],
};

/// Converts a UUID from a 16-byte array in RFC 4122 format (big-endian for numeric fields).
///
/// The byte layout is:
Expand DownExpand Up@@ -750,7 +761,7 @@ pub struct TaHead {
pub const TA_HEAD_SECTION_NAME: &str = ".ta_head";

/// `TEE_Identity` from `optee_os/lib/libutee/include/tee_api_types.h`.
#[derive(Clone, Copy, PartialEq, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, Immutable, IntoBytes)]
#[repr(C)]
pub struct TeeIdentity {
pub login: TeeLogin,
Expand DownExpand Up@@ -832,9 +843,11 @@ const TEE_LOGIN_APPLICATION: u32 = 0x4;
const TEE_LOGIN_APPLICATION_USER: u32 = 0x5;
const TEE_LOGIN_APPLICATION_GROUP: u32 = 0x6;
const TEE_LOGIN_TRUSTED_APP: u32 = 0xf000_0000;
// Private OP-TEE login for in-kernel REE clients (`tee_api_defines_extensions.h`).
const TEE_LOGIN_REE_KERNEL: u32 = 0x8000_0000;

/// `TEE Login type` from `optee_os/lib/libutee/include/tee_api_defines.h`
#[derive(Clone, Copy, PartialEq, TryFromPrimitive, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, TryFromPrimitive, Immutable, IntoBytes)]
#[repr(u32)]
pub enum TeeLogin {
Public = TEE_LOGIN_PUBLIC,
Expand All@@ -843,6 +856,7 @@ pub enum TeeLogin {
Application = TEE_LOGIN_APPLICATION,
ApplicationUser = TEE_LOGIN_APPLICATION_USER,
ApplicationGroup = TEE_LOGIN_APPLICATION_GROUP,
ReeKernel = TEE_LOGIN_REE_KERNEL,
TrustedApp = TEE_LOGIN_TRUSTED_APP,
}

Expand DownExpand Up@@ -1469,6 +1483,10 @@ const OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: u8 = 0xb;
// Note: `OPTEE_MSG_ATTR_TYPE_FMEM_*` are aliases of `OPTEE_MSG_ATTR_TYPE_RMEM_*`.
// Whether it is RMEM of FMEM depends on the conduit.

/// Meta-parameter marker of the attribute word. Set on the `OpenSession`
/// TA-UUID and client-identity params.
const OPTEE_MSG_ATTR_META: u64 = 1 << 8;

#[non_exhaustive]
#[derive(Debug, PartialEq, TryFromPrimitive)]
#[repr(u8)]
Expand All@@ -1492,11 +1510,17 @@ pub enum OpteeMsgAttrType {
/// - bit 8 – meta
/// - bit 9 – noncontig
/// - bits \[63:10\] – reserved (zero)
#[derive(Clone, Copy, Default, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[derive(Clone, Copy, Default, PartialEq, Eq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(transparent)]
pub struct OpteeMsgAttr(u64);

impl OpteeMsgAttr {
/// The exact attribute word an `OpenSession` meta value parameter must carry
/// (`OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT`, all other bits
/// zero). See [`OpteeMsgArgs::get_meta_param_value`].
pub const META_VALUE_INPUT: Self =
Self(OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT as u64);

/// Returns the attribute type (bits 0–7).
#[allow(clippy::cast_possible_truncation)]
pub fn attr_type(&self) -> u8 {
Expand DownExpand Up@@ -1525,6 +1549,10 @@ impl OpteeMsgParam {
pub fn attr_type(&self) -> OpteeMsgAttrType {
OpteeMsgAttrType::try_from(self.attr.attr_type()).unwrap_or(OpteeMsgAttrType::None)
}
/// Returns `true` when the meta bit (bit 8) is set.
pub fn is_meta(&self) -> bool {
self.attr.meta()
}
pub fn get_param_tmem(&self) -> Option<OpteeMsgParamTmem> {
if matches!(
self.attr.attr_type(),
Expand DownExpand Up@@ -1757,6 +1785,27 @@ impl OpteeMsgArgs {
.ok_or(OpteeSmcReturnCode::EBadCmd)?)
}
}

/// Read a value parameter that must be tagged as an `OpenSession` meta parameter.
///
/// `OpenSession` conveys the TA UUID and client identity in the first two
/// params, each marked exactly [`OpteeMsgAttr::META_VALUE_INPUT`], mirroring
/// OP-TEE OS `get_open_session_meta()`. Plain `get_param_value` ignores
/// these bits, so it must not be used for this.
pub fn get_meta_param_value(
&self,
index: usize,
) -> Result<OpteeMsgParamValue, OpteeSmcReturnCode> {
if index >= self.num_params as usize {
return Err(OpteeSmcReturnCode::ENotAvail);
}
let param = &self.params[index];
if param.attr != OpteeMsgAttr::META_VALUE_INPUT {
return Err(OpteeSmcReturnCode::EBadCmd);
}
param.get_param_value().ok_or(OpteeSmcReturnCode::EBadCmd)
}

pub fn set_param_value(
&mut self,
index: usize,
Expand Down
1 change: 0 additions & 1 deletion litebox_runner_lvbs/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,6 @@ litebox_shim_optee = { path = "../litebox_shim_optee/", version = "0.1.0" }
litebox_util_log = { version = "0.1.0", path = "../litebox_util_log" }
log = { version = "0.4", default-features = false }
spin = { version = "0.10.0", default-features = false, features = ["spin_mutex"] }
once_cell = { version = "1.21.3", default-features = false, features = ["race", "alloc"] }

[target.'cfg(target_arch = "x86_64")'.dependencies]
x86_64 = { version = "0.15.2", default-features = false, features = ["instructions"] }
Expand Down
50 changes: 24 additions & 26 deletions litebox_runner_lvbs/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,9 +42,8 @@ use litebox_shim_optee::msg_handler::{
decode_ta_request, handle_optee_msg_args, handle_optee_smc_args, packed_msg_args_lock,
update_optee_msg_args,
};
use litebox_shim_optee::session::{OpenSessionTarget, SessionManager, TaInstance};
use litebox_shim_optee::session::{OpenSessionTarget, TaInstance, session_manager};
use litebox_shim_optee::{NormalWorldConstPtr, NormalWorldMutPtr, UserConstPtr};
use once_cell::race::OnceBox;

/// Seed the initial heap regions so the global allocator has enough memory
/// for slab-backed allocations (the slab needs >= 2 MB backing pages).
Expand DownExpand Up@@ -288,12 +287,6 @@ fn optee_smc_handler_entry_inner(
Ok(0)
}

/// Get the global session manager.
fn session_manager() -> &'static SessionManager {
static SESSION_MANAGER: OnceBox<SessionManager> = OnceBox::new();
SESSION_MANAGER.get_or_init(|| Box::new(SessionManager::new()))
}

/// Switch to the base page table.
///
/// This must be called before returning to VTL0 to ensure VTL1 reentry is
Expand DownExpand Up@@ -527,6 +520,7 @@ fn handle_open_session(
msg_args_phys_addr,
instance,
params,
client_identity,
&ta_req_info,
),
OpenSessionTarget::NewInstance => open_session_new_instance(
Expand DownExpand Up@@ -560,6 +554,7 @@ fn open_session_single_instance(
msg_args_phys_addr: u64,
instance: &TaInstance,
params: &[litebox_common_optee::UteeParamOwned],
client_identity: Option<litebox_common_optee::TeeIdentity>,
ta_req_info: &litebox_shim_optee::msg_handler::TaRequestInfo<PAGE_SIZE>,
) -> Result<(), OpteeSmcReturnCode> {
let task_pt_id = instance.task_page_table_id();
Expand All@@ -570,6 +565,9 @@ fn open_session_single_instance(
// Safe to unwrap: session ID has been just created.
let runner_session_id = session_token.session_id().unwrap();

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

debug_serial_println!(
"Reusing single-instance TA: uuid={:?}, task_pt_id={}, session_id={}",
ta_uuid,
Expand All@@ -588,7 +586,7 @@ fn open_session_single_instance(
.ok_or(OpteeSmcReturnCode::EBadCmd)?
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -686,6 +684,9 @@ fn open_session_single_instance(
teardown_ta_page_table(instance.shim(), task_pt_id);
};
} else {
// The session id is forgotten (never recycled), so the token's drop
// won't clear the recorded identity. Remove the client identity here.
session_manager().clear_session_client_identity(runner_session_id);
Comment thread
sangho2 marked this conversation as resolved.
session_token.disarm();
}
return Err(e);
Expand All@@ -704,7 +705,7 @@ fn open_session_single_instance(
}

/// Create a new TA instance for a session. Must be called from within a
/// [`SessionManager::with_ta`] closure.
/// [`litebox_shim_optee::session::SessionManager::with_ta`] closure.
///
/// If ldelf loading or OpenSession entry point fails, the page table is torn down.
/// Per OP-TEE OS semantics: if OpenSession returns non-success, cleanup happens.
Expand DownExpand Up@@ -741,19 +742,13 @@ fn open_session_new_instance(
// Load ldelf and TA - Box immediately to keep at fixed heap address
let shim = litebox_shim_optee::OpteeShimBuilder::new().build();
let loaded_program = Box::new(
shim.load_ldelf(
LDELF_BINARY,
ta_uuid,
Some(ta_bin),
client_identity,
runner_session_id,
)
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
shim.load_ldelf(LDELF_BINARY, ta_uuid, Some(ta_bin))
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
);

let ta_flags = loaded_program.ta_flags;
Expand DownExpand Up@@ -801,6 +796,9 @@ fn open_session_new_instance(
return Ok(());
}

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

// Load TA context with parameters for OpenSession - pass actual session_id
loaded_program.entrypoints.as_ref().ok_or_else(|| {
// Safety: We are about to tear down this TA instance;
Expand All@@ -814,7 +812,7 @@ fn open_session_new_instance(
.unwrap()
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -983,7 +981,7 @@ fn handle_invoke_command(
entrypoints_ref
.load_ta_context(
params.as_slice(),
Some(session_id),
session_id,
UteeEntryFunc::InvokeCommand as u32,
Some(cmd_id),
)
Expand DownExpand Up@@ -1095,7 +1093,7 @@ fn handle_close_session(
.unwrap()
.load_ta_context(
&[],
Some(session_id),
session_id,
UteeEntryFunc::CloseSession as u32,
None,
)
Expand Down
15 changes: 4 additions & 11 deletions litebox_runner_optee_on_linux_userland/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ use anyhow::{Context as _, Result};
use clap::Parser;
use litebox_common_optee::{TeeUuid, UteeEntryFunc, UteeParamOwned};
use litebox_platform_multiplex::Platform;
use litebox_shim_optee::session::SessionManager;
use litebox_shim_optee::session::session_manager;
use std::path::PathBuf;

mod tests;
Expand DownExpand Up@@ -109,21 +109,14 @@ fn run_ta_with_default_commands(
ldelf_bin: &[u8],
ta_bin: &[u8],
) {
let session_manager = SessionManager::new();
for func_id in [UteeEntryFunc::OpenSession, UteeEntryFunc::CloseSession] {
let params = [const { UteeParamOwned::None }; UteeParamOwned::TEE_NUM_PARAMS];

if func_id == UteeEntryFunc::OpenSession {
let session_token = session_manager.try_acquire_open_session_token().unwrap();
let session_token = session_manager().try_acquire_open_session_token().unwrap();
let session_id = session_token.session_id().unwrap();
let loaded_program = shim
.load_ldelf(
ldelf_bin,
TeeUuid::default(),
Some(ta_bin),
None,
session_id,
)
.load_ldelf(ldelf_bin, TeeUuid::default(), Some(ta_bin))
.map_err(|_| {
panic!("Failed to load ldelf");
})
Expand All@@ -140,7 +133,7 @@ fn run_ta_with_default_commands(
// loaded binary and heap. In that sense, we can create (and destroy) a stack
// for each command freely.
let _ = entrypoints
.load_ta_context(params.as_slice(), None, func_id as u32, None)
.load_ta_context(params.as_slice(), session_id, func_id as u32, None)
.map_err(|_| {
panic!("Failed to load TA context");
});
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Add per-session OP-TEE client identity handling by sangho2 · Pull Request #885 · microsoft/litebox · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dev_tests/src/ratchet.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -40,10 +40,10 @@ fn ratchet_globals() -> Result<()> {
("litebox_platform_lvbs/", 24),
("litebox_platform_multiplex/", 1),
("litebox_platform_windows_userland/", 8),
("litebox_runner_lvbs/", 6),
("litebox_runner_lvbs/", 5),
("litebox_runner_snp/", 2),
("litebox_shim_linux/", 1),
("litebox_shim_optee/", 4),
("litebox_shim_optee/", 5),
],
|file| {
Ok(file
Expand Down
55 changes: 52 additions & 3 deletions litebox_common_optee/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -624,6 +624,17 @@ pub struct TeeUuid {
}

impl TeeUuid {
/// The nil UUID (all zeros, RFC 4122 S4.1.7).
///
/// Used for anonymous clients (e.g., `TeeLogin::Public`) that carry no
/// REE-derived identity.
pub const NIL: Self = Self {
time_low: 0,
time_mid: 0,
time_hi_and_version: 0,
clock_seq_and_node: [0; 8],
};

/// Converts a UUID from a 16-byte array in RFC 4122 format (big-endian for numeric fields).
///
/// The byte layout is:
Expand DownExpand Up@@ -750,7 +761,7 @@ pub struct TaHead {
pub const TA_HEAD_SECTION_NAME: &str = ".ta_head";

/// `TEE_Identity` from `optee_os/lib/libutee/include/tee_api_types.h`.
#[derive(Clone, Copy, PartialEq, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, Immutable, IntoBytes)]
#[repr(C)]
pub struct TeeIdentity {
pub login: TeeLogin,
Expand DownExpand Up@@ -832,9 +843,11 @@ const TEE_LOGIN_APPLICATION: u32 = 0x4;
const TEE_LOGIN_APPLICATION_USER: u32 = 0x5;
const TEE_LOGIN_APPLICATION_GROUP: u32 = 0x6;
const TEE_LOGIN_TRUSTED_APP: u32 = 0xf000_0000;
// Private OP-TEE login for in-kernel REE clients (`tee_api_defines_extensions.h`).
const TEE_LOGIN_REE_KERNEL: u32 = 0x8000_0000;

/// `TEE Login type` from `optee_os/lib/libutee/include/tee_api_defines.h`
#[derive(Clone, Copy, PartialEq, TryFromPrimitive, Immutable, IntoBytes)]
#[derive(Clone, Copy, PartialEq, Debug, TryFromPrimitive, Immutable, IntoBytes)]
#[repr(u32)]
pub enum TeeLogin {
Public = TEE_LOGIN_PUBLIC,
Expand All@@ -843,6 +856,7 @@ pub enum TeeLogin {
Application = TEE_LOGIN_APPLICATION,
ApplicationUser = TEE_LOGIN_APPLICATION_USER,
ApplicationGroup = TEE_LOGIN_APPLICATION_GROUP,
ReeKernel = TEE_LOGIN_REE_KERNEL,
TrustedApp = TEE_LOGIN_TRUSTED_APP,
}

Expand DownExpand Up@@ -1469,6 +1483,10 @@ const OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: u8 = 0xb;
// Note: `OPTEE_MSG_ATTR_TYPE_FMEM_*` are aliases of `OPTEE_MSG_ATTR_TYPE_RMEM_*`.
// Whether it is RMEM of FMEM depends on the conduit.

/// Meta-parameter marker of the attribute word. Set on the `OpenSession`
/// TA-UUID and client-identity params.
const OPTEE_MSG_ATTR_META: u64 = 1 << 8;

#[non_exhaustive]
#[derive(Debug, PartialEq, TryFromPrimitive)]
#[repr(u8)]
Expand All@@ -1492,11 +1510,17 @@ pub enum OpteeMsgAttrType {
/// - bit 8 – meta
/// - bit 9 – noncontig
/// - bits \[63:10\] – reserved (zero)
#[derive(Clone, Copy, Default, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[derive(Clone, Copy, Default, PartialEq, Eq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(transparent)]
pub struct OpteeMsgAttr(u64);

impl OpteeMsgAttr {
/// The exact attribute word an `OpenSession` meta value parameter must carry
/// (`OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT`, all other bits
/// zero). See [`OpteeMsgArgs::get_meta_param_value`].
pub const META_VALUE_INPUT: Self =
Self(OPTEE_MSG_ATTR_META | OPTEE_MSG_ATTR_TYPE_VALUE_INPUT as u64);

/// Returns the attribute type (bits 0–7).
#[allow(clippy::cast_possible_truncation)]
pub fn attr_type(&self) -> u8 {
Expand DownExpand Up@@ -1525,6 +1549,10 @@ impl OpteeMsgParam {
pub fn attr_type(&self) -> OpteeMsgAttrType {
OpteeMsgAttrType::try_from(self.attr.attr_type()).unwrap_or(OpteeMsgAttrType::None)
}
/// Returns `true` when the meta bit (bit 8) is set.
pub fn is_meta(&self) -> bool {
self.attr.meta()
}
pub fn get_param_tmem(&self) -> Option<OpteeMsgParamTmem> {
if matches!(
self.attr.attr_type(),
Expand DownExpand Up@@ -1757,6 +1785,27 @@ impl OpteeMsgArgs {
.ok_or(OpteeSmcReturnCode::EBadCmd)?)
}
}

/// Read a value parameter that must be tagged as an `OpenSession` meta parameter.
///
/// `OpenSession` conveys the TA UUID and client identity in the first two
/// params, each marked exactly [`OpteeMsgAttr::META_VALUE_INPUT`], mirroring
/// OP-TEE OS `get_open_session_meta()`. Plain `get_param_value` ignores
/// these bits, so it must not be used for this.
pub fn get_meta_param_value(
&self,
index: usize,
) -> Result<OpteeMsgParamValue, OpteeSmcReturnCode> {
if index >= self.num_params as usize {
return Err(OpteeSmcReturnCode::ENotAvail);
}
let param = &self.params[index];
if param.attr != OpteeMsgAttr::META_VALUE_INPUT {
return Err(OpteeSmcReturnCode::EBadCmd);
}
param.get_param_value().ok_or(OpteeSmcReturnCode::EBadCmd)
}

pub fn set_param_value(
&mut self,
index: usize,
Expand Down
1 change: 0 additions & 1 deletion litebox_runner_lvbs/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,6 @@ litebox_shim_optee = { path = "../litebox_shim_optee/", version = "0.1.0" }
litebox_util_log = { version = "0.1.0", path = "../litebox_util_log" }
log = { version = "0.4", default-features = false }
spin = { version = "0.10.0", default-features = false, features = ["spin_mutex"] }
once_cell = { version = "1.21.3", default-features = false, features = ["race", "alloc"] }

[target.'cfg(target_arch = "x86_64")'.dependencies]
x86_64 = { version = "0.15.2", default-features = false, features = ["instructions"] }
Expand Down
50 changes: 24 additions & 26 deletions litebox_runner_lvbs/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,9 +42,8 @@ use litebox_shim_optee::msg_handler::{
decode_ta_request, handle_optee_msg_args, handle_optee_smc_args, packed_msg_args_lock,
update_optee_msg_args,
};
use litebox_shim_optee::session::{OpenSessionTarget, SessionManager, TaInstance};
use litebox_shim_optee::session::{OpenSessionTarget, TaInstance, session_manager};
use litebox_shim_optee::{NormalWorldConstPtr, NormalWorldMutPtr, UserConstPtr};
use once_cell::race::OnceBox;

/// Seed the initial heap regions so the global allocator has enough memory
/// for slab-backed allocations (the slab needs >= 2 MB backing pages).
Expand DownExpand Up@@ -288,12 +287,6 @@ fn optee_smc_handler_entry_inner(
Ok(0)
}

/// Get the global session manager.
fn session_manager() -> &'static SessionManager {
static SESSION_MANAGER: OnceBox<SessionManager> = OnceBox::new();
SESSION_MANAGER.get_or_init(|| Box::new(SessionManager::new()))
}

/// Switch to the base page table.
///
/// This must be called before returning to VTL0 to ensure VTL1 reentry is
Expand DownExpand Up@@ -527,6 +520,7 @@ fn handle_open_session(
msg_args_phys_addr,
instance,
params,
client_identity,
&ta_req_info,
),
OpenSessionTarget::NewInstance => open_session_new_instance(
Expand DownExpand Up@@ -560,6 +554,7 @@ fn open_session_single_instance(
msg_args_phys_addr: u64,
instance: &TaInstance,
params: &[litebox_common_optee::UteeParamOwned],
client_identity: Option<litebox_common_optee::TeeIdentity>,
ta_req_info: &litebox_shim_optee::msg_handler::TaRequestInfo<PAGE_SIZE>,
) -> Result<(), OpteeSmcReturnCode> {
let task_pt_id = instance.task_page_table_id();
Expand All@@ -570,6 +565,9 @@ fn open_session_single_instance(
// Safe to unwrap: session ID has been just created.
let runner_session_id = session_token.session_id().unwrap();

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

debug_serial_println!(
"Reusing single-instance TA: uuid={:?}, task_pt_id={}, session_id={}",
ta_uuid,
Expand All@@ -588,7 +586,7 @@ fn open_session_single_instance(
.ok_or(OpteeSmcReturnCode::EBadCmd)?
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -686,6 +684,9 @@ fn open_session_single_instance(
teardown_ta_page_table(instance.shim(), task_pt_id);
};
} else {
// The session id is forgotten (never recycled), so the token's drop
// won't clear the recorded identity. Remove the client identity here.
session_manager().clear_session_client_identity(runner_session_id);
Comment thread
sangho2 marked this conversation as resolved.
session_token.disarm();
}
return Err(e);
Expand All@@ -704,7 +705,7 @@ fn open_session_single_instance(
}

/// Create a new TA instance for a session. Must be called from within a
/// [`SessionManager::with_ta`] closure.
/// [`litebox_shim_optee::session::SessionManager::with_ta`] closure.
///
/// If ldelf loading or OpenSession entry point fails, the page table is torn down.
/// Per OP-TEE OS semantics: if OpenSession returns non-success, cleanup happens.
Expand DownExpand Up@@ -741,19 +742,13 @@ fn open_session_new_instance(
// Load ldelf and TA - Box immediately to keep at fixed heap address
let shim = litebox_shim_optee::OpteeShimBuilder::new().build();
let loaded_program = Box::new(
shim.load_ldelf(
LDELF_BINARY,
ta_uuid,
Some(ta_bin),
client_identity,
runner_session_id,
)
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
shim.load_ldelf(LDELF_BINARY, ta_uuid, Some(ta_bin))
.map_err(|_| {
// Safety: We are about to tear down this TA instance;
// no references to user-space memory will be held afterwards.
unsafe { teardown_ta_page_table(&shim, task_pt_id) };
OpteeSmcReturnCode::ENomem
})?,
);

let ta_flags = loaded_program.ta_flags;
Expand DownExpand Up@@ -801,6 +796,9 @@ fn open_session_new_instance(
return Ok(());
}

// Record the client identity before running OpenSession
session_manager().set_session_client_identity(runner_session_id, client_identity);

// Load TA context with parameters for OpenSession - pass actual session_id
loaded_program.entrypoints.as_ref().ok_or_else(|| {
// Safety: We are about to tear down this TA instance;
Expand All@@ -814,7 +812,7 @@ fn open_session_new_instance(
.unwrap()
.load_ta_context(
params,
Some(runner_session_id),
runner_session_id,
UteeEntryFunc::OpenSession as u32,
None,
)
Expand DownExpand Up@@ -983,7 +981,7 @@ fn handle_invoke_command(
entrypoints_ref
.load_ta_context(
params.as_slice(),
Some(session_id),
session_id,
UteeEntryFunc::InvokeCommand as u32,
Some(cmd_id),
)
Expand DownExpand Up@@ -1095,7 +1093,7 @@ fn handle_close_session(
.unwrap()
.load_ta_context(
&[],
Some(session_id),
session_id,
UteeEntryFunc::CloseSession as u32,
None,
)
Expand Down
15 changes: 4 additions & 11 deletions litebox_runner_optee_on_linux_userland/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ use anyhow::{Context as _, Result};
use clap::Parser;
use litebox_common_optee::{TeeUuid, UteeEntryFunc, UteeParamOwned};
use litebox_platform_multiplex::Platform;
use litebox_shim_optee::session::SessionManager;
use litebox_shim_optee::session::session_manager;
use std::path::PathBuf;

mod tests;
Expand DownExpand Up@@ -109,21 +109,14 @@ fn run_ta_with_default_commands(
ldelf_bin: &[u8],
ta_bin: &[u8],
) {
let session_manager = SessionManager::new();
for func_id in [UteeEntryFunc::OpenSession, UteeEntryFunc::CloseSession] {
let params = [const { UteeParamOwned::None }; UteeParamOwned::TEE_NUM_PARAMS];

if func_id == UteeEntryFunc::OpenSession {
let session_token = session_manager.try_acquire_open_session_token().unwrap();
let session_token = session_manager().try_acquire_open_session_token().unwrap();
let session_id = session_token.session_id().unwrap();
let loaded_program = shim
.load_ldelf(
ldelf_bin,
TeeUuid::default(),
Some(ta_bin),
None,
session_id,
)
.load_ldelf(ldelf_bin, TeeUuid::default(), Some(ta_bin))
.map_err(|_| {
panic!("Failed to load ldelf");
})
Expand All@@ -140,7 +133,7 @@ fn run_ta_with_default_commands(
// loaded binary and heap. In that sense, we can create (and destroy) a stack
// for each command freely.
let _ = entrypoints
.load_ta_context(params.as_slice(), None, func_id as u32, None)
.load_ta_context(params.as_slice(), session_id, func_id as u32, None)
.map_err(|_| {
panic!("Failed to load TA context");
});
Expand Down
Loading