Skip to content

Commit d5021d1

Browse files
authored
Merge pull request #340 from Superhepper/improved-ffi-data-handling
Fixes potential memory leaks from the ffi types.
2 parents 3295dba + 743acde commit d5021d1

18 files changed

+279
-342
lines changed

tss-esapi/src/context.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -388,25 +388,25 @@ impl Context {
388388
.unwrap() // will only fail if called from Drop after .take()
389389
}
390390

391-
/// Internal function for retrieving the ESYS session handle for
391+
/// Private method for retrieving the ESYS session handle for
392392
/// the optional session 1.
393393
fn optional_session_1(&self) -> ESYS_TR {
394394
SessionHandle::from(self.sessions.0).into()
395395
}
396396

397-
/// Internal function for retrieving the ESYS session handle for
397+
/// Private method for retrieving the ESYS session handle for
398398
/// the optional session 2.
399399
fn optional_session_2(&self) -> ESYS_TR {
400400
SessionHandle::from(self.sessions.1).into()
401401
}
402402

403-
/// Internal function for retrieving the ESYS session handle for
403+
/// Private method for retrieving the ESYS session handle for
404404
/// the optional session 3.
405405
fn optional_session_3(&self) -> ESYS_TR {
406406
SessionHandle::from(self.sessions.2).into()
407407
}
408408

409-
/// Function that returns the required
409+
/// Private method that returns the required
410410
/// session handle 1 if it is available else
411411
/// returns an error.
412412
fn required_session_1(&self) -> Result<ESYS_TR> {
@@ -419,7 +419,7 @@ impl Context {
419419
})
420420
}
421421

422-
/// Function that returns the required
422+
/// Private method that returns the required
423423
/// session handle 2 if it is available else
424424
/// returns an error.
425425
fn required_session_2(&self) -> Result<ESYS_TR> {
@@ -431,6 +431,12 @@ impl Context {
431431
Error::local_error(ErrorKind::MissingAuthSession)
432432
})
433433
}
434+
435+
/// Private function for handling that has been allocated with
436+
/// C memory allocation functions in TSS.
437+
fn ffi_data_to_owned<T>(data_ptr: *mut T) -> T {
438+
MBox::into_inner(unsafe { MBox::from_raw(data_ptr) })
439+
}
434440
}
435441

436442
impl Drop for Context {

tss-esapi/src/context/general_esys_tr.rs

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,20 @@ use crate::{
66
handles::{handle_conversion::TryIntoNotNone, TpmHandle},
77
structures::Auth,
88
structures::Name,
9-
tss2_esys::{
10-
Esys_TR_Close, Esys_TR_FromTPMPublic, Esys_TR_GetName, Esys_TR_SetAuth, ESYS_TR,
11-
ESYS_TR_NONE, TPM2B_NAME,
12-
},
9+
tss2_esys::{Esys_TR_Close, Esys_TR_FromTPMPublic, Esys_TR_GetName, Esys_TR_SetAuth},
1310
Context, Error, Result,
1411
};
1512
use log::error;
16-
use mbox::MBox;
1713
use std::convert::TryFrom;
1814
use std::ptr::null_mut;
1915
use zeroize::Zeroize;
2016

2117
impl Context {
2218
/// Set the authentication value for a given object handle in the ESYS context.
2319
pub fn tr_set_auth(&mut self, object_handle: ObjectHandle, auth: Auth) -> Result<()> {
24-
let mut tss_auth = auth.into();
25-
let ret = unsafe { Esys_TR_SetAuth(self.mut_context(), object_handle.into(), &tss_auth) };
26-
tss_auth.buffer.zeroize();
20+
let mut auth_value = auth.into();
21+
let ret = unsafe { Esys_TR_SetAuth(self.mut_context(), object_handle.into(), &auth_value) };
22+
auth_value.buffer.zeroize();
2723
let ret = Error::from_tss_rc(ret);
2824
if ret.is_success() {
2925
Ok(())
@@ -35,12 +31,12 @@ impl Context {
3531

3632
/// Retrieve the name of an object from the object handle
3733
pub fn tr_get_name(&mut self, object_handle: ObjectHandle) -> Result<Name> {
38-
let mut name = null_mut();
39-
let ret = unsafe { Esys_TR_GetName(self.mut_context(), object_handle.into(), &mut name) };
34+
let mut name_ptr = null_mut();
35+
let ret =
36+
unsafe { Esys_TR_GetName(self.mut_context(), object_handle.into(), &mut name_ptr) };
4037
let ret = Error::from_tss_rc(ret);
4138
if ret.is_success() {
42-
let tss_name = unsafe { MBox::<TPM2B_NAME>::from_raw(name) };
43-
Ok(Name::try_from(*tss_name)?)
39+
Name::try_from(Context::ffi_data_to_owned(name_ptr))
4440
} else {
4541
error!("Error in getting name: {}", ret);
4642
Err(ret)
@@ -49,29 +45,28 @@ impl Context {
4945

5046
/// Used to construct an esys object from the resources inside the TPM.
5147
pub fn tr_from_tpm_public(&mut self, tpm_handle: TpmHandle) -> Result<ObjectHandle> {
52-
let mut esys_object_handle: ESYS_TR = ESYS_TR_NONE;
48+
let mut object = ObjectHandle::None.into();
5349
let ret = unsafe {
5450
Esys_TR_FromTPMPublic(
5551
self.mut_context(),
5652
tpm_handle.into(),
5753
self.optional_session_1(),
5854
self.optional_session_2(),
5955
self.optional_session_3(),
60-
&mut esys_object_handle,
56+
&mut object,
6157
)
6258
};
6359
let ret = Error::from_tss_rc(ret);
6460
if ret.is_success() {
65-
let object_handle = ObjectHandle::from(esys_object_handle);
6661
self.handle_manager.add_handle(
67-
object_handle,
62+
object.into(),
6863
if tpm_handle.may_be_flushed() {
6964
HandleDropAction::Flush
7065
} else {
7166
HandleDropAction::Close
7267
},
7368
)?;
74-
Ok(object_handle)
69+
Ok(object.into())
7570
} else {
7671
error!("Error when getting ESYS handle from TPM handle: {}", ret);
7772
Err(ret)
@@ -82,12 +77,12 @@ impl Context {
8277
///
8378
/// This is useful for cleaning up handles for which the context cannot be flushed.
8479
pub fn tr_close(&mut self, object_handle: &mut ObjectHandle) -> Result<()> {
85-
let mut tss_esys_object_handle = object_handle.try_into_not_none()?;
86-
let ret = unsafe { Esys_TR_Close(self.mut_context(), &mut tss_esys_object_handle) };
80+
let mut rsrc_handle = object_handle.try_into_not_none()?;
81+
let ret = unsafe { Esys_TR_Close(self.mut_context(), &mut rsrc_handle) };
8782
let ret = Error::from_tss_rc(ret);
8883
if ret.is_success() {
8984
self.handle_manager.set_as_closed(*object_handle)?;
90-
*object_handle = ObjectHandle::from(tss_esys_object_handle);
85+
*object_handle = ObjectHandle::from(rsrc_handle);
9186
Ok(())
9287
} else {
9388
error!("Error when closing an ESYS handle: {}", ret);

tss-esapi/src/context/session_administration.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{
44
attributes::{SessionAttributes, SessionAttributesMask},
55
handles::SessionHandle,
66
interface_types::session_handles::AuthSession,
7-
tss2_esys::{Esys_TRSess_GetAttributes, Esys_TRSess_SetAttributes, TPMA_SESSION},
7+
tss2_esys::{Esys_TRSess_GetAttributes, Esys_TRSess_SetAttributes},
88
Context, Error, Result,
99
};
1010
use log::error;
@@ -36,7 +36,7 @@ impl Context {
3636

3737
/// Get session attribute flags.
3838
pub fn tr_sess_get_attributes(&mut self, session: AuthSession) -> Result<SessionAttributes> {
39-
let mut flags: TPMA_SESSION = 0;
39+
let mut flags = 0;
4040
let ret = unsafe {
4141
Esys_TRSess_GetAttributes(
4242
self.mut_context(),

tss-esapi/src/context/tpm_commands/asymmetric_primitives.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ use crate::{
44
handles::KeyHandle,
55
structures::Data,
66
structures::{EccPoint, PublicKeyRsa, RsaDecryptionScheme},
7-
tss2_esys::*,
7+
tss2_esys::{Esys_ECDH_KeyGen, Esys_ECDH_ZGen, Esys_RSA_Decrypt, Esys_RSA_Encrypt},
88
Context, Error, Result,
99
};
1010
use log::error;
1111
use std::convert::TryFrom;
12-
use std::convert::TryInto;
1312
use std::ptr::null_mut;
1413

1514
impl Context {
@@ -21,7 +20,7 @@ impl Context {
2120
in_scheme: RsaDecryptionScheme,
2221
label: Data,
2322
) -> Result<PublicKeyRsa> {
24-
let mut out_data = null_mut();
23+
let mut out_data_ptr = null_mut();
2524
let ret = unsafe {
2625
Esys_RSA_Encrypt(
2726
self.mut_context(),
@@ -32,14 +31,13 @@ impl Context {
3231
&message.into(),
3332
&in_scheme.into(),
3433
&label.into(),
35-
&mut out_data,
34+
&mut out_data_ptr,
3635
)
3736
};
3837
let ret = Error::from_tss_rc(ret);
3938

4039
if ret.is_success() {
41-
let data = unsafe { PublicKeyRsa::try_from(*out_data)? };
42-
Ok(data)
40+
PublicKeyRsa::try_from(Context::ffi_data_to_owned(out_data_ptr))
4341
} else {
4442
error!("Error when performing RSA encryption: {}", ret);
4543
Err(ret)
@@ -54,7 +52,7 @@ impl Context {
5452
in_scheme: RsaDecryptionScheme,
5553
label: Data,
5654
) -> Result<PublicKeyRsa> {
57-
let mut message = null_mut();
55+
let mut message_ptr = null_mut();
5856
let ret = unsafe {
5957
Esys_RSA_Decrypt(
6058
self.mut_context(),
@@ -65,14 +63,13 @@ impl Context {
6563
&cipher_text.into(),
6664
&in_scheme.into(),
6765
&label.into(),
68-
&mut message,
66+
&mut message_ptr,
6967
)
7068
};
7169
let ret = Error::from_tss_rc(ret);
7270

7371
if ret.is_success() {
74-
let data = unsafe { PublicKeyRsa::try_from(*message)? };
75-
Ok(data)
72+
PublicKeyRsa::try_from(Context::ffi_data_to_owned(message_ptr))
7673
} else {
7774
error!("Error when performing RSA decryption: {}", ret);
7875
Err(ret)
@@ -186,24 +183,29 @@ impl Context {
186183
/// let (z_point, pub_point) = context.ecdh_key_gen(key_handle).unwrap();
187184
/// ```
188185
pub fn ecdh_key_gen(&mut self, key_handle: KeyHandle) -> Result<(EccPoint, EccPoint)> {
189-
let mut z_point = null_mut();
190-
let mut pub_point = null_mut();
186+
let mut z_point_ptr = null_mut();
187+
let mut pub_point_ptr = null_mut();
191188
let ret = unsafe {
192189
Esys_ECDH_KeyGen(
193190
self.mut_context(),
194191
key_handle.into(),
195192
self.optional_session_1(),
196193
self.optional_session_2(),
197194
self.optional_session_3(),
198-
&mut z_point,
199-
&mut pub_point,
195+
&mut z_point_ptr,
196+
&mut pub_point_ptr,
200197
)
201198
};
202199

203200
let ret = Error::from_tss_rc(ret);
204201

205202
if ret.is_success() {
206-
Ok(unsafe { ((*z_point).point.try_into()?, (*pub_point).point.try_into()?) })
203+
let z_point = Context::ffi_data_to_owned(z_point_ptr);
204+
let pub_point = Context::ffi_data_to_owned(pub_point_ptr);
205+
Ok((
206+
EccPoint::try_from(z_point.point)?,
207+
EccPoint::try_from(pub_point.point)?,
208+
))
207209
} else {
208210
error!("Error when generating ECDH keypair: {}", ret);
209211
Err(ret)
@@ -320,7 +322,7 @@ impl Context {
320322
/// assert_eq!(z_point.x().value(), z_point_gen.x().value());
321323
/// ```
322324
pub fn ecdh_z_gen(&mut self, key_handle: KeyHandle, in_point: EccPoint) -> Result<EccPoint> {
323-
let mut point = null_mut();
325+
let mut out_point_ptr = null_mut();
324326
let ret = unsafe {
325327
Esys_ECDH_ZGen(
326328
self.mut_context(),
@@ -329,13 +331,14 @@ impl Context {
329331
self.optional_session_2(),
330332
self.optional_session_3(),
331333
&in_point.into(),
332-
&mut point,
334+
&mut out_point_ptr,
333335
)
334336
};
335337
let ret = Error::from_tss_rc(ret);
336338

337339
if ret.is_success() {
338-
Ok(unsafe { (*point).point.try_into()? })
340+
let out_point = Context::ffi_data_to_owned(out_point_ptr);
341+
EccPoint::try_from(out_point.point)
339342
} else {
340343
error!("Error when performing ECDH ZGen: {}", ret);
341344
Err(ret)

tss-esapi/src/context/tpm_commands/attestation_commands.rs

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
use crate::{
44
handles::{KeyHandle, ObjectHandle},
55
structures::{Attest, AttestBuffer, Data, PcrSelectionList, Signature, SignatureScheme},
6-
tss2_esys::*,
6+
tss2_esys::{Esys_Certify, Esys_Quote},
77
Context, Error, Result,
88
};
99
use log::error;
10-
use mbox::MBox;
1110
use std::convert::TryFrom;
1211
use std::ptr::null_mut;
1312

@@ -123,8 +122,8 @@ impl Context {
123122
qualifying_data: Data,
124123
signing_scheme: SignatureScheme,
125124
) -> Result<(Attest, Signature)> {
126-
let mut certify_info = null_mut();
127-
let mut signature = null_mut();
125+
let mut certify_info_ptr = null_mut();
126+
let mut signature_ptr = null_mut();
128127
let ret = unsafe {
129128
Esys_Certify(
130129
self.mut_context(),
@@ -135,18 +134,18 @@ impl Context {
135134
self.optional_session_3(),
136135
&qualifying_data.into(),
137136
&signing_scheme.into(),
138-
&mut certify_info,
139-
&mut signature,
137+
&mut certify_info_ptr,
138+
&mut signature_ptr,
140139
)
141140
};
142141
let ret = Error::from_tss_rc(ret);
143142

144143
if ret.is_success() {
145-
let certify_info = unsafe { MBox::<TPM2B_ATTEST>::from_raw(certify_info) };
146-
let signature = unsafe { MBox::from_raw(signature) };
144+
let certify_info = Context::ffi_data_to_owned(certify_info_ptr);
145+
let signature = Context::ffi_data_to_owned(signature_ptr);
147146
Ok((
148-
Attest::try_from(AttestBuffer::try_from(*certify_info)?)?,
149-
Signature::try_from(*signature)?,
147+
Attest::try_from(AttestBuffer::try_from(certify_info)?)?,
148+
Signature::try_from(signature)?,
150149
))
151150
} else {
152151
error!("Error in certifying: {}", ret);
@@ -167,8 +166,8 @@ impl Context {
167166
signing_scheme: SignatureScheme,
168167
pcr_selection_list: PcrSelectionList,
169168
) -> Result<(Attest, Signature)> {
170-
let mut quoted = null_mut();
171-
let mut signature = null_mut();
169+
let mut quoted_ptr = null_mut();
170+
let mut signature_ptr = null_mut();
172171
let ret = unsafe {
173172
Esys_Quote(
174173
self.mut_context(),
@@ -179,18 +178,18 @@ impl Context {
179178
&qualifying_data.into(),
180179
&signing_scheme.into(),
181180
&pcr_selection_list.into(),
182-
&mut quoted,
183-
&mut signature,
181+
&mut quoted_ptr,
182+
&mut signature_ptr,
184183
)
185184
};
186185
let ret = Error::from_tss_rc(ret);
187186

188187
if ret.is_success() {
189-
let quoted = unsafe { MBox::from_raw(quoted) };
190-
let signature = unsafe { MBox::from_raw(signature) };
188+
let quoted = Context::ffi_data_to_owned(quoted_ptr);
189+
let signature = Context::ffi_data_to_owned(signature_ptr);
191190
Ok((
192-
Attest::try_from(AttestBuffer::try_from(*quoted)?)?,
193-
Signature::try_from(*signature)?,
191+
Attest::try_from(AttestBuffer::try_from(quoted)?)?,
192+
Signature::try_from(signature)?,
194193
))
195194
} else {
196195
error!("Error in quoting PCR: {}", ret);

0 commit comments

Comments
 (0)