Skip to content
Open
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
16 changes: 15 additions & 1 deletion litebox_common_optee/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2025,7 +2025,7 @@ impl From<&OpteeSmcArgsPage> for OpteeSmcArgs {
/// OP-TEE SMC call arguments.
#[derive(Clone, Copy, Default, FromBytes)]
pub struct OpteeSmcArgs {
args: [usize; Self::NUM_OPTEE_SMC_ARGS],
pub args: [usize; Self::NUM_OPTEE_SMC_ARGS],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it require pub?

}

impl OpteeSmcArgs {
Expand All @@ -2050,6 +2050,19 @@ impl OpteeSmcArgs {
}
}

/// Get the shared memory reference and offset for the physical address of `OpteeMsgArgs`.
pub fn optee_regd_shm_ref_and_offset(&self) -> Result<(u64, usize), OpteeSmcReturnCode> {
// args[1]:args[2] contains the shared memory reference (pointer)
// and args[3] contains the offset within that shared memory.
if self.args[1] & 0xffff_ffff_0000_0000 == 0 && self.args[2] & 0xffff_ffff_0000_0000 == 0 {
let shm_ref = (self.args[1] << 32) | self.args[2];
let offset = self.args[3];
Ok((shm_ref as u64, offset))
} else {
Err(OpteeSmcReturnCode::EBadAddr)
}
}

/// Set the return code of an OP-TEE SMC call
pub fn set_return_code(&mut self, code: OpteeSmcReturnCode) {
self.args[0] = code as usize;
Expand Down Expand Up @@ -2121,6 +2134,7 @@ pub enum OpteeSmcResult<'a> {
CallWithArg {
msg_args: Box<OpteeMsgArgs>,
rpc_args: Option<Box<OpteeRpcArgs>>,
msg_args_phys_addr: u64,
},
}

Expand Down
5 changes: 1 addition & 4 deletions litebox_runner_lvbs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,17 +417,14 @@ fn optee_smc_handler(smc_args_addr: usize) -> OpteeSmcArgs {
let Ok(mut smc_args) = (unsafe { smc_args_ptr.read_at_offset(0) }) else {
return make_error_response(OpteeSmcReturnCode::EBadAddr);
};
let Ok(msg_args_phys_addr) = smc_args.optee_msg_args_phys_addr() else {
smc_args.set_return_code(OpteeSmcReturnCode::EBadAddr);
return *smc_args;
};
let Ok(smc_result) = handle_optee_smc_args(&mut smc_args) else {
smc_args.set_return_code(OpteeSmcReturnCode::EBadCmd);
return *smc_args;
};
if let OpteeSmcResult::CallWithArg {
msg_args,
rpc_args: _,
msg_args_phys_addr,
} = smc_result
{
let mut msg_args = *msg_args;
Expand Down
29 changes: 27 additions & 2 deletions litebox_shim_optee/src/msg_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,38 @@ pub fn handle_optee_smc_args(
Ok(OpteeSmcResult::CallWithArg {
msg_args,
rpc_args: None,
msg_args_phys_addr: msg_args_addr as u64,
})
}
OpteeSmcFunction::CallWithRpcArg | OpteeSmcFunction::CallWithRegdArg => {
OpteeSmcFunction::CallWithRpcArg => {
let msg_args_addr = smc.optee_msg_args_phys_addr()?;
let msg_args_addr: usize = msg_args_addr.truncate();
let (msg_args, rpc_args) = read_optee_msg_args_from_phys(msg_args_addr, true)?;
Ok(OpteeSmcResult::CallWithArg { msg_args, rpc_args })
Ok(OpteeSmcResult::CallWithArg {
msg_args,
rpc_args,
msg_args_phys_addr: msg_args_addr as u64,
})
}
OpteeSmcFunction::CallWithRegdArg => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just curios, when is this method invoked?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the VTL0 side, the optee_smc_do_call_with_arg() function will pass OPTEE_SMC_CALL_WITH_REGD_ARG if the tee shared memory was dynamically allocated

// `OpteeMsgArgs` is located at the offset specified in args[3] within the shared memory region pointed by args[1]:args[2].
let (shm_ref, offset) = smc.optee_regd_shm_ref_and_offset()?;
let shm_info = shm_ref_map()
.get(shm_ref)
.ok_or(OpteeSmcReturnCode::EBadAddr)?;
let page_index = (shm_info.page_offset + offset) / PAGE_SIZE;
let offset_in_page = (shm_info.page_offset + offset) % PAGE_SIZE;
Comment on lines +207 to +208
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might better to do shm_info.page_offset.checked_add(offset).ok_or(OpteeSmcReturnCode::EBadAddr)?; to deal with potential integer overflow attacks. Also, we don't have to compute this twice.

if page_index >= shm_info.page_addrs.len() {
return Err(OpteeSmcReturnCode::EBadAddr);
}
let msg_args_addr = shm_info.page_addrs[page_index].as_usize() + offset_in_page;

let (msg_args, rpc_args) = read_optee_msg_args_from_phys(msg_args_addr, true)?;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LiteBox has read_data_from_shm which reads from offset 0. Could you add another method to read with an offset and use that method here?

Ok(OpteeSmcResult::CallWithArg {
msg_args,
rpc_args,
msg_args_phys_addr: msg_args_addr as u64,
})
}
OpteeSmcFunction::ExchangeCapabilities => {
// TODO: update the below when we support more features
Expand Down
Loading