From e75b88839aa4ce9d1518437fad0055500b99768d Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Fri, 10 Apr 2026 08:27:03 +0200 Subject: [PATCH] fix: prevent memory leak in otel schema_version decode branch When thread_ctx_config is already allocated, reuse the existing struct instead of allocating a new one and leaking the old pointer. Also free the old schema_version value before reassignment if it was already set. Fixes: PROF-14142 --- ddprof-lib/src/main/cpp/otel_process_ctx.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ddprof-lib/src/main/cpp/otel_process_ctx.cpp b/ddprof-lib/src/main/cpp/otel_process_ctx.cpp index e263ff66d..1608441c1 100644 --- a/ddprof-lib/src/main/cpp/otel_process_ctx.cpp +++ b/ddprof-lib/src/main/cpp/otel_process_ctx.cpp @@ -806,10 +806,16 @@ static otel_process_ctx_result otel_process_ctx_encode_protobuf_payload(char **o // Dispatch based on key if (strcmp(key_buffer, "threadlocal.schema_version") == 0) { - otel_thread_ctx_config_data *setup = (otel_thread_ctx_config_data *) calloc(1, sizeof(otel_thread_ctx_config_data)); - if (!setup) { free(value); return false; } - setup->schema_version = value; - data_out->thread_ctx_config = setup; + if (!data_out->thread_ctx_config) { + otel_thread_ctx_config_data *setup = (otel_thread_ctx_config_data *) calloc(1, sizeof(otel_thread_ctx_config_data)); + if (!setup) { free(value); return false; } + data_out->thread_ctx_config = setup; + } else { + if (((otel_thread_ctx_config_data *)data_out->thread_ctx_config)->schema_version) { + free((void *)((otel_thread_ctx_config_data *)data_out->thread_ctx_config)->schema_version); + } + } + ((otel_thread_ctx_config_data *)data_out->thread_ctx_config)->schema_version = value; } else { char *key = strdup(key_buffer); if (!key || extra_attributes_index + 2 >= extra_attributes_capacity) {