aboutsummaryrefslogtreecommitdiff
path: root/rust/src/verify.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/src/verify.rs')
-rw-r--r--rust/src/verify.rs44
1 files changed, 31 insertions, 13 deletions
diff --git a/rust/src/verify.rs b/rust/src/verify.rs
index e972226..0098644 100644
--- a/rust/src/verify.rs
+++ b/rust/src/verify.rs
@@ -34,6 +34,7 @@ use avb_bindgen::{
use core::{
ffi::{c_char, CStr},
fmt,
+ marker::PhantomData,
ptr::{self, null, null_mut, NonNull},
slice,
};
@@ -200,13 +201,25 @@ impl fmt::Debug for PartitionData {
/// Wraps a raw C `AvbSlotVerifyData` struct.
///
/// This provides a Rust safe view over the raw data; no copies are made.
+///
+/// # Lifetimes
+/// * `'a`: the lifetime of any preloaded partition data borrowed from an `Ops<'a>` object.
+///
+/// If the `Ops` doesn't provide any preloaded data, `SlotVerifyData` doesn't borrow anything
+/// and instead allocates and owns all data internally, freeing it accordingly on `Drop`. In this
+/// case, `'a` can be `'static` which imposes no lifetime restrictions on `SlotVerifyData`.
pub struct SlotVerifyData<'a> {
/// Internally owns the underlying data and deletes it on drop.
raw_data: NonNull<AvbSlotVerifyData>,
- /// This provides the necessary lifetime borrow so the compiler can make sure that the `Ops`
- /// stays alive at least as long as we do, since it owns any preloaded partition data.
- _ops: &'a dyn Ops,
+ /// This provides the necessary lifetimes so the compiler can make sure that the preloaded
+ /// partition data stays alive at least as long as we do, since the underlying
+ /// `AvbSlotVerifyData` may wrap this data rather than making a copy.
+ //
+ // We do not want to actually borrow an `Ops` here, since in some cases `Ops` is just a
+ // temporary object and may go out of scope before us. The only shared data is the preloaded
+ // partition contents, not the entire `Ops` object.
+ _preloaded: PhantomData<&'a [u8]>,
}
// Useful so that `SlotVerifyError`, which may hold a `SlotVerifyData`, can derive `PartialEq`.
@@ -225,24 +238,28 @@ impl<'a> SlotVerifyData<'a> {
/// The returned `SlotVerifyData` will take ownership of the given `AvbSlotVerifyData` and
/// properly release the allocated memory when it drops.
///
+ /// If `ops` provided any preloaded data, the returned `SlotVerifyData` also borrows the data to
+ /// account for the underlying `AvbSlotVerifyData` holding a pointer to it. If there was no
+ /// preloaded data, then `SlotVerifyData` owns all its data.
+ ///
/// # Arguments
- /// * `data`: a `AvbSlotVerifyData` object created by libavb.
- /// * `ops`: the user-provided callback ops; borrowing this here ensures that any preloaded
- /// partition data stays unmodified while `data` is wrapping it.
+ /// * `data`: a `AvbSlotVerifyData` object created by libavb using `ops`.
+ /// * `ops`: the user-provided `Ops` object that was used for verification; only used here to
+ /// grab the preloaded data lifetime.
///
/// # Returns
/// The new object, or `Err(SlotVerifyError::Internal)` if the data looks invalid.
///
/// # Safety
- /// * `data` must be a valid `AvbSlotVerifyData` object created by libavb
+ /// * `data` must be a valid `AvbSlotVerifyData` object created by libavb using `ops`.
/// * after calling this function, do not access `data` except through the returned object
unsafe fn new(
data: *mut AvbSlotVerifyData,
- ops: &'a mut dyn Ops,
+ _ops: &dyn Ops<'a>,
) -> SlotVerifyNoDataResult<Self> {
let ret = Self {
raw_data: NonNull::new(data).ok_or(SlotVerifyError::Internal)?,
- _ops: ops,
+ _preloaded: PhantomData,
};
// Validate all the contained data here so accessors will never fail.
@@ -319,6 +336,7 @@ impl<'a> SlotVerifyData<'a> {
}
}
+/// Frees any internally-allocated and owned data.
impl<'a> Drop for SlotVerifyData<'a> {
fn drop(&mut self) {
// SAFETY:
@@ -371,11 +389,11 @@ impl<'a> fmt::Debug for SlotVerifyData<'a> {
/// 2. if `AllowVerificationError` is given in `flags`, it will also be returned on verification
/// failure
///
-/// If a `SlotVerifyData` is returned, it will borrow the provided `ops`. This is to ensure that
-/// any data shared by `SlotVerifyData` and `ops` - in particular preloaded partition contents -
-/// is not modified until `SlotVerifyData` is dropped.
+/// A returned `SlotVerifyData` will also borrow any preloaded data provided by `ops`. The `ops`
+/// object itself can go out of scope, but any preloaded data it could provide must outlive the
+/// returned object.
pub fn slot_verify<'a>(
- ops: &'a mut dyn Ops,
+ ops: &mut dyn Ops<'a>,
requested_partitions: &[&CStr],
ab_suffix: Option<&CStr>,
flags: SlotVerifyFlags,