Skip to content

Commit 41d9554

Browse files
authored
Fix duplicate header leak in ACLK HTTPS client (#21084)
fix(aclk): free previous header values before overwrite Refs: #21083
1 parent f16d13c commit 41d9554

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

src/aclk/https_client.c

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,6 @@ static const char *http_req_type_to_str(http_req_type_t req) {
147147

148148
#define TRANSFER_ENCODING_CHUNKED (-2)
149149

150-
void http_parse_ctx_create(http_parse_ctx *ctx, enum http_parse_state parse_state)
151-
{
152-
ctx->state = parse_state;
153-
ctx->content_length = -1;
154-
ctx->http_code = 0;
155-
ctx->headers = c_rhash_new(0);
156-
ctx->flags = HTTP_PARSE_FLAGS_DEFAULT;
157-
}
158-
159150
void http_parse_ctx_destroy(http_parse_ctx *ctx)
160151
{
161152
if(!ctx->headers)
@@ -175,6 +166,23 @@ void http_parse_ctx_destroy(http_parse_ctx *ctx)
175166
ctx->headers = NULL;
176167
}
177168

169+
void http_parse_ctx_create(http_parse_ctx *ctx, enum http_parse_state parse_state)
170+
{
171+
http_parse_ctx_destroy(ctx);
172+
173+
ctx->state = parse_state;
174+
ctx->content_length = -1;
175+
ctx->http_code = 0;
176+
ctx->headers = c_rhash_new(0);
177+
ctx->flags = HTTP_PARSE_FLAGS_DEFAULT;
178+
ctx->chunked_content_state = CHUNKED_CONTENT_CHUNK_SIZE;
179+
ctx->chunk_size = 0;
180+
ctx->chunk_got = 0;
181+
ctx->chunked_response_written = 0;
182+
ctx->chunked_response_size = 0;
183+
ctx->chunked_response = NULL;
184+
}
185+
178186
#define POLL_TO_MS 100
179187

180188
#define HTTP_LINE_TERM "\x0D\x0A"
@@ -214,6 +222,10 @@ static int process_http_hdr(http_parse_ctx *parse_ctx, const char *key, const ch
214222
}
215223
return 0;
216224
}
225+
void *prev_val = NULL;
226+
if (!c_rhash_get_ptr_by_str(parse_ctx->headers, key, &prev_val))
227+
freez(prev_val); // drop previous allocation before overwriting
228+
217229
char *val_cpy = strdupz(val);
218230
c_rhash_insert_str_ptr(parse_ctx->headers, key, val_cpy);
219231
return 0;
@@ -710,8 +722,12 @@ static https_client_resp_t handle_http_request(https_req_ctx_t *ctx) {
710722
rc = read_parse_response(ctx);
711723
if (rc != HTTPS_CLIENT_RESP_OK) {
712724
netdata_log_error("ACLK: error reading or parsing response from server");
713-
if (ctx->parse_ctx.chunked_response)
725+
if (ctx->parse_ctx.chunked_response) {
714726
freez(ctx->parse_ctx.chunked_response);
727+
ctx->parse_ctx.chunked_response = NULL;
728+
ctx->parse_ctx.chunked_response_size = 0;
729+
ctx->parse_ctx.chunked_response_written = 0;
730+
}
715731
}
716732

717733
err_exit:
@@ -887,6 +903,9 @@ https_client_resp_t https_request(https_req_t *request, https_req_response_t *re
887903
if (ctx->parse_ctx.content_length == TRANSFER_ENCODING_CHUNKED) {
888904
response->payload_size = ctx->parse_ctx.chunked_response_size;
889905
response->payload = ctx->parse_ctx.chunked_response;
906+
ctx->parse_ctx.chunked_response = NULL;
907+
ctx->parse_ctx.chunked_response_size = 0;
908+
ctx->parse_ctx.chunked_response_written = 0;
890909
}
891910
if (ctx->parse_ctx.content_length > 0) {
892911
response->payload_size = ctx->parse_ctx.content_length;
@@ -918,6 +937,7 @@ https_client_resp_t https_request(https_req_t *request, https_req_response_t *re
918937
exit_buf_rx:
919938
rbuf_free(ctx->buf_rx);
920939
exit_req_ctx:
940+
http_parse_ctx_destroy(&ctx->parse_ctx);
921941
freez(ctx);
922942
return rc;
923943
}

0 commit comments

Comments
 (0)