You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by iv...@apache.org on 2026/10/12 09:58:18 UTC
(teaclave-trustzone-sdk) 01/03: optee-utee: represent unknown login types instead of panicking
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/teaclave-trustzone-sdk.git
commit 96f2b5b9a5fba894fba1eadf49e69d32b07b80b7
Author: ivila <iv...@apache.org>
AuthorDate: Mon Oct 12 15:45:45 2026 +0800
optee-utee: represent unknown login types instead of panicking
Derive `LoginType` with num_enum's `FromPrimitive`/`IntoPrimitive`
and an `Unknown(u32)` catch-all, as `ErrorKind` does, so
`Identity::login_type` maps an unnamed login to data instead of
reaching the `panic!` for the seven named `TEE_LOGIN_*` constants. In
a TA that panic calls `TEE_Panic`, killing the instance and every
session on it. The raw value still round-trips through `Into<u32>`.
---
crates/optee-utee/src/identity.rs | 77 +++++++++++++++++++++++++++++++++------
1 file changed, 66 insertions(+), 11 deletions(-)
diff --git a/crates/optee-utee/src/identity.rs b/crates/optee-utee/src/identity.rs
index 1a3ea65..2c2138b 100644
--- a/crates/optee-utee/src/identity.rs
+++ b/crates/optee-utee/src/identity.rs
@@ -16,6 +16,7 @@
// under the License.
use crate::Uuid;
+use num_enum::{FromPrimitive, IntoPrimitive};
use optee_utee_sys as raw;
#[derive(Copy, Clone)]
@@ -24,17 +25,15 @@ pub struct Identity {
}
impl Identity {
+ /// Returns the login type of this client identity.
+ ///
+ /// The GlobalPlatform specification reserves implementation-defined login ranges,
+ /// so a login value outside the set named below is possible in principle. Such a
+ /// value is returned as [`LoginType::Unknown`] carrying the raw code instead of
+ /// aborting the TA, so a TA inspecting its callers must decide explicitly what to
+ /// do with a login it does not recognize — normally by rejecting the caller.
pub fn login_type(&self) -> LoginType {
- match self.raw.login {
- raw::TEE_LOGIN_PUBLIC => LoginType::Public,
- raw::TEE_LOGIN_USER => LoginType::User,
- raw::TEE_LOGIN_GROUP => LoginType::Group,
- raw::TEE_LOGIN_APPLICATION => LoginType::Application,
- raw::TEE_LOGIN_APPLICATION_USER => LoginType::ApplicationUser,
- raw::TEE_LOGIN_APPLICATION_GROUP => LoginType::ApplicationGroup,
- raw::TEE_LOGIN_TRUSTED_APP => LoginType::TrustedApp,
- _ => panic!("Invalid login type"),
- }
+ LoginType::from(self.raw.login)
}
pub fn uuid(&self) -> Uuid {
@@ -48,7 +47,12 @@ impl From<raw::TEE_Identity> for Identity {
}
}
-#[derive(Copy, Clone, PartialEq, Eq, strum::Display)]
+/// The login type of a client, as stamped by OP-TEE into `TEE_Identity::login`.
+///
+/// This is the Rust-side mirror of the `TEE_LOGIN_*` constants defined in the C
+/// header. The `Unknown(u32)` variant catches any login value this crate does not
+/// name, so the value always round-trips back through [`IntoPrimitive`].
+#[derive(Clone, Copy, Debug, Eq, PartialEq, FromPrimitive, IntoPrimitive, strum::Display)]
#[repr(u32)]
pub enum LoginType {
Public = raw::TEE_LOGIN_PUBLIC,
@@ -58,4 +62,55 @@ pub enum LoginType {
ApplicationUser = raw::TEE_LOGIN_APPLICATION_USER,
ApplicationGroup = raw::TEE_LOGIN_APPLICATION_GROUP,
TrustedApp = raw::TEE_LOGIN_TRUSTED_APP,
+ #[num_enum(catch_all)]
+ Unknown(u32),
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ fn identity_with_login(login: u32) -> Identity {
+ Identity::from(raw::TEE_Identity {
+ login,
+ uuid: raw::TEE_UUID {
+ timeLow: 0,
+ timeMid: 0,
+ timeHiAndVersion: 0,
+ clockSeqAndNode: [0; 8],
+ },
+ })
+ }
+
+ /// Guarantees: the login values named by the GlobalPlatform specification still
+ /// map to their named variants.
+ #[test]
+ fn known_login_types_still_map() {
+ let known = [
+ (raw::TEE_LOGIN_PUBLIC, LoginType::Public),
+ (raw::TEE_LOGIN_USER, LoginType::User),
+ (raw::TEE_LOGIN_GROUP, LoginType::Group),
+ (raw::TEE_LOGIN_APPLICATION, LoginType::Application),
+ (raw::TEE_LOGIN_APPLICATION_USER, LoginType::ApplicationUser),
+ (
+ raw::TEE_LOGIN_APPLICATION_GROUP,
+ LoginType::ApplicationGroup,
+ ),
+ (raw::TEE_LOGIN_TRUSTED_APP, LoginType::TrustedApp),
+ ];
+ for (raw_login, expected) in known {
+ assert_eq!(identity_with_login(raw_login).login_type(), expected);
+ }
+ }
+
+ /// Guarantees: reading a login value outside the named set yields `Unknown`
+ /// instead of panicking, and the raw value round-trips.
+ #[test]
+ fn unnamed_login_types_do_not_panic() {
+ for raw_login in [0x0000_0003, 0x0000_0300, 0x8000_0000, u32::MAX] {
+ let login_type = identity_with_login(raw_login).login_type();
+ assert_eq!(login_type, LoginType::Unknown(raw_login));
+ assert_eq!(u32::from(login_type), raw_login);
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org