@cryptotaxi247 / netdata-1 / commits / 41d9554a0

Fix duplicate header leak in ACLK HTTPS client (#21084)

fix(aclk): free previous header values before overwrite Refs: netdata/netdata#21083

Costa Tsaousis committed Oct 2, 2025 at 08:49 UTC 41d9554a022dc6ba69d6587a859425198c4430a7
1 file changed +30 -10
src/aclk/https_client.c
+30 -10
@@ -147,15 +147,6 @@ static const char *http_req_type_to_str(http_req_type_t req) {
147
148 #define TRANSFER_ENCODING_CHUNKED (-2)
149
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 -
150 void http_parse_ctx_destroy(http_parse_ctx *ctx)
151 {
152 if(!ctx->headers)
@@ -175,6 +166,23 @@ void http_parse_ctx_destroy(http_parse_ctx *ctx)
166 ctx->headers = NULL;
167 }
168
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 +
186 #define POLL_TO_MS 100
187
188 #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
222 }
223 return 0;
224 }
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 +
229 char *val_cpy = strdupz(val);
230 c_rhash_insert_str_ptr(parse_ctx->headers, key, val_cpy);
231 return 0;
@@ -710,8 +722,12 @@ static https_client_resp_t handle_http_request(https_req_ctx_t *ctx) {
722 rc = read_parse_response(ctx);
723 if (rc != HTTPS_CLIENT_RESP_OK) {
724 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) {
726 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 + }
731 }
732
733 err_exit:
@@ -887,6 +903,9 @@ https_client_resp_t https_request(https_req_t *request, https_req_response_t *re
903 if (ctx->parse_ctx.content_length == TRANSFER_ENCODING_CHUNKED) {
904 response->payload_size = ctx->parse_ctx.chunked_response_size;
905 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;
909 }
910 if (ctx->parse_ctx.content_length > 0) {
911 response->payload_size = ctx->parse_ctx.content_length;
@@ -918,6 +937,7 @@ exit_sock:
937 exit_buf_rx:
938 rbuf_free(ctx->buf_rx);
939 exit_req_ctx:
940 + http_parse_ctx_destroy(&ctx->parse_ctx);
941 freez(ctx);
942 return rc;
943 }