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:02 UTC

(teaclave-trustzone-sdk) branch main updated (c2da817 -> 2e54d5f)

This is an automated email from the ASF dual-hosted git repository.

yuanz pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/teaclave-trustzone-sdk.git


    from c2da817  ci: enhance cleanup process in workflow (#234)
     new 3847baa  optee-utee: clippy default enforcement
     new c4b7d4d  optee-teec: clippy default enforcement
     new 2e54d5f  plugin: add pointer checks and refine FFI logic

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .github/workflows/reuse_test.yml                |   4 +
 optee-teec/macros/src/lib.rs                    | 107 ++++++++++++++++++------
 optee-teec/optee-teec-sys/src/tee_client_api.rs |   2 +-
 optee-teec/src/extension.rs                     |  28 +++++--
 optee-teec/src/operation.rs                     |   2 +-
 optee-teec/src/parameter.rs                     |  12 +--
 optee-utee/macros/src/lib.rs                    |  49 ++++-------
 optee-utee/optee-utee-sys/src/user_ta_header.rs |  12 ++-
 optee-utee/src/arithmetical.rs                  |  12 +--
 optee-utee/src/crypto_op.rs                     |  34 ++++----
 optee-utee/src/error.rs                         |  20 ++---
 optee-utee/src/extension.rs                     |   6 +-
 optee-utee/src/net/optee.rs                     |   4 +-
 optee-utee/src/object/attribute.rs              |   2 +-
 optee-utee/src/object/object_define.rs          |   6 +-
 optee-utee/src/object/object_info.rs            |   2 +-
 optee-utee/src/object/persistent_object.rs      |   2 +-
 optee-utee/src/object/transient_object.rs       |   2 +-
 optee-utee/src/parameter.rs                     |   8 +-
 optee-utee/src/property.rs                      |  64 +++++++-------
 optee-utee/src/tee_parameter.rs                 |  10 ++-
 optee-utee/src/time.rs                          |   6 ++
 22 files changed, 232 insertions(+), 162 deletions(-)


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org


(teaclave-trustzone-sdk) 03/03: plugin: add pointer checks and refine FFI logic

Posted by yu...@apache.org.
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 2e54d5f72159dee5224362fe8b1dcc55f16c964f
Author: Yuan Zhuang <yu...@apache.org>
AuthorDate: Mon Sep 29 03:39:59 2025 +0000

    plugin: add pointer checks and refine FFI logic
---
 optee-teec/macros/src/lib.rs | 85 +++++++++++++++++++++++++++++++-------------
 optee-teec/src/extension.rs  | 26 +++++++++-----
 2 files changed, 78 insertions(+), 33 deletions(-)

diff --git a/optee-teec/macros/src/lib.rs b/optee-teec/macros/src/lib.rs
index ddabc33..0507276 100644
--- a/optee-teec/macros/src/lib.rs
+++ b/optee-teec/macros/src/lib.rs
@@ -125,7 +125,7 @@ pub fn plugin_invoke(_args: TokenStream, input: TokenStream) -> TokenStream {
     quote!(
         /// # Safety
         ///
-        /// The `_plugin_invoke` function is the `extern "C"` entrypoint called by OP-TEE OS.  
+        /// 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
@@ -134,46 +134,81 @@ pub fn plugin_invoke(_args: TokenStream, input: TokenStream) -> TokenStream {
         /// must be marked `unsafe`. This applies here because the function directly
         /// dereferences `data` and `out_len`.
         ///
-        /// ## Security assumptions
+        /// ## 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`
+        /// - `out_len` is a valid, writable, and properly aligned pointer to a `u32` (cannot be null)
         /// - If `in_len == 0`, `data` may be null; otherwise it must be non-null
+        /// - The memory region pointed to by `data` must not be modified by other threads
+        ///   or processes during plugin execution
         ///
         /// 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`].
+        /// - If `data` is null and `in_len` is 0, it is treated as an empty input buffer;
+        ///   the inner logic (developer code) should consider this case
+        /// - If the output length exceeds `in_len`, it will be rejected and a short buffer
+        ///   error returned, with the required `out_len` set
+        /// - Input and output share the same buffer, so overlap is intentional and safely
+        ///   handled by [`PluginParameters::set_buf_from_slice`] when `out_len <= in_len`
+        /// - If no output is set for a success call, `out_len` will be `0`
         ///
-        /// ## 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).
+        /// ## Usage Scenarios
+        /// - **Valid empty call**: `data = null`, `in_len = 0` → allowed (empty input to inner)
+        /// - **Normal call**: `data` points to a buffer of size `in_len`; if `out_len <= in_len`,
+        ///   the plugin writes up to `in_len` bytes and updates `*out_len`; if `out_len > in_len`,
+        ///   it is rejected with a short buffer error
+        /// - **Buffer overflow attempt**: if inner logic (developer code) tries to return
+        ///   more bytes than `in_len` → rejected by `set_buf_from_slice`, error returned with required `out_len`
+        /// - **Invalid pointers**: null pointers are checked, but other invalid cases of pointers
+        ///   such as dangling, misaligned, or read-only pointers will cause undefined behavior 
+        ///   and must be prevented by the caller
         pub unsafe fn _plugin_invoke(
             cmd: u32,
             sub_cmd: u32,
             data: *mut core::ffi::c_char,
             in_len: u32,
-            out_len: *mut u32
+            out_len: *mut u32,
         ) -> optee_teec::raw::TEEC_Result {
             fn inner(#params) -> optee_teec::Result<()> {
                 #f_block
             }
-            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();
+
+            // Check for null pointers
+            if data.is_null() && in_len != 0 {
+                return optee_teec::raw::TEEC_ERROR_BAD_PARAMETERS;
+            }
+            if out_len.is_null() {
+                return optee_teec::raw::TEEC_ERROR_BAD_PARAMETERS;
+            }
+
+            // Prepare input buffer
+            // `data` is guaranteed to be non-null if `in_len > 0` (checked above)
+            // If `data` is null, `in_len` must be 0, so we create an empty slice
+            // Otherwise, we create a mutable slice from the raw pointer and length
+            let inbuf = if data.is_null() {
+                &mut []
+            } else {
+                // SAFETY: from_raw_parts_mut() is unsafe, but avoids copying the memory
+                // (which is unacceptable for large io buffers).
+                // Note that the caller must ensure the memory is consistent during the plugin execution.
+                std::slice::from_raw_parts_mut(data, in_len as usize)
             };
-            let outslice = params.get_out_slice();
-            *out_len = outslice.len() as u32;
-            std::ptr::copy(outslice.as_ptr(), data, outslice.len());
-            return optee_teec::raw::TEEC_SUCCESS;
+
+            let mut params = optee_teec::PluginParameters::new(cmd, sub_cmd, inbuf);
+            match inner(&mut params) {
+                Ok(()) => {
+                    *out_len = params.get_required_out_len() as u32;
+                    optee_teec::raw::TEEC_SUCCESS
+                }
+                Err(err) => {
+                    if err.kind() == optee_teec::ErrorKind::ShortBuffer {
+                        // Inform the caller about the required buffer size
+                        *out_len = params.get_required_out_len() as u32;
+                        optee_teec::raw::TEEC_ERROR_SHORT_BUFFER
+                    } else {
+                        err.raw_code()
+                    }
+                }
+            }
         }
     )
     .into()
diff --git a/optee-teec/src/extension.rs b/optee-teec/src/extension.rs
index c9887d4..8f50b49 100644
--- a/optee-teec/src/extension.rs
+++ b/optee-teec/src/extension.rs
@@ -37,13 +37,13 @@ pub struct PluginMethod {
 /// @cmd: u32,              plugin cmd, defined in proto/
 /// @sub_cmd: u32,          plugin subcmd, defined in proto/
 /// @inout: &'a mut [u8],   input/output buffer shared with TA and plugin
-/// @outlen,                length of output sent to TA
+/// @required_outlen,                length of output sent to TA
 /// }
 pub struct PluginParameters<'a> {
     pub cmd: u32,
     pub sub_cmd: u32,
     pub inout: &'a mut [u8],
-    outlen: usize,
+    required_outlen: usize,
 }
 impl<'a> PluginParameters<'a> {
     pub fn new(cmd: u32, sub_cmd: u32, inout: &'a mut [u8]) -> Self {
@@ -51,19 +51,29 @@ impl<'a> PluginParameters<'a> {
             cmd,
             sub_cmd,
             inout,
-            outlen: 0_usize,
+            required_outlen: 0_usize,
         }
     }
+
+    // This function copies data from the provided slice to the inout buffer
+    // Please note that the Result should be properly handled by the caller
+    // If the inout buffer is smaller than the provided slice, an error will be returned
+    // Ignoring this error will lead to undefined behavior
     pub fn set_buf_from_slice(&mut self, sendslice: &[u8]) -> Result<()> {
         if self.inout.len() < sendslice.len() {
             println!("Overflow: Input length is less than output length");
-            return Err(Error::new(ErrorKind::Security));
+            self.required_outlen = sendslice.len();
+            return Err(Error::new(ErrorKind::ShortBuffer));
         }
-        self.outlen = sendslice.len();
-        self.inout[..self.outlen].copy_from_slice(sendslice);
+        self.required_outlen = sendslice.len();
+        self.inout[..self.required_outlen].copy_from_slice(sendslice);
         Ok(())
     }
-    pub fn get_out_slice(&self) -> &[u8] {
-        &self.inout[..self.outlen]
+
+    /// This function returns the required output length
+    /// If the inout buffer is too small, this indicates the size needed
+    /// If the inout buffer is large enough, this is the actual output length
+    pub fn get_required_out_len(&self) -> usize {
+        self.required_outlen
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org


(teaclave-trustzone-sdk) 01/03: optee-utee: clippy default enforcement

Posted by yu...@apache.org.
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 3847baa34f23b9a44710ab8cc83987c7c131271d
Author: Yuan Zhuang <yu...@apache.org>
AuthorDate: Wed Sep 24 02:39:04 2025 +0000

    optee-utee: clippy default enforcement
    
    "source environment && cd optee-utee && cargo clippy --target aarch64-unknown-linux-gnu -- -D warnings"
---
 .github/workflows/reuse_test.yml                |  3 ++
 optee-utee/macros/src/lib.rs                    | 49 ++++++-------------
 optee-utee/optee-utee-sys/src/user_ta_header.rs | 12 +++--
 optee-utee/src/arithmetical.rs                  | 12 ++---
 optee-utee/src/crypto_op.rs                     | 34 ++++++-------
 optee-utee/src/error.rs                         | 20 ++++----
 optee-utee/src/extension.rs                     |  6 +--
 optee-utee/src/net/optee.rs                     |  4 +-
 optee-utee/src/object/attribute.rs              |  2 +-
 optee-utee/src/object/object_define.rs          |  6 +--
 optee-utee/src/object/object_info.rs            |  2 +-
 optee-utee/src/object/persistent_object.rs      |  2 +-
 optee-utee/src/object/transient_object.rs       |  2 +-
 optee-utee/src/parameter.rs                     |  8 +++-
 optee-utee/src/property.rs                      | 64 +++++++++++++------------
 optee-utee/src/tee_parameter.rs                 | 10 ++--
 optee-utee/src/time.rs                          |  6 +++
 17 files changed, 123 insertions(+), 119 deletions(-)

diff --git a/.github/workflows/reuse_test.yml b/.github/workflows/reuse_test.yml
index 9272d6c..6980089 100644
--- a/.github/workflows/reuse_test.yml
+++ b/.github/workflows/reuse_test.yml
@@ -59,6 +59,9 @@ jobs:
           (cd optee-utee && cargo build --target aarch64-unknown-linux-gnu -vv)
           (cd optee-teec && cargo build --target aarch64-unknown-linux-gnu -vv)
 
+          # Clippy checks
+          (cd optee-utee && cargo clippy --target aarch64-unknown-linux-gnu -- -D warnings)
+
   # Cross-compile on host and run tests in QEMU
   #
   # Cross-compile target pairs:
diff --git a/optee-utee/macros/src/lib.rs b/optee-utee/macros/src/lib.rs
index 95142dd..ec667a5 100644
--- a/optee-utee/macros/src/lib.rs
+++ b/optee-utee/macros/src/lib.rs
@@ -40,10 +40,7 @@ pub fn ta_create(_args: TokenStream, input: TokenStream) -> TokenStream {
 
     // check the function signature
     let valid_signature = f.constness.is_none()
-        && match f.vis {
-            syn::Visibility::Inherited => true,
-            _ => false,
-        }
+        && matches!(f.vis, syn::Visibility::Inherited)
         && f.abi.is_none()
         && f.decl.inputs.is_empty()
         && f.decl.generics.where_clause.is_none()
@@ -87,18 +84,12 @@ pub fn ta_destroy(_args: TokenStream, input: TokenStream) -> TokenStream {
 
     // check the function signature
     let valid_signature = f.constness.is_none()
-        && match f.vis {
-            syn::Visibility::Inherited => true,
-            _ => false,
-        }
+        && matches!(f.vis, syn::Visibility::Inherited)
         && f.abi.is_none()
         && f.decl.inputs.is_empty()
         && f.decl.generics.where_clause.is_none()
         && f.decl.variadic.is_none()
-        && match f.decl.output {
-            syn::ReturnType::Default => true,
-            _ => false,
-        };
+        && matches!(f.decl.output, syn::ReturnType::Default);
 
     if !valid_signature {
         return syn::parse::Error::new(
@@ -141,10 +132,7 @@ pub fn ta_open_session(_args: TokenStream, input: TokenStream) -> TokenStream {
 
     // check the function signature
     let valid_signature = f.constness.is_none()
-        && match f.vis {
-            syn::Visibility::Inherited => true,
-            _ => false,
-        }
+        && matches!(f.vis, syn::Visibility::Inherited)
         && f.abi.is_none()
         && (f.decl.inputs.len() == 1 || f.decl.inputs.len() == 2)
         && f.decl.generics.where_clause.is_none()
@@ -184,12 +172,12 @@ pub fn ta_open_session(_args: TokenStream, input: TokenStream) -> TokenStream {
                 .inputs
                 .iter()
                 .map(|arg| match arg {
-                    &syn::FnArg::Captured(ref val) => &val.ty,
+                    syn::FnArg::Captured(val) => &val.ty,
                     _ => unreachable!(),
                 })
                 .collect();
             let ctx_type = match input_types.last().unwrap() {
-                &syn::Type::Reference(ref r) => &r.elem,
+                syn::Type::Reference(r) => &r.elem,
                 _ => unreachable!(),
             };
 
@@ -241,18 +229,12 @@ pub fn ta_close_session(_args: TokenStream, input: TokenStream) -> TokenStream {
 
     // check the function signature
     let valid_signature = f.constness.is_none()
-        && match f.vis {
-            syn::Visibility::Inherited => true,
-            _ => false,
-        }
+        && matches!(f.vis, syn::Visibility::Inherited)
         && f.abi.is_none()
-        && (f.decl.inputs.len() == 0 || f.decl.inputs.len() == 1)
+        && (f.decl.inputs.is_empty() || f.decl.inputs.len() == 1)
         && f.decl.generics.where_clause.is_none()
         && f.decl.variadic.is_none()
-        && match f.decl.output {
-            syn::ReturnType::Default => true,
-            _ => false,
-        };
+        && matches!(f.decl.output, syn::ReturnType::Default);
 
     if !valid_signature {
         return syn::parse::Error::new(
@@ -279,12 +261,12 @@ pub fn ta_close_session(_args: TokenStream, input: TokenStream) -> TokenStream {
                 .inputs
                 .iter()
                 .map(|arg| match arg {
-                    &syn::FnArg::Captured(ref val) => &val.ty,
+                    syn::FnArg::Captured(val) => &val.ty,
                     _ => unreachable!(),
                 })
                 .collect();
             let t = match input_types.first().unwrap() {
-                &syn::Type::Reference(ref r) => &r.elem,
+                syn::Type::Reference(r) => &r.elem,
                 _ => unreachable!(),
             };
 
@@ -328,10 +310,7 @@ pub fn ta_invoke_command(_args: TokenStream, input: TokenStream) -> TokenStream
 
     // check the function signature
     let valid_signature = f.constness.is_none()
-        && match f.vis {
-            syn::Visibility::Inherited => true,
-            _ => false,
-        }
+        && matches!(f.vis, syn::Visibility::Inherited)
         && f.abi.is_none()
         && (f.decl.inputs.len() == 2 || f.decl.inputs.len() == 3)
         && f.decl.generics.where_clause.is_none()
@@ -373,12 +352,12 @@ pub fn ta_invoke_command(_args: TokenStream, input: TokenStream) -> TokenStream
                 .inputs
                 .iter()
                 .map(|arg| match arg {
-                    &syn::FnArg::Captured(ref val) => &val.ty,
+                    syn::FnArg::Captured(val) => &val.ty,
                     _ => unreachable!(),
                 })
                 .collect();
             let t = match input_types.first().unwrap() {
-                &syn::Type::Reference(ref r) => &r.elem,
+                syn::Type::Reference(r) => &r.elem,
                 _ => unreachable!(),
             };
 
diff --git a/optee-utee/optee-utee-sys/src/user_ta_header.rs b/optee-utee/optee-utee-sys/src/user_ta_header.rs
index bc5f8de..0d0c7eb 100644
--- a/optee-utee/optee-utee-sys/src/user_ta_header.rs
+++ b/optee-utee/optee-utee-sys/src/user_ta_header.rs
@@ -41,11 +41,17 @@ extern "C" {
     pub fn __utee_entry(func: c_ulong, session_id: c_ulong, up: *mut utee_params, cmd_id: c_ulong) -> TEE_Result;
 }
 
+/// # Safety
+/// This function is the main entry point for a Trusted Application (TA) in OP-TEE.
+/// It must only be called by the OP-TEE OS with valid parameters. The `up` parameter
+/// is a raw pointer that must point to a valid `utee_params` structure initialized
+/// by the OP-TEE runtime environment. This function should never be called directly
+/// from user code - it is only exported for the OP-TEE OS loader.
 #[no_mangle]
-pub fn __ta_entry(func: c_ulong, session_id: c_ulong, up: *mut utee_params, cmd_id: c_ulong) -> ! {
-    let res: u32 = unsafe { __utee_entry(func, session_id, up, cmd_id) };
+unsafe fn __ta_entry(func: c_ulong, session_id: c_ulong, up: *mut utee_params, cmd_id: c_ulong) -> ! {
+    let res: u32 = __utee_entry(func, session_id, up, cmd_id);
 
-    unsafe { _utee_return(res.into()) };
+    _utee_return(res.into());
 }
 
 unsafe impl Sync for ta_head {}
diff --git a/optee-utee/src/arithmetical.rs b/optee-utee/src/arithmetical.rs
index ecb3ade..259898e 100644
--- a/optee-utee/src/arithmetical.rs
+++ b/optee-utee/src/arithmetical.rs
@@ -34,13 +34,13 @@ impl BigInt {
 
     // size represents BigInt bits
     pub fn size_in_u32(size: u32) -> u32 {
-        return ((size + 31) / 32) + 2;
+        ((size + 31) / 32) + 2
     }
 
     pub fn new(bits: u32) -> Self {
         let size: usize = Self::size_in_u32(bits) as usize;
         let mut tmp_vec: Vec<BigIntUnit> = vec![0; size];
-        unsafe { raw::TEE_BigIntInit(tmp_vec.as_mut_ptr(), size as usize) };
+        unsafe { raw::TEE_BigIntInit(tmp_vec.as_mut_ptr(), size) };
         Self(tmp_vec)
     }
 
@@ -49,7 +49,7 @@ impl BigInt {
             raw::TEE_BigIntConvertFromOctetString(
                 self.0.as_mut_ptr(),
                 buffer.as_ptr(),
-                buffer.len() as usize,
+                buffer.len(),
                 sign,
             )
         } {
@@ -70,7 +70,7 @@ impl BigInt {
         } {
             raw::TEE_SUCCESS => {
                 tmp_vec.truncate(buffer_size);
-                return Ok(tmp_vec);
+                Ok(tmp_vec)
             }
             code => Err(Error::from_raw_error(code)),
         }
@@ -272,7 +272,7 @@ impl BigIntFMMContext {
 
     // Globalplatform define FMMContext1 here while OP-TEE does not update yet
     pub fn new(bits: u32, modulus: BigInt) -> Result<Self> {
-        let size: usize = Self::size_in_u32(bits as usize) as usize;
+        let size: usize = Self::size_in_u32(bits as usize);
         let mut tmp_vec: Vec<BigIntFMMContextUnit> = vec![0; size];
         unsafe {
             raw::TEE_BigIntInitFMMContext(tmp_vec.as_mut_ptr(), size, modulus.data_ptr())
@@ -293,7 +293,7 @@ impl BigIntFMM {
     }
 
     pub fn new(bits: u32) -> Self {
-        let size: usize = Self::size_in_u32(bits as usize) as usize;
+        let size: usize = Self::size_in_u32(bits as usize);
         let mut tmp_vec: Vec<BigIntFMMUnit> = vec![0; size];
         unsafe { raw::TEE_BigIntInitFMM(tmp_vec.as_mut_ptr(), size) };
         Self(tmp_vec)
diff --git a/optee-utee/src/crypto_op.rs b/optee-utee/src/crypto_op.rs
index 17cafad..260c2ce 100644
--- a/optee-utee/src/crypto_op.rs
+++ b/optee-utee/src/crypto_op.rs
@@ -217,7 +217,7 @@ impl OperationHandle {
 
     fn set_key<T: GenericObject>(&self, object: &T) -> Result<()> {
         match unsafe { raw::TEE_SetOperationKey(self.handle(), object.handle()) } {
-            raw::TEE_SUCCESS => return Ok(()),
+            raw::TEE_SUCCESS => Ok(()),
             code => Err(Error::from_raw_error(code)),
         }
     }
@@ -243,7 +243,7 @@ pub fn is_algorithm_supported(alg_id: u32, element: u32) -> Result<()> {
 impl Drop for OperationHandle {
     fn drop(&mut self) {
         unsafe {
-            if self.raw != ptr::null_mut() {
+            if !self.raw.is_null() {
                 raw::TEE_FreeOperation(self.handle());
             }
             drop(Box::from_raw(self.raw));
@@ -336,7 +336,7 @@ impl Digest {
                 &mut hash_size,
             )
         } {
-            raw::TEE_SUCCESS => return Ok(hash_size),
+            raw::TEE_SUCCESS => Ok(hash_size),
             code => Err(Error::from_raw_error(code)),
         }
     }
@@ -622,7 +622,7 @@ impl Cipher {
             )
         } {
             raw::TEE_SUCCESS => {
-                return Ok(dest_size as usize);
+                Ok(dest_size)
             }
             code => Err(Error::from_raw_error(code)),
         }
@@ -657,7 +657,7 @@ impl Cipher {
                 &mut dest_size,
             )
         } {
-            raw::TEE_SUCCESS => return Ok(dest_size as usize),
+            raw::TEE_SUCCESS => Ok(dest_size),
             code => Err(Error::from_raw_error(code)),
         }
     }
@@ -746,7 +746,7 @@ impl Cipher {
         match unsafe {
             raw::TEE_SetOperationKey2(self.handle(), object1.handle(), object2.handle())
         } {
-            raw::TEE_SUCCESS => return Ok(()),
+            raw::TEE_SUCCESS => Ok(()),
             code => Err(Error::from_raw_error(code)),
         }
     }
@@ -1008,7 +1008,7 @@ impl AE {
                 pay_load_len,
             )
         } {
-            raw::TEE_SUCCESS => return Ok(()),
+            raw::TEE_SUCCESS => Ok(()),
             code => Err(Error::from_raw_error(code)),
         }
     }
@@ -1068,7 +1068,7 @@ impl AE {
             )
         } {
             raw::TEE_SUCCESS => {
-                return Ok(dest_size);
+                Ok(dest_size)
             }
             code => Err(Error::from_raw_error(code)),
         }
@@ -1156,7 +1156,7 @@ impl AE {
             )
         } {
             raw::TEE_SUCCESS => {
-                return Ok((dest_size, tag_size));
+                Ok((dest_size, tag_size))
             }
             code => Err(Error::from_raw_error(code)),
         }
@@ -1199,7 +1199,7 @@ impl AE {
             )
         } {
             raw::TEE_SUCCESS => {
-                return Ok(dest_size);
+                Ok(dest_size)
             }
             code => Err(Error::from_raw_error(code)),
         }
@@ -1314,7 +1314,7 @@ impl Asymmetric {
     pub fn encrypt(&self, params: &[Attribute], src: &[u8]) -> Result<Vec<u8>> {
         let p: Vec<raw::TEE_Attribute> = params.iter().map(|p| p.raw()).collect();
         let mut res_size: usize = self.info().key_size() as usize;
-        let mut res_vec: Vec<u8> = vec![0u8; res_size as usize];
+        let mut res_vec: Vec<u8> = vec![0u8; res_size];
         match unsafe {
             raw::TEE_AsymmetricEncrypt(
                 self.handle(),
@@ -1328,7 +1328,7 @@ impl Asymmetric {
         } {
             raw::TEE_SUCCESS => {
                 res_vec.truncate(res_size);
-                return Ok(res_vec);
+                Ok(res_vec)
             }
             code => Err(Error::from_raw_error(code)),
         }
@@ -1357,7 +1357,7 @@ impl Asymmetric {
     pub fn decrypt(&self, params: &[Attribute], src: &[u8]) -> Result<Vec<u8>> {
         let p: Vec<raw::TEE_Attribute> = params.iter().map(|p| p.raw()).collect();
         let mut res_size: usize = self.info().key_size() as usize;
-        let mut res_vec: Vec<u8> = vec![0u8; res_size as usize];
+        let mut res_vec: Vec<u8> = vec![0u8; res_size];
         match unsafe {
             raw::TEE_AsymmetricDecrypt(
                 self.handle(),
@@ -1370,8 +1370,8 @@ impl Asymmetric {
             )
         } {
             raw::TEE_SUCCESS => {
-                res_vec.truncate(res_size as usize);
-                return Ok(res_vec);
+                res_vec.truncate(res_size);
+                Ok(res_vec)
             }
             code => Err(Error::from_raw_error(code)),
         }
@@ -1418,7 +1418,7 @@ impl Asymmetric {
             )
         } {
             raw::TEE_SUCCESS => {
-                return Ok(signature_size);
+                Ok(signature_size)
             }
             code => Err(Error::from_raw_error(code)),
         }
@@ -1537,7 +1537,7 @@ impl DeriveKey {
     ///         key_pair_1.generate_key(256, &[attr_prime.into(), attr_base.into()])?;
     ///         key_pair_1.ref_attribute(AttributeId::DhPublicValue, &mut public_1)?;
     ///         Ok(())
-    ///     },
+    ///     }
     ///     Err(e) => Err(e),
     /// }
     /// # }
diff --git a/optee-utee/src/error.rs b/optee-utee/src/error.rs
index fabf6ca..35f69d0 100644
--- a/optee-utee/src/error.rs
+++ b/optee-utee/src/error.rs
@@ -288,12 +288,12 @@ impl From<ErrorKind> for Error {
 #[derive(Clone, Debug, Default, Eq, PartialEq)]
 #[repr(u32)]
 pub enum ErrorOrigin {
-    API = raw::TEE_ORIGIN_API,
-    COMMS = raw::TEE_ORIGIN_COMMS,
-    TEE = raw::TEE_ORIGIN_TEE,
-    TA = raw::TEE_ORIGIN_TRUSTED_APP,
+    Api = raw::TEE_ORIGIN_API,
+    Comms = raw::TEE_ORIGIN_COMMS,
+    Tee = raw::TEE_ORIGIN_TEE,
+    Ta = raw::TEE_ORIGIN_TRUSTED_APP,
     #[default]
-    UNKNOWN,
+    Unknown,
 }
 
 impl From<ErrorOrigin> for u32 {
@@ -305,11 +305,11 @@ impl From<ErrorOrigin> for u32 {
 impl From<u32> for ErrorOrigin {
     fn from(code: u32) -> ErrorOrigin {
         match code {
-            raw::TEE_ORIGIN_API => ErrorOrigin::API,
-            raw::TEE_ORIGIN_COMMS => ErrorOrigin::COMMS,
-            raw::TEE_ORIGIN_TEE => ErrorOrigin::TEE,
-            raw::TEE_ORIGIN_TRUSTED_APP => ErrorOrigin::TA,
-            _ => ErrorOrigin::UNKNOWN,
+            raw::TEE_ORIGIN_API => ErrorOrigin::Api,
+            raw::TEE_ORIGIN_COMMS => ErrorOrigin::Comms,
+            raw::TEE_ORIGIN_TEE => ErrorOrigin::Tee,
+            raw::TEE_ORIGIN_TRUSTED_APP => ErrorOrigin::Ta,
+            _ => ErrorOrigin::Unknown,
         }
     }
 }
diff --git a/optee-utee/src/extension.rs b/optee-utee/src/extension.rs
index 175053a..50e86b6 100644
--- a/optee-utee/src/extension.rs
+++ b/optee-utee/src/extension.rs
@@ -110,12 +110,12 @@ impl LoadablePlugin {
     /// # }
     /// ```
     /// Notice: the shared buffer could grow to fit the request data automatically.
-    pub fn invoke_with_capacity<'a>(
-        &'a self,
+    pub fn invoke_with_capacity(
+        &self,
         command_id: u32,
         subcommand_id: u32,
         capacity: usize,
-    ) -> LoadablePluginCommand<'a> {
+    ) -> LoadablePluginCommand<'_> {
         LoadablePluginCommand::new_with_capacity(self, command_id, subcommand_id, capacity)
     }
 }
diff --git a/optee-utee/src/net/optee.rs b/optee-utee/src/net/optee.rs
index b198319..a7bbb58 100644
--- a/optee-utee/src/net/optee.rs
+++ b/optee-utee/src/net/optee.rs
@@ -110,7 +110,7 @@ impl SocketAdapter for TcpAdapter {
         let ret = unsafe {
             ((*raw::TEE_tcpSocket).send)(
                 handle.0,
-                buf.as_ptr() as *const u8 as _,
+                buf.as_ptr() as _,
                 &mut length,
                 timeout,
             )
@@ -170,7 +170,7 @@ impl SocketAdapter for UdpAdapter {
         let ret = unsafe {
             ((*raw::TEE_udpSocket).send)(
                 handle.0,
-                buf.as_ptr() as *const u8 as _,
+                buf.as_ptr() as _,
                 &mut length,
                 timeout,
             )
diff --git a/optee-utee/src/object/attribute.rs b/optee-utee/src/object/attribute.rs
index caa8e07..91ed92c 100644
--- a/optee-utee/src/object/attribute.rs
+++ b/optee-utee/src/object/attribute.rs
@@ -66,7 +66,7 @@ impl<'attrref> AttributeMemref<'attrref> {
             attributeID: 0,
             content: raw::content {
                 memref: raw::Memref {
-                    buffer: 0 as *mut _,
+                    buffer: core::ptr::null_mut(),
                     size: 0,
                 },
             },
diff --git a/optee-utee/src/object/object_define.rs b/optee-utee/src/object/object_define.rs
index a5586ae..88eac28 100644
--- a/optee-utee/src/object/object_define.rs
+++ b/optee-utee/src/object/object_define.rs
@@ -29,9 +29,9 @@ pub enum Whence {
     DataSeekEnd,
 }
 
-impl Into<raw::TEE_Whence> for Whence {
-    fn into(self) -> raw::TEE_Whence {
-        match self {
+impl From<Whence> for raw::TEE_Whence {
+    fn from(val: Whence) -> Self {
+        match val {
             Whence::DataSeekSet => raw::TEE_Whence::TEE_DATA_SEEK_SET,
             Whence::DataSeekCur => raw::TEE_Whence::TEE_DATA_SEEK_CUR,
             Whence::DataSeekEnd => raw::TEE_Whence::TEE_DATA_SEEK_END,
diff --git a/optee-utee/src/object/object_info.rs b/optee-utee/src/object/object_info.rs
index 33e6e17..59aea11 100644
--- a/optee-utee/src/object/object_info.rs
+++ b/optee-utee/src/object/object_info.rs
@@ -63,7 +63,7 @@ impl ObjectInfo {
 
     /// Return the `dataSize` field of the raw structure `TEE_ObjectInfo`.
     pub fn data_size(&self) -> usize {
-        self.raw.dataSize as usize
+        self.raw.dataSize
     }
 
     /// Return the `objectSize` field of the raw structure `TEE_ObjectInfo`.
diff --git a/optee-utee/src/object/persistent_object.rs b/optee-utee/src/object/persistent_object.rs
index 706ad10..35fbcec 100644
--- a/optee-utee/src/object/persistent_object.rs
+++ b/optee-utee/src/object/persistent_object.rs
@@ -262,7 +262,7 @@ impl PersistentObject {
         // So we must forget the raw_handle to prevent calling TEE_CloseObject
         // on it (no matter the result of TEE_CloseAndDeletePersistentObject1).
         self.0.forget();
-        return result;
+        result
     }
 
     /// Changes the identifier of an object.
diff --git a/optee-utee/src/object/transient_object.rs b/optee-utee/src/object/transient_object.rs
index 44f985f..f0f5794 100644
--- a/optee-utee/src/object/transient_object.rs
+++ b/optee-utee/src/object/transient_object.rs
@@ -253,7 +253,7 @@ impl TransientObject {
             raw::TEE_PopulateTransientObject(self.0.handle(), p.as_ptr() as _, attrs.len() as u32)
         } {
             raw::TEE_SUCCESS => Ok(()),
-            code => return Err(Error::from_raw_error(code)),
+            code => Err(Error::from_raw_error(code)),
         }
     }
 
diff --git a/optee-utee/src/parameter.rs b/optee-utee/src/parameter.rs
index 02b771a..120fe92 100644
--- a/optee-utee/src/parameter.rs
+++ b/optee-utee/src/parameter.rs
@@ -74,7 +74,7 @@ pub struct ParamMemref<'parameter> {
 impl<'parameter> ParamMemref<'parameter> {
     pub fn buffer(&mut self) -> &mut [u8] {
         unsafe {
-            slice::from_raw_parts_mut((*self.raw).buffer as *mut u8, (*self.raw).size as usize)
+            slice::from_raw_parts_mut((*self.raw).buffer as *mut u8, (*self.raw).size)
         }
     }
 
@@ -100,10 +100,12 @@ impl Parameter {
     pub fn from_raw(ptr: *mut raw::TEE_Param, param_type: ParamType) -> Self {
         Self {
             raw: ptr,
-            param_type: param_type,
+            param_type,
         }
     }
 
+    /// # Safety
+    /// The caller must ensure that the raw pointer is valid and points to a properly initialized TEE_Param.
     pub unsafe fn as_value(&mut self) -> Result<ParamValue> {
         match self.param_type {
             ParamType::ValueInput | ParamType::ValueInout | ParamType::ValueOutput => {
@@ -117,6 +119,8 @@ impl Parameter {
         }
     }
 
+    /// # Safety
+    /// The caller must ensure that the raw pointer is valid and points to a properly initialized TEE_Param.
     pub unsafe fn as_memref(&mut self) -> Result<ParamMemref> {
         match self.param_type {
             ParamType::MemrefInout | ParamType::MemrefInput | ParamType::MemrefOutput => {
diff --git a/optee-utee/src/property.rs b/optee-utee/src/property.rs
index 2a033a1..bcab863 100644
--- a/optee-utee/src/property.rs
+++ b/optee-utee/src/property.rs
@@ -46,18 +46,22 @@ impl PropertySet {
 /// The property value is obtained from the TEE
 /// property set using the TEE_GetPropertyAs* functions.
 pub trait PropertyValue: Sized {
-    fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self>;
+    /// # Safety
+    /// This function is unsafe because it dereferences raw pointers from the TEE API.
+    /// The caller must ensure that the `set` handle is valid and that the TEE environment
+    /// is properly initialized.
+    unsafe fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self>;
 }
 
 /// Implements the PropertyValue trait for all return types:
 /// String, Bool, u32, u64, BinaryBlock, UUID, Identity.
 impl PropertyValue for String {
-    fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
+    unsafe fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
         let mut out_size = 0;
 
         // The first call is to get the size of the string
         // So we pass a null pointer and a size of 0
-        let res = unsafe {
+        let res = {
             raw::TEE_GetPropertyAsString(
                 set,
                 key.as_ptr() as *const core::ffi::c_char,
@@ -69,16 +73,16 @@ impl PropertyValue for String {
             raw::TEE_SUCCESS => {
                 if out_size == 0 {
                     // return an empty string
-                    return Ok(String::new());
+                    Ok(String::new())
                 }
                 else {
-                    return Err(Error::new(ErrorKind::Generic));
+                    Err(Error::new(ErrorKind::Generic))
                 }
             }
             raw::TEE_ERROR_SHORT_BUFFER => {
                 // Resize the string to the actual size
-                let mut out_buffer = vec![0; out_size as usize];
-                let res = unsafe {
+                let mut out_buffer = vec![0; out_size];
+                let res = {
                     raw::TEE_GetPropertyAsString(
                         set,
                         key.as_ptr() as *const core::ffi::c_char,
@@ -99,17 +103,17 @@ impl PropertyValue for String {
                 Ok(result)
             }
             _ => {
-                return Err(Error::from_raw_error(res));
+                Err(Error::from_raw_error(res))
             }
         }
     }
 }
 
 impl PropertyValue for bool {
-    fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
+    unsafe fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
         let mut b: bool = false;
 
-        let res = unsafe { raw::TEE_GetPropertyAsBool(set, key.as_ptr() as *const core::ffi::c_char, &mut b) };
+        let res = raw::TEE_GetPropertyAsBool(set, key.as_ptr() as *const core::ffi::c_char, &mut b);
         if res != 0 {
             return Err(Error::from_raw_error(res));
         }
@@ -119,10 +123,10 @@ impl PropertyValue for bool {
 }
 
 impl PropertyValue for u32 {
-    fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
+    unsafe fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
         let mut value = 0;
 
-        let res = unsafe { raw::TEE_GetPropertyAsU32(set, key.as_ptr() as *const core::ffi::c_char, &mut value) };
+        let res = raw::TEE_GetPropertyAsU32(set, key.as_ptr() as *const core::ffi::c_char, &mut value);
         if res != 0 {
             return Err(Error::from_raw_error(res));
         }
@@ -132,10 +136,10 @@ impl PropertyValue for u32 {
 }
 
 impl PropertyValue for u64 {
-    fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
+    unsafe fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
         let mut value = 0;
 
-        let res = unsafe { raw::TEE_GetPropertyAsU64(set, key.as_ptr() as *const core::ffi::c_char, &mut value) };
+        let res = raw::TEE_GetPropertyAsU64(set, key.as_ptr() as *const core::ffi::c_char, &mut value);
         if res != 0 {
             return Err(Error::from_raw_error(res));
         }
@@ -145,12 +149,12 @@ impl PropertyValue for u64 {
 }
 
 impl PropertyValue for Vec<u8> {
-    fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
+    unsafe fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
         let mut out_size = 0;
 
         // The first call is to get the size of the binary block
         // So we pass a null pointer and a size of 0
-        let res = unsafe {
+        let res = {
             raw::TEE_GetPropertyAsBinaryBlock(
                 set,
                 key.as_ptr() as *const core::ffi::c_char,
@@ -163,16 +167,16 @@ impl PropertyValue for Vec<u8> {
             raw::TEE_SUCCESS => {
                 if out_size == 0 {
                     // return an empty buffer
-                    return Ok(vec![]);
+                    Ok(vec![])
                 }
                 else {
-                    return Err(Error::new(ErrorKind::Generic));
+                    Err(Error::new(ErrorKind::Generic))
                 }
             }
             raw::TEE_ERROR_SHORT_BUFFER => {
-                let mut buf = vec![0; out_size as usize];
+                let mut buf = vec![0; out_size];
 
-                let res = unsafe {
+                let res = {
                     raw::TEE_GetPropertyAsBinaryBlock(
                         set,
                         key.as_ptr() as *const core::ffi::c_char,
@@ -181,20 +185,20 @@ impl PropertyValue for Vec<u8> {
                     )
                 };
                 if res != raw::TEE_SUCCESS {
-                    return Err(Error::from_raw_error(res));
+                    Err(Error::from_raw_error(res))
+                } else {
+                    Ok(buf)
                 }
-
-                Ok(buf)
             }
             _ => {
-                return Err(Error::from_raw_error(res));
+                Err(Error::from_raw_error(res))
             }
         }
     }
 }
 
 impl PropertyValue for Uuid {
-    fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
+    unsafe fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
         let mut raw_uuid = raw::TEE_UUID {
             timeLow: 0,
             timeMid: 0,
@@ -203,7 +207,7 @@ impl PropertyValue for Uuid {
         };
 
         let res =
-            unsafe { raw::TEE_GetPropertyAsUUID(set, key.as_ptr() as *const core::ffi::c_char, &mut raw_uuid) };
+            raw::TEE_GetPropertyAsUUID(set, key.as_ptr() as *const core::ffi::c_char, &mut raw_uuid);
         if res != 0 {
             return Err(Error::from_raw_error(res));
         }
@@ -213,7 +217,7 @@ impl PropertyValue for Uuid {
 }
 
 impl PropertyValue for Identity {
-    fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
+    unsafe fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
         // Allocate a buffer for the raw identity
         let mut raw_id = raw::TEE_Identity {
             login: 0,
@@ -225,9 +229,7 @@ impl PropertyValue for Identity {
             },
         };
 
-        let res = unsafe {
-            raw::TEE_GetPropertyAsIdentity(set, key.as_ptr() as *const core::ffi::c_char, &mut raw_id)
-        };
+        let res = raw::TEE_GetPropertyAsIdentity(set, key.as_ptr() as *const core::ffi::c_char, &mut raw_id);
         if res != 0 {
             return Err(Error::from_raw_error(res));
         }
@@ -248,7 +250,7 @@ pub trait PropertyKey {
     fn set(&self) -> PropertySet;
 
     fn get(&self) -> Result<Self::Output> {
-        Self::Output::from_raw(self.set().as_raw(), self.key())
+        unsafe { Self::Output::from_raw(self.set().as_raw(), self.key()) }
     }
 }
 
diff --git a/optee-utee/src/tee_parameter.rs b/optee-utee/src/tee_parameter.rs
index 55a00e6..bce51c6 100644
--- a/optee-utee/src/tee_parameter.rs
+++ b/optee-utee/src/tee_parameter.rs
@@ -176,9 +176,7 @@ impl<'a> Param<'a> {
                 *written = new_size;
                 Ok(())
             }
-            _ => {
-                return Err(Error::new(ErrorKind::BadFormat));
-            }
+            _ => Err(Error::new(ErrorKind::BadFormat)),
         }
     }
 
@@ -214,6 +212,12 @@ pub struct TeeParams<'a> {
     params: [Param<'a>; 4],
 }
 
+impl<'a> Default for TeeParams<'a> {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl<'a> TeeParams<'a> {
     pub fn new() -> Self {
         Self {
diff --git a/optee-utee/src/time.rs b/optee-utee/src/time.rs
index 47d64c7..2a27a54 100644
--- a/optee-utee/src/time.rs
+++ b/optee-utee/src/time.rs
@@ -27,6 +27,12 @@ pub struct Time {
     pub millis: u32,
 }
 
+impl Default for Time {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl Time {
     /// Create a new empty time structure.
     pub fn new() -> Self {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org


(teaclave-trustzone-sdk) 02/03: optee-teec: clippy default enforcement

Posted by yu...@apache.org.
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