Skip to content

Commit 4d08f5e

Browse files
committed
Fix for handles not being unique.
- Handles returned from tpm2-tss APIs does not need to be unique. This an attempt to fix problem #383 by removing the check in HandleManager that made a check for uniqueness. This has been replaced with handle consistency check. - Enables the integration tests that was disabled due to this issue. Co-authored-by: Ionut Mihalcea <[email protected]> Co-authored-by: Jesper Brynolf <[email protected]> Signed-off-by: Jesper Brynolf <[email protected]>
1 parent 4e00ff8 commit 4d08f5e

File tree

4 files changed

+37
-8
lines changed

4 files changed

+37
-8
lines changed

tss-esapi/src/abstraction/nv.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ pub fn read_full(
4242
}
4343

4444
/// Returns the NvPublic and Name associated with an NV index TPM handle
45+
///
46+
/// NOTE: This call _may_ close existing ESYS handles to the NV Index.
4547
fn get_nv_index_info(
4648
context: &mut Context,
4749
nv_index_tpm_handle: NvIndexTpmHandle,
@@ -63,6 +65,8 @@ fn get_nv_index_info(
6365
}
6466

6567
/// Lists all the currently defined NV Indexes' names and public components
68+
///
69+
/// NOTE: This call _may_ close existing ESYS handles to the NV Index.
6670
pub fn list(context: &mut Context) -> Result<Vec<(NvPublic, Name)>> {
6771
context.execute_without_session(|ctx| {
6872
ctx.get_capability(
@@ -166,6 +170,8 @@ pub fn max_nv_buffer_size(ctx: &mut Context) -> Result<usize> {
166170
/// Provides methods and trait implementations to interact with a non-volatile storage index that has been opened.
167171
///
168172
/// Use [`NvOpenOptions::open`] to obtain an [`NvReaderWriter`] object.
173+
///
174+
/// NOTE: When the `NvReaderWriter` is dropped, any existing ESYS handles to NV Indexes _may_ be closed.
169175
#[derive(Debug)]
170176
pub struct NvReaderWriter<'a> {
171177
context: &'a mut Context,

tss-esapi/src/context/handle_manager.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,14 @@ impl HandleManager {
4040
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
4141
}
4242

43-
if self.open_handles.contains_key(&handle) {
44-
error!("Handle({}) is already open", ESYS_TR::from(handle));
45-
return Err(Error::local_error(WrapperErrorKind::InvalidHandleState));
43+
// The TSS might return the same handle, see #383
44+
if let Some(stored_handle_drop_action) = self.open_handles.get(&handle) {
45+
if handle_drop_action != *stored_handle_drop_action {
46+
error!("Handle drop action inconsistency");
47+
return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
48+
}
4649
}
50+
4751
let _ = self.open_handles.insert(handle, handle_drop_action);
4852
Ok(())
4953
}

tss-esapi/tests/integration_tests/abstraction_tests/ek_tests.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use tss_esapi::{
88

99
use crate::common::create_ctx_without_session;
1010

11-
#[ignore = "issues with tpm2-tss"]
1211
#[test]
1312
fn test_retrieve_ek_pubcert() {
1413
let mut context = create_ctx_without_session();

tss-esapi/tests/integration_tests/abstraction_tests/nv_tests.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ fn write_nv_index(context: &mut Context, nv_index: NvIndexTpmHandle) -> NvIndexH
6060
owner_nv_index_handle
6161
}
6262

63-
#[ignore = "issues with tpm2-tss"]
6463
#[test]
6564
fn list() {
6665
let mut context = create_ctx_with_session();
@@ -73,31 +72,52 @@ fn list() {
7372
.map(|(public, _)| public.nv_index())
7473
.any(|x| x == nv_index));
7574

76-
let owner_nv_index_handle = write_nv_index(&mut context, nv_index);
75+
let initial_owner_nv_index_handle = write_nv_index(&mut context, nv_index);
7776

7877
assert!(nv::list(&mut context)
7978
.unwrap()
8079
.iter()
8180
.map(|(public, _)| public.nv_index())
8281
.any(|x| x == nv_index));
8382

83+
// Need to get the ESYS handle again, as it was closed by nv::list above.
84+
// 1. If this fails with a TssError something is seriously wrong but it
85+
// does not hurt to to try to clean the NV space up using the initial handle.
86+
//
87+
// 2. If this fails with a WrapperError then there is only an inconsistency
88+
// in how the handle should be closed and cleaning up the NV space should
89+
// using the initial handle should still be possible.
90+
let owner_nv_index_handle = context
91+
.tr_from_tpm_public(nv_index.into())
92+
.map_or_else(|_| initial_owner_nv_index_handle, NvIndexHandle::from);
93+
8494
context
8595
.nv_undefine_space(Provision::Owner, owner_nv_index_handle)
8696
.expect("Call to nv_undefine_space failed");
8797
}
8898

89-
#[ignore = "issues with tpm2-tss"]
9099
#[test]
91100
fn read_full() {
92101
let mut context = create_ctx_with_session();
93102

94103
let nv_index = NvIndexTpmHandle::new(0x01500015).unwrap();
95104

96-
let owner_nv_index_handle = write_nv_index(&mut context, nv_index);
105+
let initial_owner_nv_index_handle = write_nv_index(&mut context, nv_index);
97106

98107
// Now read it back
99108
let read_result = nv::read_full(&mut context, NvAuth::Owner, nv_index);
100109

110+
// Need to get the ESYS handle again, as it was closed by nv::list above.
111+
// 1. If this fails with a TssError something is seriously wrong but it
112+
// does not hurt to to try to clean the NV space up using the initial handle.
113+
//
114+
// 2. If this fails with a WrapperError then there is only an inconsistency
115+
// in how the handle should be closed and cleaning up the NV space should
116+
// using the initial handle should still be possible.
117+
let owner_nv_index_handle = context
118+
.tr_from_tpm_public(nv_index.into())
119+
.map_or_else(|_| initial_owner_nv_index_handle, NvIndexHandle::from);
120+
101121
context
102122
.nv_undefine_space(Provision::Owner, owner_nv_index_handle)
103123
.expect("Call to nv_undefine_space failed");

0 commit comments

Comments
 (0)