From 3d8cce08c8bebf3054e601a8c3dc21b4bd8fd790 Mon Sep 17 00:00:00 2001 From: tb <> Date: Sat, 13 Apr 2019 18:04:05 +0000 Subject: Avoid leak in SSL_dup_CA_list() In the case that X509_NAME_dup() succeeds, but sk_X509_NAME_push() fails, name is leaked. The entire function is trying to be clever and therefore hard to follow. Let's do it the stupid but safe way. ok jsing --- src/lib/libssl/ssl_cert.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src/lib') diff --git a/src/lib/libssl/ssl_cert.c b/src/lib/libssl/ssl_cert.c index 6c00b0d336..4641ac92d0 100644 --- a/src/lib/libssl/ssl_cert.c +++ b/src/lib/libssl/ssl_cert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_cert.c,v 1.74 2019/03/25 17:33:26 jsing Exp $ */ +/* $OpenBSD: ssl_cert.c,v 1.75 2019/04/13 18:04:05 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -466,17 +466,23 @@ SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk) { int i; STACK_OF(X509_NAME) *ret; - X509_NAME *name; + X509_NAME *name = NULL; + + if ((ret = sk_X509_NAME_new_null()) == NULL) + goto err; - ret = sk_X509_NAME_new_null(); for (i = 0; i < sk_X509_NAME_num(sk); i++) { - name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); - if ((name == NULL) || !sk_X509_NAME_push(ret, name)) { - sk_X509_NAME_pop_free(ret, X509_NAME_free); - return (NULL); - } + if ((name = X509_NAME_dup(sk_X509_NAME_value(sk, i))) == NULL) + goto err; + if (!sk_X509_NAME_push(ret, name)) + goto err; } return (ret); + + err: + X509_NAME_free(name); + sk_X509_NAME_pop_free(ret, X509_NAME_free); + return NULL; } void -- cgit v1.2.3-55-g6feb