From c4c9e070f35c113b8b9c4d79ca1b9c1afe87d0e4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 5 Sep 2019 00:08:21 +0200 Subject: [PATCH] Curl_fillreadbuffer: avoid double-free trailer buf on error Reviewed-by: Jay Satiro Reported-by: Thomas Vegas Closes #4307 --- lib/http.c | 16 ++++++++++------ lib/http.h | 2 +- lib/transfer.c | 11 ++++++----- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/lib/http.c b/lib/http.c index d352d139d..28d1fa607 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1146,10 +1146,14 @@ Curl_send_buffer *Curl_add_buffer_init(void) */ void Curl_add_buffer_free(Curl_send_buffer **inp) { - Curl_send_buffer *in = *inp; - if(in) /* deal with NULL input */ + Curl_send_buffer *in; + if(!inp) + return; + in = *inp; + if(in) { /* deal with NULL input */ free(in->buffer); - free(in); + free(in); + } *inp = NULL; } @@ -1720,7 +1724,7 @@ enum proxy_use { will return an error code if one of the headers is not formatted correctly */ CURLcode Curl_http_compile_trailers(struct curl_slist *trailers, - Curl_send_buffer *buffer, + Curl_send_buffer **buffer, struct Curl_easy *handle) { char *ptr = NULL; @@ -1746,7 +1750,7 @@ CURLcode Curl_http_compile_trailers(struct curl_slist *trailers, /* only add correctly formatted trailers */ ptr = strchr(trailers->data, ':'); if(ptr && *(ptr + 1) == ' ') { - result = Curl_add_bufferf(&buffer, "%s%s", trailers->data, + result = Curl_add_bufferf(buffer, "%s%s", trailers->data, endofline_native); if(result) return result; @@ -1755,7 +1759,7 @@ CURLcode Curl_http_compile_trailers(struct curl_slist *trailers, infof(handle, "Malformatted trailing header ! Skipping trailer."); trailers = trailers->next; } - result = Curl_add_buffer(&buffer, endofline_network, + result = Curl_add_buffer(buffer, endofline_network, strlen(endofline_network)); return result; } diff --git a/lib/http.h b/lib/http.h index 5bacb1754..f0ddec759 100644 --- a/lib/http.h +++ b/lib/http.h @@ -75,7 +75,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, bool is_connect, Curl_send_buffer *req_buffer); CURLcode Curl_http_compile_trailers(struct curl_slist *trailers, - Curl_send_buffer *buffer, + Curl_send_buffer **buffer, struct Curl_easy *handle); /* protocol-specific functions set up to be called by the main engine */ diff --git a/lib/transfer.c b/lib/transfer.c index 7e57fbe03..ef0d80638 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -176,7 +176,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes, #ifndef CURL_DISABLE_HTTP if(data->state.trailers_state == TRAILERS_INITIALIZED) { struct curl_slist *trailers = NULL; - CURLcode c; + CURLcode result; int trailers_ret_code; /* at this point we already verified that the callback exists @@ -195,17 +195,18 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes, data->set.trailer_data); Curl_set_in_callback(data, false); if(trailers_ret_code == CURL_TRAILERFUNC_OK) { - c = Curl_http_compile_trailers(trailers, data->state.trailers_buf, data); + result = Curl_http_compile_trailers(trailers, &data->state.trailers_buf, + data); } else { failf(data, "operation aborted by trailing headers callback"); *nreadp = 0; - c = CURLE_ABORTED_BY_CALLBACK; + result = CURLE_ABORTED_BY_CALLBACK; } - if(c != CURLE_OK) { + if(result) { Curl_add_buffer_free(&data->state.trailers_buf); curl_slist_free_all(trailers); - return c; + return result; } infof(data, "Successfully compiled trailers.\r\n"); curl_slist_free_all(trailers);