diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-03-11 16:35:20 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-03-11 17:51:23 +0100 |
commit | e56516dafeb46d701725684e8fd11074350b7443 (patch) | |
tree | 1ddd8b3ff106d9e4ce1d8659d9cbe09083aab8d4 /openpgp-ffi | |
parent | 5f95716a86b6cefb1f9b6a8a5233f6980a511637 (diff) |
openpgp-ffi: Avoid undefined behavior.
- Dropping a zeroed instant of that type is not safe as it contains
references.
Diffstat (limited to 'openpgp-ffi')
-rw-r--r-- | openpgp-ffi/src/cert.rs | 86 | ||||
-rw-r--r-- | openpgp-ffi/src/serialize.rs | 6 |
2 files changed, 44 insertions, 48 deletions
diff --git a/openpgp-ffi/src/cert.rs b/openpgp-ffi/src/cert.rs index d0b83e0f..6a781411 100644 --- a/openpgp-ffi/src/cert.rs +++ b/openpgp-ffi/src/cert.rs @@ -435,8 +435,8 @@ pub extern "C" fn pgp_user_id_bundle_iter_next<'a>( /// Wraps a KeyIter for export via the FFI. pub struct KeyIterWrapper<'a> { pub(crate) // For serialize.rs. - iter: KeyIter<'a, openpgp::packet::key::PublicParts, - openpgp::packet::key::UnspecifiedRole>, + iter: Option<KeyIter<'a, openpgp::packet::key::PublicParts, + openpgp::packet::key::UnspecifiedRole>>, // Whether next has been called. next_called: bool, } @@ -451,7 +451,7 @@ pub extern "C" fn pgp_cert_key_iter(cert: *const Cert) { let cert = cert.ref_raw(); box_raw!(KeyIterWrapper { - iter: cert.keys(), + iter: Some(cert.keys()), next_called: false, }) } @@ -476,9 +476,10 @@ pub extern "C" fn pgp_cert_key_iter_secret<'a>( panic!("Can't change KeyIter filter after iterating."); } - use std::mem; - let tmp = mem::replace(&mut iter_wrapper.iter, unsafe { mem::zeroed() }); - iter_wrapper.iter = unsafe { std::mem::transmute(tmp.secret()) }; + use std::mem::transmute; + iter_wrapper.iter = Some(unsafe { + transmute(iter_wrapper.iter.take().unwrap().secret()) + }); } /// Changes the iterator to only return keys that have unencrypted @@ -494,10 +495,10 @@ pub extern "C" fn pgp_cert_key_iter_unencrypted_secret<'a>( panic!("Can't change KeyIter filter after iterating."); } - use std::mem; - let tmp = mem::replace(&mut iter_wrapper.iter, unsafe { mem::zeroed() }); - iter_wrapper.iter = - unsafe { std::mem::transmute(tmp.unencrypted_secret()) }; + use std::mem::transmute; + iter_wrapper.iter = Some(unsafe { + transmute(iter_wrapper.iter.take().unwrap().unencrypted_secret()) + }); } /// Changes the iterator to only return keys that are valid at time @@ -517,13 +518,12 @@ pub extern "C" fn pgp_cert_key_iter_policy<'a>( panic!("Can't change KeyIter filter after iterating."); } - use std::mem; - let tmp = mem::replace(&mut iter_wrapper.iter, unsafe { mem::zeroed() }); - + use std::mem::transmute; box_raw!(ValidKeyIterWrapper { - iter: unsafe { - std::mem::transmute(tmp.with_policy(&**policy, maybe_time(when))) - }, + iter: Some(unsafe { + transmute(iter_wrapper.iter.take().unwrap() + .with_policy(&**policy, maybe_time(when))) + }), next_called: false, }) } @@ -545,7 +545,7 @@ pub extern "C" fn pgp_cert_key_iter_next<'a>( let iter_wrapper = ffi_param_ref_mut!(iter_wrapper); iter_wrapper.next_called = true; - if let Some(ka) = iter_wrapper.iter.next() { + if let Some(ka) = iter_wrapper.iter.as_mut().unwrap().next() { Some(ka.key().mark_parts_unspecified_ref().mark_role_unspecified_ref()) .move_into_raw() } else { @@ -556,8 +556,8 @@ pub extern "C" fn pgp_cert_key_iter_next<'a>( /// Wraps a ValidKeyIter for export via the FFI. pub struct ValidKeyIterWrapper<'a> { pub(crate) // For serialize.rs. - iter: ValidKeyIter<'a, openpgp::packet::key::PublicParts, - openpgp::packet::key::UnspecifiedRole>, + iter: Option<ValidKeyIter<'a, openpgp::packet::key::PublicParts, + openpgp::packet::key::UnspecifiedRole>>, // Whether next has been called. next_called: bool, } @@ -574,7 +574,7 @@ pub extern "C" fn pgp_cert_valid_key_iter(cert: *const Cert, { let cert = cert.ref_raw(); let iter = box_raw!(KeyIterWrapper { - iter: cert.keys(), + iter: Some(cert.keys()), next_called: false, }); @@ -601,9 +601,10 @@ pub extern "C" fn pgp_cert_valid_key_iter_secret<'a>( panic!("Can't change ValidKeyIter filter after iterating."); } - use std::mem; - let tmp = mem::replace(&mut iter_wrapper.iter, unsafe { mem::zeroed() }); - iter_wrapper.iter = unsafe { std::mem::transmute(tmp.secret()) }; + use std::mem::transmute; + iter_wrapper.iter = Some(unsafe { + transmute(iter_wrapper.iter.take().unwrap().secret()) + }); } /// Changes the iterator to only return keys that have unencrypted @@ -619,10 +620,10 @@ pub extern "C" fn pgp_cert_valid_key_iter_unencrypted_secret<'a>( panic!("Can't change ValidKeyIter filter after iterating."); } - use std::mem; - let tmp = mem::replace(&mut iter_wrapper.iter, unsafe { mem::zeroed() }); - iter_wrapper.iter = - unsafe { std::mem::transmute(tmp.unencrypted_secret()) }; + use std::mem::transmute; + iter_wrapper.iter = Some(unsafe { + transmute(iter_wrapper.iter.take().unwrap().unencrypted_secret()) + }); } /// Changes the iterator to only return keys that are certification @@ -643,9 +644,8 @@ pub extern "C" fn pgp_cert_valid_key_iter_for_certification<'a>( panic!("Can't change KeyIter filter after iterating."); } - use std::mem; - let tmp = mem::replace(&mut iter_wrapper.iter, unsafe { mem::zeroed() }); - iter_wrapper.iter = tmp.for_certification(); + iter_wrapper.iter = + Some(iter_wrapper.iter.take().unwrap().for_certification()); } /// Changes the iterator to only return keys that are certification @@ -666,9 +666,8 @@ pub extern "C" fn pgp_cert_valid_key_iter_for_signing<'a>( panic!("Can't change KeyIter filter after iterating."); } - use std::mem; - let tmp = mem::replace(&mut iter_wrapper.iter, unsafe { mem::zeroed() }); - iter_wrapper.iter = tmp.for_signing(); + iter_wrapper.iter = + Some(iter_wrapper.iter.take().unwrap().for_signing()); } /// Changes the iterator to only return keys that are capable of @@ -689,9 +688,8 @@ pub extern "C" fn pgp_cert_valid_key_iter_for_storage_encryption<'a>( panic!("Can't change KeyIter filter after iterating."); } - use std::mem; - let tmp = mem::replace(&mut iter_wrapper.iter, unsafe { mem::zeroed() }); - iter_wrapper.iter = tmp.for_storage_encryption(); + iter_wrapper.iter = + Some(iter_wrapper.iter.take().unwrap().for_storage_encryption()); } /// Changes the iterator to only return keys that are capable of @@ -712,9 +710,8 @@ pub extern "C" fn pgp_cert_valid_key_iter_for_transport_encryption<'a>( panic!("Can't change KeyIter filter after iterating."); } - use std::mem; - let tmp = mem::replace(&mut iter_wrapper.iter, unsafe { mem::zeroed() }); - iter_wrapper.iter = tmp.for_transport_encryption(); + iter_wrapper.iter = + Some(iter_wrapper.iter.take().unwrap().for_transport_encryption()); } /// Changes the iterator to only return keys that are alive. @@ -732,9 +729,7 @@ pub extern "C" fn pgp_cert_valid_key_iter_alive<'a>( panic!("Can't change KeyIter filter after iterating."); } - use std::mem; - let tmp = mem::replace(&mut iter_wrapper.iter, unsafe { mem::zeroed() }); - iter_wrapper.iter = tmp.alive(); + iter_wrapper.iter = Some(iter_wrapper.iter.take().unwrap().alive()); } /// Changes the iterator to only return keys whose revocation status @@ -751,9 +746,8 @@ pub extern "C" fn pgp_cert_valid_key_iter_revoked<'a>( panic!("Can't change KeyIter filter after iterating."); } - use std::mem; - let tmp = mem::replace(&mut iter_wrapper.iter, unsafe { mem::zeroed() }); - iter_wrapper.iter = tmp.revoked(Some(revoked)); + iter_wrapper.iter = + Some(iter_wrapper.iter.take().unwrap().revoked(revoked)); } /// Returns the next valid key. Returns NULL if there are no more @@ -773,7 +767,7 @@ pub extern "C" fn pgp_cert_valid_key_iter_next<'a>( let iter_wrapper = ffi_param_ref_mut!(iter_wrapper); iter_wrapper.next_called = true; - if let Some(ka) = iter_wrapper.iter.next() { + if let Some(ka) = iter_wrapper.iter.as_mut().unwrap().next() { let sig = ka.binding_signature(); let rs = ka.revoked(); let key = ka.key(); diff --git a/openpgp-ffi/src/serialize.rs b/openpgp-ffi/src/serialize.rs index dbbb537c..e9fece8d 100644 --- a/openpgp-ffi/src/serialize.rs +++ b/openpgp-ffi/src/serialize.rs @@ -279,10 +279,11 @@ fn pgp_recipients_from_key_iter<'a>( result_len: *mut size_t) -> *mut *mut Recipient<'a> { - let iter_wrapper = ffi_param_move!(iter_wrapper); + let mut iter_wrapper = ffi_param_move!(iter_wrapper); let result_len = ffi_param_ref_mut!(result_len); let recipients = iter_wrapper.iter + .take().unwrap() .map(|ka| ka.key().into()) .collect::<Vec<openpgp::serialize::stream::Recipient>>(); @@ -310,10 +311,11 @@ fn pgp_recipients_from_valid_key_iter<'a>( result_len: *mut size_t) -> *mut *mut Recipient<'a> { - let iter_wrapper = ffi_param_move!(iter_wrapper); + let mut iter_wrapper = ffi_param_move!(iter_wrapper); let result_len = ffi_param_ref_mut!(result_len); let recipients = iter_wrapper.iter + .take().unwrap() .map(|ka| ka.key().into()) .collect::<Vec<openpgp::serialize::stream::Recipient>>(); |