From c05b6761a4b0753f0bad11ffdd9c3fe8663813f0 Mon Sep 17 00:00:00 2001 From: ivila <390810839@qq.com> Date: Fri, 11 Sep 2026 18:35:19 +0800 Subject: [PATCH] optee-utee, optee-teec: preserve raw code in ErrorKind::Unknown Turn ErrorKind::Unknown into a num_enum catch-all holding the raw u32, so unrecognized codes round-trip through from_raw_error and raw_code instead of collapsing to a single discriminant. --- crates/optee-teec/src/error.rs | 27 +++++++-- crates/optee-utee/src/error.rs | 90 ++++++++++++++---------------- crates/optee-utee/src/extension.rs | 2 +- 3 files changed, 66 insertions(+), 53 deletions(-) diff --git a/crates/optee-teec/src/error.rs b/crates/optee-teec/src/error.rs index 830db712..0b6675d5 100644 --- a/crates/optee-teec/src/error.rs +++ b/crates/optee-teec/src/error.rs @@ -89,9 +89,9 @@ pub enum ErrorKind { ExternalCancel = raw::TEEC_ERROR_EXTERNAL_CANCEL, /// Implementation defined error code: trusted Application has panicked during the operation. TargetDead = raw::TEEC_ERROR_TARGET_DEAD, - /// Unknown error. - #[default] - Unknown, + /// Unknown error, holding the original raw code. + #[num_enum(catch_all)] + Unknown(u32), } impl ErrorKind { @@ -120,7 +120,7 @@ impl ErrorKind { ErrorKind::ShortBuffer => "The supplied buffer is too short for the generated output.", ErrorKind::ExternalCancel => "Undocumented.", ErrorKind::TargetDead => "Trusted Application has panicked during the operation.", - ErrorKind::Unknown => "Unknown error.", + ErrorKind::Unknown(_) => "Unknown error.", } } } @@ -221,3 +221,22 @@ pub enum ErrorOrigin { #[default] UNKNOWN, } + +#[cfg(test)] +mod tests { + use super::*; + + /// Guarantees: unrecognized codes are preserved in the catch-all variant + /// and round-trip through `Error`. + #[test] + fn unknown_raw_code_round_trips() { + let code = 0x1234_5678; + assert_eq!(ErrorKind::from(code), ErrorKind::Unknown(code)); + let back: u32 = ErrorKind::Unknown(code).into(); + assert_eq!(back, code); + + let err = Error::from_raw_error(code); + assert_eq!(err.kind(), ErrorKind::Unknown(code)); + assert_eq!(err.raw_code(), code); + } +} diff --git a/crates/optee-utee/src/error.rs b/crates/optee-utee/src/error.rs index a936fb04..749f542d 100644 --- a/crates/optee-utee/src/error.rs +++ b/crates/optee-utee/src/error.rs @@ -18,6 +18,7 @@ #[cfg(not(feature = "std"))] use core::error; use core::{fmt, result}; +use num_enum::{FromPrimitive, IntoPrimitive}; use optee_utee_sys as raw; #[cfg(feature = "std")] use std::error; @@ -44,7 +45,13 @@ pub struct Error { /// A list specifying general categories of TEE error and its corresponding code /// in OP-TEE OS. -#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +/// +/// Unrecognized codes are preserved in the `Unknown` catch-all variant, so +/// `raw_code()` always round-trips the value passed to +/// [`Error::from_raw_error`]. +#[derive( + Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, FromPrimitive, IntoPrimitive, +)] #[repr(u32)] pub enum ErrorKind { /// Object corruption. @@ -107,9 +114,9 @@ pub enum ErrorKind { /// The persistent time has been set but may have been corrupted and SHALL /// no longer be trusted. TimeNeedsReset = raw::TEE_ERROR_TIME_NEEDS_RESET, - /// Unknown error. - #[default] - Unknown, + /// Unknown error, holding the original raw code. + #[num_enum(catch_all)] + Unknown(u32), } impl ErrorKind { @@ -150,50 +157,7 @@ impl ErrorKind { ErrorKind::TimeNeedsReset => { "The persistent time has been set but may have been corrupted and SHALL no longer be trusted." } - ErrorKind::Unknown => "Unknown error.", - } - } -} - -impl From for u32 { - fn from(kind: ErrorKind) -> u32 { - kind as u32 - } -} - -impl From for ErrorKind { - fn from(code: u32) -> ErrorKind { - match code { - raw::TEE_ERROR_CORRUPT_OBJECT => ErrorKind::CorruptObject, - raw::TEE_ERROR_CORRUPT_OBJECT_2 => ErrorKind::CorruptObject2, - raw::TEE_ERROR_STORAGE_NOT_AVAILABLE => ErrorKind::StorageNotAvailable, - raw::TEE_ERROR_STORAGE_NOT_AVAILABLE_2 => ErrorKind::StorageNotAvailable2, - raw::TEE_ERROR_GENERIC => ErrorKind::Generic, - raw::TEE_ERROR_ACCESS_DENIED => ErrorKind::AccessDenied, - raw::TEE_ERROR_CANCEL => ErrorKind::Cancel, - raw::TEE_ERROR_ACCESS_CONFLICT => ErrorKind::AccessConflict, - raw::TEE_ERROR_EXCESS_DATA => ErrorKind::ExcessData, - raw::TEE_ERROR_BAD_FORMAT => ErrorKind::BadFormat, - raw::TEE_ERROR_BAD_PARAMETERS => ErrorKind::BadParameters, - raw::TEE_ERROR_BAD_STATE => ErrorKind::BadState, - raw::TEE_ERROR_ITEM_NOT_FOUND => ErrorKind::ItemNotFound, - raw::TEE_ERROR_NOT_IMPLEMENTED => ErrorKind::NotImplemented, - raw::TEE_ERROR_NOT_SUPPORTED => ErrorKind::NotSupported, - raw::TEE_ERROR_NO_DATA => ErrorKind::NoData, - raw::TEE_ERROR_OUT_OF_MEMORY => ErrorKind::OutOfMemory, - raw::TEE_ERROR_BUSY => ErrorKind::Busy, - raw::TEE_ERROR_COMMUNICATION => ErrorKind::Communication, - raw::TEE_ERROR_SECURITY => ErrorKind::Security, - raw::TEE_ERROR_SHORT_BUFFER => ErrorKind::ShortBuffer, - raw::TEE_ERROR_EXTERNAL_CANCEL => ErrorKind::ExternalCancel, - raw::TEE_ERROR_OVERFLOW => ErrorKind::Overflow, - raw::TEE_ERROR_TARGET_DEAD => ErrorKind::TargetDead, - raw::TEE_ERROR_STORAGE_NO_SPACE => ErrorKind::StorageNoSpace, - raw::TEE_ERROR_MAC_INVALID => ErrorKind::MacInvalid, - raw::TEE_ERROR_SIGNATURE_INVALID => ErrorKind::SignatureInvalid, - raw::TEE_ERROR_TIME_NOT_SET => ErrorKind::TimeNotSet, - raw::TEE_ERROR_TIME_NEEDS_RESET => ErrorKind::TimeNeedsReset, - _ => ErrorKind::Unknown, + ErrorKind::Unknown(_) => "Unknown error.", } } } @@ -313,3 +277,33 @@ impl From for ErrorOrigin { } } } + +#[cfg(test)] +mod tests { + use super::*; + + /// Guarantees: unrecognized codes are preserved in the catch-all variant + /// and round-trip through `Error`. + #[test] + fn unknown_raw_code_round_trips() { + let code = 0x1234_5678; + assert_eq!(ErrorKind::from(code), ErrorKind::Unknown(code)); + let back: u32 = ErrorKind::Unknown(code).into(); + assert_eq!(back, code); + + let err = Error::from_raw_error(code); + assert_eq!(err.kind(), ErrorKind::Unknown(code)); + assert_eq!(err.raw_code(), code); + } + + /// Guarantees: known codes still map to their named variants. + #[test] + fn known_codes_still_map() { + assert_eq!( + ErrorKind::from(raw::TEE_ERROR_SECURITY), + ErrorKind::Security + ); + let code: u32 = ErrorKind::Security.into(); + assert_eq!(code, raw::TEE_ERROR_SECURITY); + } +} diff --git a/crates/optee-utee/src/extension.rs b/crates/optee-utee/src/extension.rs index 99f050c7..300af63e 100644 --- a/crates/optee-utee/src/extension.rs +++ b/crates/optee-utee/src/extension.rs @@ -102,7 +102,7 @@ impl LoadablePlugin { /// let mut cmd = plugin.invoke_with_capacity(command_id, subcommand_id, capacity); /// serde_json::to_writer(Wrapper(&mut cmd), &request_data).map_err(|err| { /// trace_println!("serde error: {:?}", err); - /// ErrorKind::Unknown + /// ErrorKind::Generic /// })?; /// let result = cmd.call()?; ///