Skip to content

Commit

Permalink
Add OwnedSession to support Send
Browse files Browse the repository at this point in the history
By default, Sessions contain a borrow into their Context. This is
correct, because the underlying implementation is allowed to have
pointer pointing back at their context.

However, this makes them harder to use from multiple threads, as a
non-static reference is inherently not Send.

This provides `OwnedSession`, behind the `owned` feature, which keeps a
reference counted hold on the context backing the session to prevent it
from being moved or dropped until the session leaves scope. This way,
the `OwnedSession` can be transferred to another thread which does not
know how long the original thread would keep the context around.
  • Loading branch information
maurer committed Feb 3, 2024
1 parent 71c2ff2 commit a33466f
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 0 deletions.
4 changes: 4 additions & 0 deletions optee-teec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ optee-teec-macros = { path = "macros" }
libc = "0.2"
uuid = "0.7"
hex = "0.3"
self_cell = { version = "1.0", optional = true }

[features]
owned = ["self_cell"]

[workspace]
members = ['systest']
51 changes: 51 additions & 0 deletions optee-teec/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ use libc;
use optee_teec_sys as raw;
use std::ptr;

#[cfg(feature = "owned")]
use crate::OwnedSession;
#[cfg(feature = "owned")]
use std::sync::Arc;

/// An abstraction of the logical connection between a client application and a
/// TEE.
pub struct Context {
Expand Down Expand Up @@ -91,6 +96,27 @@ impl Context {
)
}

#[cfg(feature = "owned")]
/// Opens a new owned session with the specified trusted application.
///
/// The target trusted application is specified by `uuid`.
///
/// # Examples
///
/// ```
/// use std::sync::Arc;
/// let mut ctx = Arc::new(Context::new().unwrap());
/// let uuid = Uuid::parse_str("8abcf200-2450-11e4-abe2-0002a5d5c51b").unwrap();
/// let session = ctx.open_owned_session(uuid).unwrap();
/// ```
pub fn open_owned_session(self: Arc<Self>, uuid: Uuid) -> Result<OwnedSession> {
OwnedSession::new(
self,
uuid,
None::<&mut Operation<ParamNone, ParamNone, ParamNone, ParamNone>>,
)
}

/// Opens a new session with the specified trusted application, pass some
/// parameters to TA by an operation.
///
Expand All @@ -112,6 +138,31 @@ impl Context {
) -> Result<Session> {
Session::new(self, uuid, Some(operation))
}

#[cfg(feature = "owned")]
/// Opens a new owned session with the specified trusted application, pass some
/// parameters to TA by an operation.
///
/// The target trusted application is specified by `uuid`.
///
/// # Examples
///
/// ```
/// use std::sync::Arc;
/// let mut ctx = Arc::new(Context::new().unwrap());
/// let uuid = Uuid::parse_str("8abcf200-2450-11e4-abe2-0002a5d5c51b").unwrap();
/// let p0 = ParamValue(42, 0, ParamType::ValueInout);
/// let mut operation = Operation::new(0, p0, ParamNone, ParamNone, ParamNone);
/// let session = ctx.open_session_with_operation(uuid, operation).unwrap();
/// ```
pub fn open_owned_session_with_operation<A: Param, B: Param, C: Param, D: Param>(
self: Arc<Self>,
uuid: Uuid,
operation: &mut Operation<A, B, C, D>,
) -> Result<OwnedSession> {
OwnedSession::new(self, uuid, Some(operation))
}

}

impl Drop for Context {
Expand Down
2 changes: 2 additions & 0 deletions optee-teec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ pub use self::error::{Error, ErrorKind, Result};
pub use self::operation::Operation;
pub use self::parameter::{Param, ParamNone, ParamTmpRef, ParamType, ParamTypes, ParamValue};
pub use self::session::{ConnectionMethods, Session};
#[cfg(feature = "owned")]
pub use self::session::OwnedSession;
pub use self::uuid::Uuid;
pub use self::extension::*;
pub use optee_teec_macros::{plugin_init, plugin_invoke};
Expand Down
46 changes: 46 additions & 0 deletions optee-teec/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@

use libc;
use optee_teec_sys as raw;
#[cfg(feature = "owned")]
use self_cell::self_cell;
#[cfg(feature = "owned")]
use std::sync::Arc;
use std::ptr;
use std::marker;

Expand All @@ -40,12 +44,54 @@ pub enum ConnectionMethods {
LoginGroupApplication,
}

// Sessions are documented as threadsafe in GP. Sessions with non-static lifetimes
// cannot be send because we cannot ensure that their context lives long enough, but
// sessions with 'static lifetime should be Send.
//
// A few ways to construct a session with static lifetime:
// 1. With the "owned" feature, use an `OwnedSession`
// 2. Use `once_cell::sync::Lazy` or `lazy_static` or anything similar to produce a global context
// 3. Use `Box::leak` or similar to permanently consume heap resources by creating a &'static
// Context
unsafe impl Send for Session<'static> {}

/// Represents a connection between a client application and a trusted application.
pub struct Session<'ctx> {
raw: raw::TEEC_Session,
_marker: marker::PhantomData<&'ctx Context>,
}

#[cfg(feature = "owned")]
self_cell! {
struct SessionPair {
owner: Arc<Context>,
#[covariant]
dependent: Session,
}
}

/// Represents an owned variant of `Session`, whose Context is reference counted.
#[cfg(feature = "owned")]
pub struct OwnedSession(SessionPair);

#[cfg(feature = "owned")]
impl OwnedSession {
/// Initializes an owned TEE session object with specified context and uuid.
pub fn new<A: Param, B: Param, C: Param, D: Param>(
context: Arc<Context>,
uuid: Uuid,
operation: Option<&mut Operation<A, B, C, D>>,
) -> Result<Self> {
Ok(Self(SessionPair::try_new(context, |context| Session::new(context, uuid, operation))?))
}

/// Provides access to an unowned session, borrowed from the owned version
pub fn session(&self) -> &Session<'_> {
self.0.borrow_dependent()
}

}

impl<'ctx> Session<'ctx> {
/// Initializes a TEE session object with specified context and uuid.
pub fn new<A: Param, B: Param, C: Param, D: Param>(
Expand Down

0 comments on commit a33466f

Please sign in to comment.