Skip to content

Commit 1873abf

Browse files
fix(init_ssl): Cleanup allocated resources on error to prevent a memory leak.
1 parent 4f90061 commit 1873abf

File tree

1 file changed

+71
-35
lines changed

1 file changed

+71
-35
lines changed

esp-mbedtls/src/lib.rs

+71-35
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ macro_rules! error_checked {
7373
Ok(())
7474
}
7575
}};
76+
($block:expr, $err_callback:expr) => {{
77+
let res = $block;
78+
if res != 0 {
79+
$err_callback();
80+
Err(TlsError::MbedTlsError(res))
81+
} else {
82+
Ok(())
83+
}
84+
}};
7685
}
7786

7887
#[derive(Debug, Clone, Copy, PartialEq)]
@@ -319,6 +328,7 @@ impl<'a> Certificates<'a> {
319328
let ssl_config =
320329
calloc(1, size_of::<mbedtls_ssl_config>() as u32) as *mut mbedtls_ssl_config;
321330
if ssl_config.is_null() {
331+
free(drbg_context as *const _);
322332
free(ssl_context as *const _);
323333
return Err(TlsError::OutOfMemory);
324334
}
@@ -365,12 +375,31 @@ impl<'a> Certificates<'a> {
365375
mbedtls_ctr_drbg_init(drbg_context);
366376
mbedtls_ssl_conf_rng(ssl_config, Some(rng), drbg_context as *mut c_void);
367377

368-
error_checked!(mbedtls_ssl_config_defaults(
369-
ssl_config,
370-
mode.to_mbed_tls(),
371-
MBEDTLS_SSL_TRANSPORT_STREAM as i32,
372-
MBEDTLS_SSL_PRESET_DEFAULT as i32,
373-
))?;
378+
// Closure to free all allocated resources in case of an error.
379+
let cleanup = || {
380+
mbedtls_ctr_drbg_free(drbg_context);
381+
mbedtls_ssl_config_free(ssl_config);
382+
mbedtls_ssl_free(ssl_context);
383+
mbedtls_x509_crt_free(crt);
384+
mbedtls_x509_crt_free(certificate);
385+
mbedtls_pk_free(private_key);
386+
free(drbg_context as *const _);
387+
free(ssl_context as *const _);
388+
free(ssl_config as *const _);
389+
free(crt as *const _);
390+
free(certificate as *const _);
391+
free(private_key as *const _);
392+
};
393+
394+
error_checked!(
395+
mbedtls_ssl_config_defaults(
396+
ssl_config,
397+
mode.to_mbed_tls(),
398+
MBEDTLS_SSL_TRANSPORT_STREAM as i32,
399+
MBEDTLS_SSL_PRESET_DEFAULT as i32,
400+
),
401+
cleanup
402+
)?;
374403

375404
mbedtls_ssl_conf_min_version(
376405
ssl_config,
@@ -393,36 +422,40 @@ impl<'a> Certificates<'a> {
393422
let mut hostname = StrBuf::new();
394423
hostname.append(servername);
395424
hostname.append_char('\0');
396-
error_checked!(mbedtls_ssl_set_hostname(
397-
ssl_context,
398-
hostname.as_str_ref().as_ptr() as *const c_char
399-
))?;
425+
error_checked!(
426+
mbedtls_ssl_set_hostname(
427+
ssl_context,
428+
hostname.as_str_ref().as_ptr() as *const c_char
429+
),
430+
cleanup
431+
)?;
400432
}
401433

402434
if let Some(ca_chain) = self.ca_chain {
403-
error_checked!(mbedtls_x509_crt_parse(
404-
crt,
405-
ca_chain.as_ptr(),
406-
ca_chain.len(),
407-
))?;
435+
error_checked!(
436+
mbedtls_x509_crt_parse(crt, ca_chain.as_ptr(), ca_chain.len()),
437+
cleanup
438+
)?;
408439
}
409440

410441
if let (Some(cert), Some(key)) = (self.certificate, self.private_key) {
411442
// Certificate
412443
match cert.format {
413444
CertificateFormat::PEM => {
414-
error_checked!(mbedtls_x509_crt_parse(
415-
certificate,
416-
cert.as_ptr(),
417-
cert.len(),
418-
))?;
445+
error_checked!(
446+
mbedtls_x509_crt_parse(certificate, cert.as_ptr(), cert.len()),
447+
cleanup
448+
)?;
419449
}
420450
CertificateFormat::DER => {
421-
error_checked!(mbedtls_x509_crt_parse_der_nocopy(
422-
certificate,
423-
cert.as_ptr(),
424-
cert.len(),
425-
))?;
451+
error_checked!(
452+
mbedtls_x509_crt_parse_der_nocopy(
453+
certificate,
454+
cert.as_ptr(),
455+
cert.len(),
456+
),
457+
cleanup
458+
)?;
426459
}
427460
}
428461

@@ -432,21 +465,24 @@ impl<'a> Certificates<'a> {
432465
} else {
433466
(core::ptr::null(), 0)
434467
};
435-
error_checked!(mbedtls_pk_parse_key(
436-
private_key,
437-
key.as_ptr(),
438-
key.len(),
439-
password_ptr,
440-
password_len,
441-
None,
442-
core::ptr::null_mut(),
443-
))?;
468+
error_checked!(
469+
mbedtls_pk_parse_key(
470+
private_key,
471+
key.as_ptr(),
472+
key.len(),
473+
password_ptr,
474+
password_len,
475+
None,
476+
core::ptr::null_mut(),
477+
),
478+
cleanup
479+
)?;
444480

445481
mbedtls_ssl_conf_own_cert(ssl_config, certificate, private_key);
446482
}
447483

448484
mbedtls_ssl_conf_ca_chain(ssl_config, crt, core::ptr::null_mut());
449-
error_checked!(mbedtls_ssl_setup(ssl_context, ssl_config))?;
485+
error_checked!(mbedtls_ssl_setup(ssl_context, ssl_config), cleanup)?;
450486
Ok((
451487
drbg_context,
452488
ssl_context,

0 commit comments

Comments
 (0)