This is an automated email from the ASF dual-hosted git repository.
ivila pushed a commit to branch main
in repository
https://gitbox.apache.org/repos/asf/incubator-teaclave-trustzone-sdk.git
The following commit(s) were added to refs/heads/main by this push:
new 7dac025 optee_teec: extension: fix macro errors
7dac025 is described below
commit 7dac0250001338cd1196347bac6a45ebbfc74ca3
Author: ivila <[email protected]>
AuthorDate: Tue Mar 25 16:21:09 2025 +0800
optee_teec: extension: fix macro errors
* Fix usage of Rust types as return values in FFI functions.
* Standardize the function signature to require returning a Result.
* Use inner functions in generated code to prevent unexpected early returns.
* Fix example: supp_plugin-rs.
Signed-off-by: Zehui Chen <[email protected]>
Reviewed-by: Yuan Zhuang <[email protected]>
---
examples/supp_plugin-rs/host/src/main.rs | 10 +--
examples/supp_plugin-rs/plugin/Cargo.toml | 3 +-
examples/supp_plugin-rs/plugin/build.rs | 5 +-
examples/supp_plugin-rs/plugin/plugin_static.rs | 4 +-
examples/supp_plugin-rs/plugin/src/lib.rs | 34 ++++++----
examples/supp_plugin-rs/proto/src/lib.rs | 4 +-
examples/supp_plugin-rs/ta/build.rs | 3 +-
examples/supp_plugin-rs/ta/src/main.rs | 32 ++++++----
optee-teec/macros/Cargo.toml | 4 +-
optee-teec/macros/src/lib.rs | 85 +++++++++++++++++--------
optee-teec/src/context.rs | 8 +--
optee-teec/src/error.rs | 2 +-
optee-teec/src/extension.rs | 10 +--
optee-teec/src/lib.rs | 3 +
optee-teec/src/operation.rs | 6 +-
optee-teec/src/parameter.rs | 5 +-
optee-teec/src/session.rs | 11 ++--
optee-teec/src/uuid.rs | 2 +-
18 files changed, 137 insertions(+), 94 deletions(-)
diff --git a/examples/supp_plugin-rs/host/src/main.rs
b/examples/supp_plugin-rs/host/src/main.rs
index a60a265..1182c04 100644
--- a/examples/supp_plugin-rs/host/src/main.rs
+++ b/examples/supp_plugin-rs/host/src/main.rs
@@ -15,9 +15,8 @@
// specific language governing permissions and limitations
// under the License.
-use optee_teec::{Context, Operation, ParamTmpRef, Session, Uuid};
-use optee_teec::{ParamNone};
-use proto::{TA_UUID, Command};
+use optee_teec::{Context, ErrorKind, Operation, ParamNone, ParamTmpRef,
Session, Uuid};
+use proto::{Command, TA_UUID};
fn ping_ta(session: &mut Session) -> optee_teec::Result<()> {
let test_data = [0x36u8; 10];
@@ -34,7 +33,10 @@ fn ping_ta(session: &mut Session) -> optee_teec::Result<()> {
fn main() -> optee_teec::Result<()> {
let mut ctx = Context::new()?;
- let uuid = Uuid::parse_str(TA_UUID).unwrap();
+ let uuid = Uuid::parse_str(TA_UUID).map_err(|err| {
+ println!("Invalid TA_UUID: {:?}", err);
+ ErrorKind::BadParameters
+ })?;
let mut session = ctx.open_session(uuid)?;
ping_ta(&mut session)?;
diff --git a/examples/supp_plugin-rs/plugin/Cargo.toml
b/examples/supp_plugin-rs/plugin/Cargo.toml
index fab6ae2..e6c3f88 100644
--- a/examples/supp_plugin-rs/plugin/Cargo.toml
+++ b/examples/supp_plugin-rs/plugin/Cargo.toml
@@ -28,9 +28,8 @@ edition = "2018"
libc = "0.2.48"
proto = { path = "../proto" }
optee-teec = { path = "../../../optee-teec" }
-optee-teec-sys = { path = "../../../optee-teec/optee-teec-sys" }
-[build_dependencies]
+[build-dependencies]
uuid = { version = "0.8" }
proto = { path = "../proto" }
diff --git a/examples/supp_plugin-rs/plugin/build.rs
b/examples/supp_plugin-rs/plugin/build.rs
index 434f52d..3f01ec7 100644
--- a/examples/supp_plugin-rs/plugin/build.rs
+++ b/examples/supp_plugin-rs/plugin/build.rs
@@ -15,11 +15,10 @@
// specific language governing permissions and limitations
// under the License.
-use proto;
use std::env;
use std::fs::File;
use std::io::Write;
-use std::path::{PathBuf};
+use std::path::PathBuf;
use uuid::Uuid;
fn main() -> std::io::Result<()> {
@@ -33,7 +32,7 @@ fn main() -> std::io::Result<()> {
write!(buffer, "\n")?;
write!(
buffer,
- "const PLUGIN_UUID_STRUCT: optee_teec_sys::TEEC_UUID =
optee_teec_sys::TEEC_UUID {{
+ "const PLUGIN_UUID_STRUCT: optee_teec::raw::TEEC_UUID =
optee_teec::raw::TEEC_UUID {{
timeLow: {:#x},
timeMid: {:#x},
timeHiAndVersion: {:#x},
diff --git a/examples/supp_plugin-rs/plugin/plugin_static.rs
b/examples/supp_plugin-rs/plugin/plugin_static.rs
index 8a70d0a..2378e4f 100644
--- a/examples/supp_plugin-rs/plugin/plugin_static.rs
+++ b/examples/supp_plugin-rs/plugin/plugin_static.rs
@@ -16,8 +16,8 @@
// under the License.
#[no_mangle]
-pub static mut plugin_method: PluginMethod = PluginMethod {
- name: plugin_name.as_ptr() as *const c_char,
+pub static mut plugin_method: optee_teec::PluginMethod =
optee_teec::PluginMethod {
+ name: plugin_name.as_ptr(),
uuid: PLUGIN_UUID_STRUCT,
init: _plugin_init,
invoke: _plugin_invoke,
diff --git a/examples/supp_plugin-rs/plugin/src/lib.rs
b/examples/supp_plugin-rs/plugin/src/lib.rs
index 93fbf00..65ffe5d 100644
--- a/examples/supp_plugin-rs/plugin/src/lib.rs
+++ b/examples/supp_plugin-rs/plugin/src/lib.rs
@@ -15,30 +15,40 @@
// specific language governing permissions and limitations
// under the License.
-use libc::{c_char};
-use optee_teec::{PluginMethod, PluginParameters};
-use optee_teec::{plugin_init, plugin_invoke};
-use proto::{PluginCommand};
+use optee_teec::{plugin_init, plugin_invoke, ErrorKind, PluginParameters};
+use proto::PluginCommand;
#[plugin_init]
-fn init() {
- println!("*plugin*: init");
+fn init() -> optee_teec::Result<()> {
+ println!("*plugin*: init, version: {}", env!("CARGO_PKG_VERSION"));
+ Ok(())
}
#[plugin_invoke]
-fn invoke(params: &mut PluginParameters) {
+fn invoke(params: &mut PluginParameters) -> optee_teec::Result<()> {
println!("*plugin*: invoke");
match PluginCommand::from(params.cmd) {
PluginCommand::Print => {
- println!("*plugin*: receive value: {:?} length {:?}",
params.inout, params.inout.len());
+ println!(
+ "*plugin*: receive value: {:?} length {:?}",
+ params.inout,
+ params.inout.len()
+ );
- let send_slice: [u8;9] = [0x40;9];
+ let send_slice: [u8; 9] = [0x40; 9];
params.set_buf_from_slice(&send_slice)?;
- println!("*plugin*: send value: {:?} length {:?} to ta",
send_slice, send_slice.len());
+ println!(
+ "*plugin*: send value: {:?} length {:?} to ta",
+ send_slice,
+ send_slice.len()
+ );
+ Ok(())
+ }
+ _ => {
+ println!("Unsupported plugin command: {:?}", params.cmd);
+ Err(ErrorKind::BadParameters.into())
}
- _ => println!("Unsupported plugin command: {:?}", params.cmd),
}
}
-
include!(concat!(env!("OUT_DIR"), "/plugin_static.rs"));
diff --git a/examples/supp_plugin-rs/proto/src/lib.rs
b/examples/supp_plugin-rs/proto/src/lib.rs
index 1ac2e2d..f633644 100644
--- a/examples/supp_plugin-rs/proto/src/lib.rs
+++ b/examples/supp_plugin-rs/proto/src/lib.rs
@@ -27,7 +27,7 @@ pub enum Command {
}
// If Uuid::parse_str() returns an InvalidLength error, there may be an extra
-// newline in your uuid.txt file. You can remove it by running
+// newline in your uuid.txt file. You can remove it by running
// `truncate -s 36 ta_uuid.txt`.
pub const TA_UUID: &str = &include_str!("../../ta_uuid.txt");
@@ -42,6 +42,6 @@ pub enum PluginCommand {
pub const PLUGIN_SUBCMD_NULL: u32 = 0xFFFFFFFF;
// If Uuid::parse_str() returns an InvalidLength error, there may be an extra
-// newline in your uuid.txt file. You can remove it by running
+// newline in your uuid.txt file. You can remove it by running
// `truncate -s 36 plugin_uuid.txt`.
pub const PLUGIN_UUID: &str = &include_str!("../../plugin_uuid.txt");
diff --git a/examples/supp_plugin-rs/ta/build.rs
b/examples/supp_plugin-rs/ta/build.rs
index 9bc612a..84e72f7 100644
--- a/examples/supp_plugin-rs/ta/build.rs
+++ b/examples/supp_plugin-rs/ta/build.rs
@@ -15,8 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-use proto;
-use optee_utee_build::{TaConfig, RustEdition, Error};
+use optee_utee_build::{Error, RustEdition, TaConfig};
fn main() -> Result<(), Error> {
let ta_config = TaConfig::new_default_with_cargo_env(proto::TA_UUID)?;
diff --git a/examples/supp_plugin-rs/ta/src/main.rs
b/examples/supp_plugin-rs/ta/src/main.rs
index 7ae4853..d6d4d98 100644
--- a/examples/supp_plugin-rs/ta/src/main.rs
+++ b/examples/supp_plugin-rs/ta/src/main.rs
@@ -20,11 +20,11 @@
extern crate alloc;
+use optee_utee::LoadablePlugin;
use optee_utee::{
ta_close_session, ta_create, ta_destroy, ta_invoke_command,
ta_open_session, trace_println,
};
-use optee_utee::{Error, ErrorKind, Parameters, Result, Uuid};
-use optee_utee::{LoadablePlugin};
+use optee_utee::{ErrorKind, Parameters, Result, Uuid};
use proto::{Command, PluginCommand, PLUGIN_SUBCMD_NULL, PLUGIN_UUID};
#[ta_create]
@@ -52,26 +52,32 @@ fn destroy() {
#[ta_invoke_command]
fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
trace_println!("[+] TA invoke command");
- let mut p0 = unsafe { params.0.as_memref().unwrap() };
+ let mut p0 = unsafe { params.0.as_memref()? };
let inbuf = p0.buffer().to_vec();
- trace_println!("[+] TA received value {:?} then send to plugin",
p0.buffer());
- let uuid = Uuid::parse_str(PLUGIN_UUID).unwrap();
+ trace_println!(
+ "[+] TA received value {:?} then send to plugin",
+ p0.buffer()
+ );
+ let uuid = Uuid::parse_str(PLUGIN_UUID).map_err(|err| {
+ trace_println!("Invalid PluginUuid: {:?}", err);
+ ErrorKind::BadParameters
+ })?;
match Command::from(cmd_id) {
Command::Ping => {
- let mut plugin = LoadablePlugin::new(&uuid);
- let outbuf = plugin.invoke(
- PluginCommand::Print as u32,
- PLUGIN_SUBCMD_NULL,
- &inbuf
- ).unwrap();
+ let plugin = LoadablePlugin::new(&uuid);
+ let outbuf = plugin.invoke(PluginCommand::Print as u32,
PLUGIN_SUBCMD_NULL, &inbuf)?;
- trace_println!("[+] TA received out value {:?} outlen {:?}",
outbuf, outbuf.len());
+ trace_println!(
+ "[+] TA received out value {:?} outlen {:?}",
+ outbuf,
+ outbuf.len()
+ );
trace_println!("[+] TA call invoke_supp_plugin finished");
Ok(())
}
- _ => Err(Error::new(ErrorKind::BadParameters)),
+ _ => Err(ErrorKind::BadParameters.into()),
}
}
diff --git a/optee-teec/macros/Cargo.toml b/optee-teec/macros/Cargo.toml
index c1cbf1d..798414a 100644
--- a/optee-teec/macros/Cargo.toml
+++ b/optee-teec/macros/Cargo.toml
@@ -28,8 +28,8 @@ edition = "2018"
proc-macro = true
[dependencies]
-quote = "0.6"
-syn = { version = "0.15", features = ["full"] }
+quote = "1.0"
+syn = { version = "2.0", features = ["full"] }
# The newer versions of these crates require rustc 1.81, while our custom
# patched STD version is 1.80, causing compatibility issues. To resolve this,
diff --git a/optee-teec/macros/src/lib.rs b/optee-teec/macros/src/lib.rs
index edfe2c1..0c958bb 100644
--- a/optee-teec/macros/src/lib.rs
+++ b/optee-teec/macros/src/lib.rs
@@ -20,7 +20,7 @@
extern crate proc_macro;
use proc_macro::TokenStream;
-use quote::quote;
+use quote::{quote, ToTokens};
use syn::parse_macro_input;
use syn::spanned::Spanned;
@@ -34,38 +34,56 @@ pub fn plugin_init(_args: TokenStream, input: TokenStream)
-> TokenStream {
let f = parse_macro_input!(input as syn::ItemFn);
let f_vis = &f.vis;
let f_block = &f.block;
- let f_decl = &f.decl;
- let f_inputs = &f_decl.inputs;
+ let f_sig = &f.sig;
+ let f_inputs = &f_sig.inputs;
// check the function signature
- let valid_signature = f.constness.is_none()
+ let valid_signature = f_sig.constness.is_none()
&& match f_vis {
syn::Visibility::Inherited => true,
_ => false,
}
- && f.abi.is_none()
+ && f_sig.abi.is_none()
&& f_inputs.len() == 0
- && f.decl.generics.where_clause.is_none()
- && f.decl.variadic.is_none();
+ && f_sig.generics.where_clause.is_none()
+ && f_sig.variadic.is_none()
+ && check_return_type(&f);
if !valid_signature {
return syn::parse::Error::new(
f.span(),
- "`#[plugin_init]` function must have signature `fn()`",
+ "`#[plugin_init]` function must have signature `fn() ->
optee_teec::Result<()>`",
)
.to_compile_error()
.into();
}
quote!(
- #[no_mangle]
- pub fn _plugin_init() -> optee_teec::Result<()> {
- #f_block
- Ok(())
+ pub fn _plugin_init() -> optee_teec::raw::TEEC_Result {
+ fn inner() -> optee_teec::Result<()> {
+ #f_block
+ }
+ match inner() {
+ Ok(()) => optee_teec::raw::TEEC_SUCCESS,
+ Err(err) => err.raw_code(),
+ }
}
)
.into()
+}
+// check if return_type of the function is `optee_teec::Result<()>`
+fn check_return_type(item_fn: &syn::ItemFn) -> bool {
+ if let syn::ReturnType::Type(_, return_type) =
item_fn.sig.output.to_owned() {
+ if let syn::Type::Path(path) = return_type.as_ref() {
+ let expected_type = quote! { optee_teec::Result<()> };
+ let actual_type = path.path.to_token_stream();
+ if expected_type.to_string() == actual_type.to_string() {
+ return true;
+ }
+ }
+ }
+ return false;
}
/// Attribute to declare the invoke function of a plugin
@@ -78,50 +96,61 @@ pub fn plugin_invoke(_args: TokenStream, input:
TokenStream) -> TokenStream {
let f = parse_macro_input!(input as syn::ItemFn);
let f_vis = &f.vis;
let f_block = &f.block;
- let f_decl = &f.decl;
- let f_inputs = &f_decl.inputs;
+ let f_sig = &f.sig;
+ let f_inputs = &f_sig.inputs;
// check the function signature
- let valid_signature = f.constness.is_none()
+ let valid_signature = f_sig.constness.is_none()
&& match f_vis {
syn::Visibility::Inherited => true,
_ => false,
}
- && f.abi.is_none()
+ && f_sig.abi.is_none()
&& f_inputs.len() == 1
- && f.decl.generics.where_clause.is_none()
- && f.decl.variadic.is_none();
+ && f_sig.generics.where_clause.is_none()
+ && f_sig.variadic.is_none()
+ && check_return_type(&f);
if !valid_signature {
return syn::parse::Error::new(
f.span(),
- "`#[plugin_invoke]` function must have signature `fn(params: &mut
PluginParamters)`",
+ concat!(
+ "`#[plugin_invoke]` function must have signature",
+ " `fn(params: &mut PluginParameters) ->
optee_teec::Result<()>`"
+ ),
)
.to_compile_error()
.into();
}
+ let params = f_inputs
+ .first()
+ .expect("we have already verified its len")
+ .into_token_stream();
+
quote!(
- #[no_mangle]
pub fn _plugin_invoke(
cmd: u32,
sub_cmd: u32,
- data: *mut c_char,
+ data: *mut core::ffi::c_char,
in_len: u32,
out_len: *mut u32
- ) -> optee_teec::Result<()> {
+ ) -> optee_teec::raw::TEEC_Result {
+ 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 params = PluginParameters::new(cmd, sub_cmd, inbuf);
- #f_block
+ 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());
- }
-
- Ok(())
+ };
+ return optee_teec::raw::TEEC_SUCCESS;
}
)
.into()
-
}
diff --git a/optee-teec/src/context.rs b/optee-teec/src/context.rs
index 5f79124..4f37a10 100644
--- a/optee-teec/src/context.rs
+++ b/optee-teec/src/context.rs
@@ -15,10 +15,8 @@
// specific language governing permissions and limitations
// under the License.
-use crate::{Error, Operation, Result, Session, Uuid};
-use crate::{Param, ParamNone};
+use crate::{raw, Error, Operation, Param, ParamNone, Result, Session, Uuid};
use libc;
-use optee_teec_sys as raw;
use std::ptr;
/// An abstraction of the logical connection between a client application and a
@@ -44,7 +42,7 @@ impl Context {
/// # Examples
///
/// ```
- /// let raw_ctx: optee_teec_sys::TEEC_Context = Context::new_raw(0,
true).unwrap();
+ /// let raw_ctx: optee_teec::raw::TEEC_Context = Context::new_raw(0,
true).unwrap();
/// ```
pub fn new_raw(fd: libc::c_int, reg_mem: bool, memref_null: bool) ->
Result<raw::TEEC_Context> {
let mut raw_ctx = raw::TEEC_Context {
@@ -66,7 +64,7 @@ impl Context {
///
/// ```
/// let mut ctx = Context::new().unwrap();
- /// let mut raw_ptr: *mut optee_teec_sys::TEEC_Context =
ctx.as_mut_raw_ptr();
+ /// let mut raw_ptr: *mut optee_teec::raw::TEEC_Context =
ctx.as_mut_raw_ptr();
/// ```
pub fn as_mut_raw_ptr(&mut self) -> *mut raw::TEEC_Context {
&mut self.raw
diff --git a/optee-teec/src/error.rs b/optee-teec/src/error.rs
index f8a4380..d81b2d3 100644
--- a/optee-teec/src/error.rs
+++ b/optee-teec/src/error.rs
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-use optee_teec_sys as raw;
+use crate::raw;
use std::fmt;
/// A specialized
[`Result`](https://doc.rust-lang.org/std/result/enum.Result.html)
diff --git a/optee-teec/src/extension.rs b/optee-teec/src/extension.rs
index bac750f..b479ac6 100644
--- a/optee-teec/src/extension.rs
+++ b/optee-teec/src/extension.rs
@@ -15,22 +15,22 @@
// specific language governing permissions and limitations
// under the License.
-use optee_teec_sys as raw;
-use libc::{c_char};
-use crate::{Result, Error, ErrorKind};
+use crate::raw;
+use crate::{Error, ErrorKind, Result};
+use libc::c_char;
#[repr(C)]
pub struct PluginMethod {
pub name: *const c_char,
pub uuid: raw::TEEC_UUID,
- pub init: fn() -> Result<()>,
+ pub init: fn() -> raw::TEEC_Result,
pub invoke: fn(
cmd: u32,
sub_cmd: u32,
data: *mut c_char,
in_len: u32,
out_len: *mut u32,
- ) -> Result<()>,
+ ) -> raw::TEEC_Result,
}
/// struct PluginParameters {
diff --git a/optee-teec/src/lib.rs b/optee-teec/src/lib.rs
index 26ad2f7..b1e3aed 100644
--- a/optee-teec/src/lib.rs
+++ b/optee-teec/src/lib.rs
@@ -23,6 +23,9 @@ pub use self::session::{ConnectionMethods, Session};
pub use self::uuid::Uuid;
pub use self::extension::*;
pub use optee_teec_macros::{plugin_init, plugin_invoke};
+// Re-export optee_teec_sys so developers don't have to add it to their cargo
+// dependencies.
+pub use optee_teec_sys as raw;
mod context;
mod error;
diff --git a/optee-teec/src/operation.rs b/optee-teec/src/operation.rs
index 3b22a9c..a7be290 100644
--- a/optee-teec/src/operation.rs
+++ b/optee-teec/src/operation.rs
@@ -15,10 +15,8 @@
// specific language governing permissions and limitations
// under the License.
-use crate::{Param, ParamTypes};
-use optee_teec_sys as raw;
-use std::marker::PhantomData;
-use std::mem;
+use crate::{raw, Param, ParamTypes};
+use std::{marker::PhantomData, mem};
/// This type defines the payload of either an open session operation or an
/// invoke command operation. It is also used for cancellation of operations,
diff --git a/optee-teec/src/parameter.rs b/optee-teec/src/parameter.rs
index 152d4c0..9712377 100644
--- a/optee-teec/src/parameter.rs
+++ b/optee-teec/src/parameter.rs
@@ -15,9 +15,8 @@
// specific language governing permissions and limitations
// under the License.
-use optee_teec_sys as raw;
-use std::marker;
-use std::mem;
+use crate::raw;
+use std::{marker, mem};
pub trait Param {
fn into_raw(&mut self) -> raw::TEEC_Parameter;
diff --git a/optee-teec/src/session.rs b/optee-teec/src/session.rs
index fe7624a..fb55d68 100644
--- a/optee-teec/src/session.rs
+++ b/optee-teec/src/session.rs
@@ -16,12 +16,10 @@
// under the License.
use libc;
-use optee_teec_sys as raw;
-use std::ptr;
use std::marker;
+use std::ptr;
-use crate::Param;
-use crate::{Context, Error, Operation, Result, Uuid};
+use crate::{raw, Context, Error, Operation, Param, Result, Uuid};
/// Session login methods.
#[derive(Copy, Clone)]
@@ -72,7 +70,10 @@ impl<'ctx> Session<'ctx> {
raw_operation,
&mut err_origin,
) {
- raw::TEEC_SUCCESS => Ok(Self { raw: raw_session, _marker:
marker::PhantomData }),
+ raw::TEEC_SUCCESS => Ok(Self {
+ raw: raw_session,
+ _marker: marker::PhantomData,
+ }),
code => Err(Error::from_raw_error(code)),
}
}
diff --git a/optee-teec/src/uuid.rs b/optee-teec/src/uuid.rs
index 2939fc6..f6ffd1f 100644
--- a/optee-teec/src/uuid.rs
+++ b/optee-teec/src/uuid.rs
@@ -15,9 +15,9 @@
// specific language governing permissions and limitations
// under the License.
+use crate::raw;
use core::fmt;
use hex;
-use optee_teec_sys as raw;
use uuid as uuid_crate;
use uuid_crate::parser::ParseError;
use uuid_crate::BytesError;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]