summaryrefslogtreecommitdiffstats
path: root/crypto/http
diff options
context:
space:
mode:
authorTomas Mraz <tomas@openssl.org>2021-06-07 16:56:20 +0200
committerPauli <pauli@openssl.org>2021-06-10 18:27:15 +1000
commitde5a0198b22c36884fd36021d9e4f589b939674f (patch)
tree68879b5d7c9004aa3c0237b2204c4aa1f06d43cd /crypto/http
parent5a9dbfc58ab280ec426ed013f5aed5a5660b938a (diff)
Fix use after free in OSSL_HTTP_REQ_CTX_set1_req()
Fixes #15647 Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15648)
Diffstat (limited to 'crypto/http')
-rw-r--r--crypto/http/http_client.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/crypto/http/http_client.c b/crypto/http/http_client.c
index e7e0183b59..79fe9ccd41 100644
--- a/crypto/http/http_client.c
+++ b/crypto/http/http_client.c
@@ -126,7 +126,8 @@ void OSSL_HTTP_REQ_CTX_free(OSSL_HTTP_REQ_CTX *rctx)
if (rctx->free_wbio)
BIO_free_all(rctx->wbio);
/* do not free rctx->rbio */
- BIO_free(rctx->mem); /* this may indirectly call ERR_clear_error() */
+ BIO_free(rctx->mem);
+ BIO_free(rctx->req);
OPENSSL_free(rctx->buf);
OPENSSL_free(rctx->proxy);
OPENSSL_free(rctx->server);
@@ -260,8 +261,8 @@ int OSSL_HTTP_REQ_CTX_set_expected(OSSL_HTTP_REQ_CTX *rctx,
return 1;
}
-static int set_content(OSSL_HTTP_REQ_CTX *rctx,
- const char *content_type, BIO *req)
+static int set1_content(OSSL_HTTP_REQ_CTX *rctx,
+ const char *content_type, BIO *req)
{
long req_len;
@@ -285,10 +286,16 @@ static int set_content(OSSL_HTTP_REQ_CTX *rctx,
&& BIO_printf(rctx->mem, "Content-Type: %s\r\n", content_type) <= 0)
return 0;
- rctx->req = req;
- if ((req_len = BIO_ctrl(req, BIO_CTRL_INFO, 0, NULL)) <= 0)
- return 1; /* streaming BIO may not support querying size */
- return BIO_printf(rctx->mem, "Content-Length: %ld\r\n", req_len) > 0;
+ /* streaming BIO may not support querying size */
+ if ((req_len = BIO_ctrl(req, BIO_CTRL_INFO, 0, NULL)) <= 0
+ || BIO_printf(rctx->mem, "Content-Length: %ld\r\n", req_len) > 0) {
+ if (!BIO_up_ref(req))
+ return 0;
+ BIO_free(rctx->req);
+ rctx->req = req;
+ return 1;
+ }
+ return 0;
}
int OSSL_HTTP_REQ_CTX_set1_req(OSSL_HTTP_REQ_CTX *rctx, const char *content_type,
@@ -303,7 +310,7 @@ int OSSL_HTTP_REQ_CTX_set1_req(OSSL_HTTP_REQ_CTX *rctx, const char *content_type
}
res = (mem = ASN1_item_i2d_mem_bio(it, req)) != NULL
- && set_content(rctx, content_type, mem);
+ && set1_content(rctx, content_type, mem);
BIO_free(mem);
return res;
}
@@ -965,7 +972,7 @@ int OSSL_HTTP_set_request(OSSL_HTTP_REQ_CTX *rctx, const char *path,
&& add1_headers(rctx, headers, rctx->server)
&& OSSL_HTTP_REQ_CTX_set_expected(rctx, expected_content_type,
expect_asn1, timeout, keep_alive)
- && set_content(rctx, content_type, req);
+ && set1_content(rctx, content_type, req);
}
/*-