Index | Thread | Search

From:
Marc Jorge <openbsd@cypher-fox.com>
Subject:
relayd: free original cert after X509_dup in ssl_update_certificate
To:
tech@openbsd.org
Date:
Wed, 20 May 2026 23:01:23 +0200

Download raw body.

Thread
Hello,

In ssl_update_certificate, X509_dup was called on the same cert 
variable, causing a leak of the initial certificate.



ssl_update_certificate: original cert ptr: 0x53335ca18c0
ssl_update_certificate: duplicated cert ptr: 0x53335c91620
ssl_update_certificate: executing X509_free(cert)...
ssl_update_certificate: The original certificate remains in memory:
     Certificate:
     ....
     Signature Algorithm: ecdsa-with-SHA384
         Issuer: C=US, O=Let's Encrypt, CN=E8
     ....


Index: usr.sbin/relayd/ssl.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/ssl.c,v
diff -u -p -u -r1.39 ssl.c
--- usr.sbin/relayd/ssl.c	16 May 2026 13:16:50 -0000	1.39
+++ usr.sbin/relayd/ssl.c	20 May 2026 20:54:13 -0000
@@ -104,6 +104,7 @@ ssl_update_certificate(const uint8_t *ol
  	BIO		*in, *out = NULL;
  	BUF_MEM		*bptr = NULL;
  	X509		*cert = NULL;
+	X509		*cert_dup = NULL;
  	uint8_t		*newcert = NULL;

  	if ((in = BIO_new_mem_buf(oldcert, oldlen)) == NULL) {
@@ -127,8 +128,11 @@ ssl_update_certificate(const uint8_t *ol
  	    name[1], sizeof(name[1])))
  		goto done;

-	if ((cert = X509_dup(cert)) == NULL)
+	if ((cert_dup = X509_dup(cert)) == NULL)
  		goto done;
+
+	X509_free(cert);
+	cert = cert_dup;

  	/* Update certificate key and use our CA as the issuer */
  	X509_set_pubkey(cert, pkey);