From a8fa845fa942cab6f103eee9f1d99593706cdee0 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 23 Mar 2026 15:23:59 -0400 Subject: [PATCH] Rust wrapper: ecc: fix possible resource leak in some error cases Fix F-1062. If wolfSSL returns an error after initializing ECC struct with wc_ecc_init_ex(), wc_ecc_free() might not have been called in all cases. Move construction of the ECC struct earlier ahead of further wolfSSL calls after wc_ecc_init_ex() so if those subsequent wolfSSL calls return an error the Drop impl for ECC will be called to deinitialize. --- wrapper/rust/wolfssl-wolfcrypt/src/ecc.rs | 81 +++++++++++------------ 1 file changed, 38 insertions(+), 43 deletions(-) diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/ecc.rs b/wrapper/rust/wolfssl-wolfcrypt/src/ecc.rs index 7504a1f944..5e6d09bd3d 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/ecc.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/ecc.rs @@ -427,15 +427,14 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let rc = unsafe { - sys::wc_ecc_make_key(&mut rng.wc_rng, size, &mut wc_ecc_key) + sys::wc_ecc_make_key(&mut rng.wc_rng, size, &mut ecc.wc_ecc_key) }; if rc != 0 { - unsafe { sys::wc_ecc_free(&mut wc_ecc_key); } return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -485,15 +484,14 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let rc = unsafe { - sys::wc_ecc_make_key_ex(&mut rng.wc_rng, size, &mut wc_ecc_key, curve_id) + sys::wc_ecc_make_key_ex(&mut rng.wc_rng, size, &mut ecc.wc_ecc_key, curve_id) }; if rc != 0 { - unsafe { sys::wc_ecc_free(&mut wc_ecc_key); } return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -544,15 +542,14 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let rc = unsafe { - sys::wc_ecc_make_key_ex2(&mut rng.wc_rng, size, &mut wc_ecc_key, curve_id, flags) + sys::wc_ecc_make_key_ex2(&mut rng.wc_rng, size, &mut ecc.wc_ecc_key, curve_id, flags) }; if rc != 0 { - unsafe { sys::wc_ecc_free(&mut wc_ecc_key); } return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -632,16 +629,16 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let mut idx = 0u32; let der_size = der.len() as u32; let rc = unsafe { - sys::wc_EccPrivateKeyDecode(der.as_ptr(), &mut idx, &mut wc_ecc_key, der_size) + sys::wc_EccPrivateKeyDecode(der.as_ptr(), &mut idx, &mut ecc.wc_ecc_key, der_size) }; if rc != 0 { return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -695,16 +692,16 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let mut idx = 0u32; let der_size = der.len() as u32; let rc = unsafe { - sys::wc_EccPublicKeyDecode(der.as_ptr(), &mut idx, &mut wc_ecc_key, der_size) + sys::wc_EccPublicKeyDecode(der.as_ptr(), &mut idx, &mut ecc.wc_ecc_key, der_size) }; if rc != 0 { return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -764,18 +761,18 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let priv_size = priv_buf.len() as u32; let pub_ptr = if pub_buf.is_empty() {core::ptr::null()} else {pub_buf.as_ptr()}; let pub_size = pub_buf.len() as u32; let rc = unsafe { sys::wc_ecc_import_private_key(priv_buf.as_ptr(), priv_size, - pub_ptr, pub_size, &mut wc_ecc_key) + pub_ptr, pub_size, &mut ecc.wc_ecc_key) }; if rc != 0 { return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -838,18 +835,18 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let priv_size = priv_buf.len() as u32; let pub_ptr = if pub_buf.is_empty() {core::ptr::null()} else {pub_buf.as_ptr()}; let pub_size = pub_buf.len() as u32; let rc = unsafe { sys::wc_ecc_import_private_key_ex(priv_buf.as_ptr(), priv_size, - pub_ptr, pub_size, &mut wc_ecc_key, curve_id) + pub_ptr, pub_size, &mut ecc.wc_ecc_key, curve_id) }; if rc != 0 { return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -897,19 +894,19 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let qx_ptr = qx.as_ptr() as *const core::ffi::c_char; let qy_ptr = qy.as_ptr() as *const core::ffi::c_char; let d_ptr = d.as_ptr() as *const core::ffi::c_char; let curve_name_ptr = curve_name.as_ptr() as *const core::ffi::c_char; let rc = unsafe { - sys::wc_ecc_import_raw(&mut wc_ecc_key, qx_ptr, qy_ptr, d_ptr, + sys::wc_ecc_import_raw(&mut ecc.wc_ecc_key, qx_ptr, qy_ptr, d_ptr, curve_name_ptr) }; if rc != 0 { return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -957,18 +954,18 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let qx_ptr = qx.as_ptr() as *const core::ffi::c_char; let qy_ptr = qy.as_ptr() as *const core::ffi::c_char; let d_ptr = d.as_ptr() as *const core::ffi::c_char; let rc = unsafe { - sys::wc_ecc_import_raw_ex(&mut wc_ecc_key, qx_ptr, qy_ptr, d_ptr, - curve_id) + sys::wc_ecc_import_raw_ex(&mut ecc.wc_ecc_key, qx_ptr, qy_ptr, + d_ptr, curve_id) }; if rc != 0 { return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -1025,15 +1022,15 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let rc = unsafe { - sys::wc_ecc_import_unsigned(&mut wc_ecc_key, qx.as_ptr(), qy.as_ptr(), - d.as_ptr(), curve_id) + sys::wc_ecc_import_unsigned(&mut ecc.wc_ecc_key, qx.as_ptr(), + qy.as_ptr(), d.as_ptr(), curve_id) }; if rc != 0 { return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -1084,15 +1081,14 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let rc = unsafe { - sys::wc_ecc_import_x963(din.as_ptr(), din_size, &mut wc_ecc_key) + sys::wc_ecc_import_x963(din.as_ptr(), din_size, &mut ecc.wc_ecc_key) }; if rc != 0 { - unsafe { sys::wc_ecc_free(&mut wc_ecc_key); } return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -1148,15 +1144,14 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let rc = unsafe { - sys::wc_ecc_import_x963_ex(din.as_ptr(), din_size, &mut wc_ecc_key, curve_id) + sys::wc_ecc_import_x963_ex(din.as_ptr(), din_size, &mut ecc.wc_ecc_key, curve_id) }; if rc != 0 { - unsafe { sys::wc_ecc_free(&mut wc_ecc_key); } return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) }