summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2020-10-09 17:19:35 +0000
committertb <>2020-10-09 17:19:35 +0000
commitc2d858c793f1c66f3c541ebc3f6d0bf4deb3b7e7 (patch)
treecb5721a23a34e4af109398c549587aded00d68d7
parentacf6e4c16993f0fa6153452c6141084e0c84afc3 (diff)
downloadopenbsd-c2d858c793f1c66f3c541ebc3f6d0bf4deb3b7e7.tar.gz
openbsd-c2d858c793f1c66f3c541ebc3f6d0bf4deb3b7e7.tar.bz2
openbsd-c2d858c793f1c66f3c541ebc3f6d0bf4deb3b7e7.zip
Fix leak or double free with OCSP_request_add0_id()
On success, OCSP_request_add0_id() transfers ownership of cid to either 'one' or 'req' depending on whether the latter is NULL or not. On failure, the caller can't tell whether OCSP_ONEREQ_new() failed (in which case cid needs to be freed) or whether it was a failure to allocate memory in sk_insert() (in which case cid must not be freed). The caller is thus faced with the choice of leaving either a leak or a potential double free. Fix this by transferring ownership only at the end of the function. Found while reviewing an upcoming diff by beck. ok jsing
-rw-r--r--src/lib/libcrypto/ocsp/ocsp_cl.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/src/lib/libcrypto/ocsp/ocsp_cl.c b/src/lib/libcrypto/ocsp/ocsp_cl.c
index 0ed816cdc3..cb5a2f3d18 100644
--- a/src/lib/libcrypto/ocsp/ocsp_cl.c
+++ b/src/lib/libcrypto/ocsp/ocsp_cl.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ocsp_cl.c,v 1.16 2018/11/25 19:48:43 jmc Exp $ */ 1/* $OpenBSD: ocsp_cl.c,v 1.17 2020/10/09 17:19:35 tb Exp $ */
2/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL 2/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
3 * project. */ 3 * project. */
4 4
@@ -81,18 +81,19 @@
81OCSP_ONEREQ * 81OCSP_ONEREQ *
82OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid) 82OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid)
83{ 83{
84 OCSP_ONEREQ *one = NULL; 84 OCSP_ONEREQ *one;
85 85
86 if (!(one = OCSP_ONEREQ_new())) 86 if ((one = OCSP_ONEREQ_new()) == NULL)
87 goto err; 87 goto err;
88 if (one->reqCert) 88 if (req != NULL) {
89 OCSP_CERTID_free(one->reqCert); 89 if (!sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one))
90 goto err;
91 }
92 OCSP_CERTID_free(one->reqCert);
90 one->reqCert = cid; 93 one->reqCert = cid;
91 if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one))
92 goto err;
93 return one; 94 return one;
94 95
95err: 96 err:
96 OCSP_ONEREQ_free(one); 97 OCSP_ONEREQ_free(one);
97 return NULL; 98 return NULL;
98} 99}