diff options
author | Tomas Mraz <tomas@openssl.org> | 2021-06-07 16:56:20 +0200 |
---|---|---|
committer | Pauli <pauli@openssl.org> | 2021-06-10 18:27:15 +1000 |
commit | de5a0198b22c36884fd36021d9e4f589b939674f (patch) | |
tree | 68879b5d7c9004aa3c0237b2204c4aa1f06d43cd | |
parent | 5a9dbfc58ab280ec426ed013f5aed5a5660b938a (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)
-rw-r--r-- | crypto/http/http_client.c | 25 |
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); } /*- |