Several resources were leaked on both success and error paths:
- X509_NAME *nm was never freed. X509_REQ_set_subject_name() makes
an internal copy, so nm must be freed separately by the caller.
- str_san allocated via my_strndup() was never freed on either path.
- On error paths after allocation, x (X509_REQ) and exts
(STACK_OF(X509_EXTENSION)) were also leaked.
Fix this by adding proper cleanup of all allocated resources in both
the success and error paths. Also move sk_X509_EXTENSION_pop_free()
after X509_REQ_sign() so it is not skipped when sign fails, and
initialize nm to NULL to make early error paths safe.
Must be backported as far as 3.3.
---
src/acme.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/acme.c b/src/acme.c
index c3611a199..61cce4c79 100644
--- a/src/acme.c
+++ b/src/acme.c
@@ -2526,7 +2526,7 @@ X509_REQ *acme_x509_req(EVP_PKEY *pkey, char **san)
{
struct buffer *san_trash = NULL;
X509_REQ *x = NULL;
- X509_NAME *nm;
+ X509_NAME *nm = NULL;
STACK_OF(X509_EXTENSION) *exts = NULL;
X509_EXTENSION *ext_san;
char *str_san = NULL;
@@ -2569,16 +2569,21 @@ X509_REQ *acme_x509_req(EVP_PKEY *pkey, char **san)
if (!X509_REQ_add_extensions(x, exts))
goto error;
- sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
-
if (!X509_REQ_sign(x, pkey, EVP_sha256()))
goto error;
+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+ X509_NAME_free(nm);
+ free(str_san);
free_trash_chunk(san_trash);
return x;
error:
+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+ X509_REQ_free(x);
+ X509_NAME_free(nm);
+ free(str_san);
free_trash_chunk(san_trash);
return NULL;
--
2.53.0