You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by yu...@apache.org on 2025/09/30 02:58:04 UTC
(teaclave-trustzone-sdk) 02/03: optee-teec: clippy default enforcement
This is an automated email from the ASF dual-hosted git repository.
yuanz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/teaclave-trustzone-sdk.git
commit c4b7d4d171ae17728c45ad37b9a0abbbb909d58d
Author: Yuan Zhuang <yu...@apache.org>
AuthorDate: Thu Sep 25 08:39:12 2025 +0000
optee-teec: clippy default enforcement
---
.github/workflows/reuse_test.yml | 1 +
optee-teec/macros/src/lib.rs | 60 ++++++++++++++++---------
optee-teec/optee-teec-sys/src/tee_client_api.rs | 2 +-
optee-teec/src/extension.rs | 8 ++--
optee-teec/src/operation.rs | 2 +-
optee-teec/src/parameter.rs | 12 ++---
6 files changed, 53 insertions(+), 32 deletions(-)
diff --git a/.github/workflows/reuse_test.yml b/.github/workflows/reuse_test.yml
index 6980089..407328a 100644
--- a/.github/workflows/reuse_test.yml
+++ b/.github/workflows/reuse_test.yml
@@ -61,6 +61,7 @@ jobs:
# Clippy checks
(cd optee-utee && cargo clippy --target aarch64-unknown-linux-gnu -- -D warnings)
+ (cd optee-teec && cargo clippy --target aarch64-unknown-linux-gnu -- -D warnings)
# Cross-compile on host and run tests in QEMU
#
diff --git a/optee-teec/macros/src/lib.rs b/optee-teec/macros/src/lib.rs
index b337352..ddabc33 100644
--- a/optee-teec/macros/src/lib.rs
+++ b/optee-teec/macros/src/lib.rs
@@ -39,12 +39,9 @@ pub fn plugin_init(_args: TokenStream, input: TokenStream) -> TokenStream {
// check the function signature
let valid_signature = f_sig.constness.is_none()
- && match f_vis {
- syn::Visibility::Inherited => true,
- _ => false,
- }
+ && matches!(f_vis, syn::Visibility::Inherited)
&& f_sig.abi.is_none()
- && f_inputs.len() == 0
+ && f_inputs.is_empty()
&& f_sig.generics.where_clause.is_none()
&& f_sig.variadic.is_none()
&& check_return_type(&f);
@@ -83,7 +80,7 @@ fn check_return_type(item_fn: &syn::ItemFn) -> bool {
}
}
}
- return false;
+ false
}
/// Attribute to declare the invoke function of a plugin
@@ -101,10 +98,7 @@ pub fn plugin_invoke(_args: TokenStream, input: TokenStream) -> TokenStream {
// check the function signature
let valid_signature = f_sig.constness.is_none()
- && match f_vis {
- syn::Visibility::Inherited => true,
- _ => false,
- }
+ && matches!(f_vis, syn::Visibility::Inherited)
&& f_sig.abi.is_none()
&& f_inputs.len() == 1
&& f_sig.generics.where_clause.is_none()
@@ -129,11 +123,39 @@ pub fn plugin_invoke(_args: TokenStream, input: TokenStream) -> TokenStream {
.into_token_stream();
quote!(
- // temporary workaround for this error:
- // error: this public function might dereference a raw pointer but is not marked `unsafe`
- // should remove this allow macro when fix clippy errors of optee-* crates
- #[allow(clippy::not_unsafe_ptr_arg_deref)]
- pub fn _plugin_invoke(
+ /// # Safety
+ ///
+ /// The `_plugin_invoke` function is the `extern "C"` entrypoint called by OP-TEE OS.
+ /// This SDK allows developers to implement the inner logic for a Normal World plugin in Rust.
+ /// More about plugins:
+ /// https://optee.readthedocs.io/en/latest/architecture/globalplatform_api.html#loadable-plugins-framework
+ ///
+ /// According to Clippy checks, any FFI function taking raw pointers as parameters
+ /// must be marked `unsafe`. This applies here because the function directly
+ /// dereferences `data` and `out_len`.
+ ///
+ /// ## Security assumptions
+ /// The caller (OP-TEE OS) must ensure:
+ /// - `data` points to valid memory for reads and writes of at least `in_len` bytes
+ /// - `out_len` is a valid, writable, and properly aligned pointer to a `u32`
+ /// - If `in_len == 0`, `data` may be null; otherwise it must be non-null
+ ///
+ /// Additional guarantees enforced by `PluginParameters` in this SDK:
+ /// - The output length (`outslice.len()`) will never exceed `in_len`
+ /// because [`PluginParameters::set_buf_from_slice`] checks and rejects overflows.
+ /// - Input and output share the same buffer (`inout`), so overlap is intentional
+ /// and safely handled by [`PluginParameters::set_buf_from_slice`].
+ ///
+ /// ## Scenarios
+ /// - **Valid empty call**: `data = null`, `in_len = 0` → allowed; produces an empty output.
+ /// - **Normal call**: `data` points to a buffer of size `in_len`; the plugin writes
+ /// up to `in_len` bytes and updates `*out_len`.
+ /// - **Overflow attempt**: plugin inner logic (developer code) tries to return
+ /// more bytes than `in_len` → rejected by `set_buf_from_slice`, error returned.
+ /// - **Invalid pointers**: if `data` or `out_len` are invalid (null, dangling, misaligned,
+ /// or pointing to read-only memory), dereferencing them causes undefined behavior.
+ /// This must be prevented by the caller (OP-TEE OS).
+ pub unsafe fn _plugin_invoke(
cmd: u32,
sub_cmd: u32,
data: *mut core::ffi::c_char,
@@ -143,16 +165,14 @@ pub fn plugin_invoke(_args: TokenStream, input: TokenStream) -> TokenStream {
fn inner(#params) -> optee_teec::Result<()> {
#f_block
}
- let mut inbuf = unsafe { std::slice::from_raw_parts_mut(data, in_len as usize) };
+ let mut inbuf = std::slice::from_raw_parts_mut(data, in_len as usize);
let mut params = optee_teec::PluginParameters::new(cmd, sub_cmd, inbuf);
if let Err(err) = inner(&mut params) {
return err.raw_code();
};
let outslice = params.get_out_slice();
- unsafe {
- *out_len = outslice.len() as u32;
- std::ptr::copy(outslice.as_ptr(), data, outslice.len());
- };
+ *out_len = outslice.len() as u32;
+ std::ptr::copy(outslice.as_ptr(), data, outslice.len());
return optee_teec::raw::TEEC_SUCCESS;
}
)
diff --git a/optee-teec/optee-teec-sys/src/tee_client_api.rs b/optee-teec/optee-teec-sys/src/tee_client_api.rs
index 79ee42b..16b3d76 100644
--- a/optee-teec/optee-teec-sys/src/tee_client_api.rs
+++ b/optee-teec/optee-teec-sys/src/tee_client_api.rs
@@ -19,7 +19,7 @@ use libc::*;
pub fn TEEC_PARAM_TYPES(p0:u32, p1:u32, p2:u32, p3:u32) -> u32 {
let tmp = p1 << 4 | p2 << 8 | p3 << 12;
- return p0 | tmp;
+ p0 | tmp
}
pub const TEEC_CONFIG_PAYLOAD_REF_COUNT: u32 = 4;
diff --git a/optee-teec/src/extension.rs b/optee-teec/src/extension.rs
index 206373a..c9887d4 100644
--- a/optee-teec/src/extension.rs
+++ b/optee-teec/src/extension.rs
@@ -24,7 +24,7 @@ pub struct PluginMethod {
pub name: *const c_char,
pub uuid: raw::TEEC_UUID,
pub init: fn() -> raw::TEEC_Result,
- pub invoke: fn(
+ pub invoke: unsafe fn(
cmd: u32,
sub_cmd: u32,
data: *mut c_char,
@@ -51,7 +51,7 @@ impl<'a> PluginParameters<'a> {
cmd,
sub_cmd,
inout,
- outlen: 0 as usize,
+ outlen: 0_usize,
}
}
pub fn set_buf_from_slice(&mut self, sendslice: &[u8]) -> Result<()> {
@@ -59,8 +59,8 @@ impl<'a> PluginParameters<'a> {
println!("Overflow: Input length is less than output length");
return Err(Error::new(ErrorKind::Security));
}
- self.outlen = sendslice.len() as usize;
- self.inout[..self.outlen].copy_from_slice(&sendslice);
+ self.outlen = sendslice.len();
+ self.inout[..self.outlen].copy_from_slice(sendslice);
Ok(())
}
pub fn get_out_slice(&self) -> &[u8] {
diff --git a/optee-teec/src/operation.rs b/optee-teec/src/operation.rs
index 985b954..2960182 100644
--- a/optee-teec/src/operation.rs
+++ b/optee-teec/src/operation.rs
@@ -40,7 +40,7 @@ impl<A: Param, B: Param, C: Param, D: Param> Operation<A, B, C, D> {
p3.param_type(),
)
.into();
- raw_op.params = [p0.into_raw(), p1.into_raw(), p2.into_raw(), p3.into_raw()];
+ raw_op.params = [p0.to_raw(), p1.to_raw(), p2.to_raw(), p3.to_raw()];
Operation {
raw: raw_op,
phantom0: PhantomData,
diff --git a/optee-teec/src/parameter.rs b/optee-teec/src/parameter.rs
index 9712377..18bdd49 100644
--- a/optee-teec/src/parameter.rs
+++ b/optee-teec/src/parameter.rs
@@ -19,7 +19,7 @@ use crate::raw;
use std::{marker, mem};
pub trait Param {
- fn into_raw(&mut self) -> raw::TEEC_Parameter;
+ fn to_raw(&mut self) -> raw::TEEC_Parameter;
fn param_type(&self) -> ParamType;
fn from_raw(raw: raw::TEEC_Parameter, param_type: ParamType) -> Self;
}
@@ -53,14 +53,14 @@ impl ParamValue {
}
impl Param for ParamValue {
- fn into_raw(&mut self) -> raw::TEEC_Parameter {
+ fn to_raw(&mut self) -> raw::TEEC_Parameter {
raw::TEEC_Parameter { value: self.raw }
}
fn from_raw(raw: raw::TEEC_Parameter, param_type: ParamType) -> Self {
Self {
raw: unsafe { raw.value },
- param_type: param_type,
+ param_type,
}
}
@@ -73,7 +73,7 @@ impl Param for ParamValue {
pub struct ParamNone;
impl Param for ParamNone {
- fn into_raw(&mut self) -> raw::TEEC_Parameter {
+ fn to_raw(&mut self) -> raw::TEEC_Parameter {
let raw: raw::TEEC_Parameter = unsafe { mem::zeroed() };
raw
}
@@ -133,7 +133,7 @@ impl<'a> ParamTmpRef<'a> {
}
impl<'a> Param for ParamTmpRef<'a> {
- fn into_raw(&mut self) -> raw::TEEC_Parameter {
+ fn to_raw(&mut self) -> raw::TEEC_Parameter {
raw::TEEC_Parameter { tmpref: self.raw }
}
@@ -144,7 +144,7 @@ impl<'a> Param for ParamTmpRef<'a> {
fn from_raw(raw: raw::TEEC_Parameter, param_type: ParamType) -> Self {
Self {
raw: unsafe { raw.tmpref },
- param_type: param_type,
+ param_type,
_marker: marker::PhantomData,
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org