summaryrefslogtreecommitdiffstats
path: root/src/crypto
diff options
context:
space:
mode:
authorMichael Brown2025-03-31 18:44:59 +0200
committerMichael Brown2025-03-31 19:05:11 +0200
commit0a48bb32145ce14b11d5d1e2a537d3d567489385 (patch)
treec40acc641986801e9b1725879ef0fb0b561f71a1 /src/crypto
parent[tls] Support fragmentation of transmitted records (diff)
downloadipxe-0a48bb32145ce14b11d5d1e2a537d3d567489385.tar.gz
ipxe-0a48bb32145ce14b11d5d1e2a537d3d567489385.tar.xz
ipxe-0a48bb32145ce14b11d5d1e2a537d3d567489385.zip
[x509] Ensure certificate remains valid during x509_append()
The allocation of memory for the certificate chain link may cause the certificate itself to be freed by the cache discarder, if the only current reference to the certificate is held by the certificate store and the system runs out of memory during the call to malloc(). Ensure that this cannot happen by taking out a temporary additional reference to the certificate within x509_append(), rather than requiring the caller to do so. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/crypto')
-rw-r--r--src/crypto/x509.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/crypto/x509.c b/src/crypto/x509.c
index acb27411a..10bc6369a 100644
--- a/src/crypto/x509.c
+++ b/src/crypto/x509.c
@@ -1634,11 +1634,17 @@ struct x509_chain * x509_alloc_chain ( void ) {
*/
int x509_append ( struct x509_chain *chain, struct x509_certificate *cert ) {
struct x509_link *link;
+ int rc;
+
+ /* Ensure allocation of link cannot invalidate certificate */
+ x509_get ( cert );
/* Allocate link */
link = zalloc ( sizeof ( *link ) );
- if ( ! link )
- return -ENOMEM;
+ if ( ! link ) {
+ rc = -ENOMEM;
+ goto err_alloc;
+ }
/* Add link to chain */
link->cert = x509_get ( cert );
@@ -1646,7 +1652,12 @@ int x509_append ( struct x509_chain *chain, struct x509_certificate *cert ) {
DBGC ( chain, "X509 chain %p added X509 %p \"%s\"\n",
chain, cert, x509_name ( cert ) );
- return 0;
+ /* Success */
+ rc = 0;
+
+ x509_put ( cert );
+ err_alloc:
+ return rc;
}
/**