From f270724242fdf5a284f7b876533d54122423813c Mon Sep 17 00:00:00 2001 From: ag-ramachandran Date: Wed, 4 Feb 2026 12:52:15 +0530 Subject: [PATCH 1/2] out_azure_kusto: Defer close old resource handles in next cycle Signed-off-by: ag-ramachandran --- plugins/out_azure_kusto/azure_kusto.h | 6 ++++ plugins/out_azure_kusto/azure_kusto_conf.c | 39 ++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/plugins/out_azure_kusto/azure_kusto.h b/plugins/out_azure_kusto/azure_kusto.h index 5da2d9b5593..6100c746559 100644 --- a/plugins/out_azure_kusto/azure_kusto.h +++ b/plugins/out_azure_kusto/azure_kusto.h @@ -84,6 +84,12 @@ struct flb_azure_kusto_resources { /* used to reload resouces after some time */ uint64_t load_time; + + /* Old resources pending cleanup - deferred destruction to avoid use-after-free + * when other threads may still be using them during high-volume operations */ + struct flb_upstream_ha *old_blob_ha; + struct flb_upstream_ha *old_queue_ha; + flb_sds_t old_identity_token; }; struct flb_azure_kusto { diff --git a/plugins/out_azure_kusto/azure_kusto_conf.c b/plugins/out_azure_kusto/azure_kusto_conf.c index f0945612923..b7f8661375e 100644 --- a/plugins/out_azure_kusto/azure_kusto_conf.c +++ b/plugins/out_azure_kusto/azure_kusto_conf.c @@ -145,6 +145,22 @@ static int flb_azure_kusto_resources_clear(struct flb_azure_kusto_resources *res resources->identity_token = NULL; } + /* Also clean up any old resources pending destruction */ + if (resources->old_blob_ha) { + flb_upstream_ha_destroy(resources->old_blob_ha); + resources->old_blob_ha = NULL; + } + + if (resources->old_queue_ha) { + flb_upstream_ha_destroy(resources->old_queue_ha); + resources->old_queue_ha = NULL; + } + + if (resources->old_identity_token) { + flb_sds_destroy(resources->old_identity_token); + resources->old_identity_token = NULL; + } + resources->load_time = 0; return 0; @@ -598,6 +614,29 @@ int azure_kusto_load_ingestion_resources(struct flb_azure_kusto *ctx, parse_ingestion_identity_token(ctx, response); if (identity_token) { + /* Deferred cleanup: destroy resources from two refresh cycles ago, + * then move current resources to 'old' before assigning new ones. + * This avoids use-after-free when other threads may still be using + * the current resources during high-volume operations. */ + if (ctx->resources->old_blob_ha) { + flb_upstream_ha_destroy(ctx->resources->old_blob_ha); + flb_plg_debug(ctx->ins, "clearing up old blob HA"); + } + if (ctx->resources->old_queue_ha) { + flb_upstream_ha_destroy(ctx->resources->old_queue_ha); + flb_plg_debug(ctx->ins, "clearing up old queue HA"); + } + if (ctx->resources->old_identity_token) { + flb_sds_destroy(ctx->resources->old_identity_token); + flb_plg_debug(ctx->ins, "clearing up old identity token"); + } + + /* Move current to old */ + ctx->resources->old_blob_ha = ctx->resources->blob_ha; + ctx->resources->old_queue_ha = ctx->resources->queue_ha; + ctx->resources->old_identity_token = ctx->resources->identity_token; + + /* Assign new resources */ ctx->resources->blob_ha = blob_ha; ctx->resources->queue_ha = queue_ha; ctx->resources->identity_token = identity_token; From c2a75c8c669a54a3d7c8d94e56ce8830da3e29dd Mon Sep 17 00:00:00 2001 From: ag-ramachandran Date: Wed, 4 Feb 2026 14:17:05 +0530 Subject: [PATCH 2/2] out_azure_kusto: Add comments & logs for cleanup Signed-off-by: ag-ramachandran --- plugins/out_azure_kusto/azure_kusto_conf.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/plugins/out_azure_kusto/azure_kusto_conf.c b/plugins/out_azure_kusto/azure_kusto_conf.c index b7f8661375e..7ba0b4b852a 100644 --- a/plugins/out_azure_kusto/azure_kusto_conf.c +++ b/plugins/out_azure_kusto/azure_kusto_conf.c @@ -614,10 +614,17 @@ int azure_kusto_load_ingestion_resources(struct flb_azure_kusto *ctx, parse_ingestion_identity_token(ctx, response); if (identity_token) { - /* Deferred cleanup: destroy resources from two refresh cycles ago, - * then move current resources to 'old' before assigning new ones. - * This avoids use-after-free when other threads may still be using - * the current resources during high-volume operations. */ + /* + Deferred cleanup: destroy resources from two refresh cycles ago, + then move current resources to 'old' before assigning new ones. + This avoids use-after-free when other threads may still be using + the current resources during high-volume operations. + + With a 1-hour refresh interval, the race condition requires an + ingest operation to take >1 hour (the deferred cleanup grace period). + This is extremely unlikely under normal conditions (and hence a lock based + mechanism is avoided for performance). + */ if (ctx->resources->old_blob_ha) { flb_upstream_ha_destroy(ctx->resources->old_blob_ha); flb_plg_debug(ctx->ins, "clearing up old blob HA"); @@ -642,6 +649,9 @@ int azure_kusto_load_ingestion_resources(struct flb_azure_kusto *ctx, ctx->resources->identity_token = identity_token; ctx->resources->load_time = now; + flb_plg_info(ctx->ins, "ingestion resources rotated successfully, " + "previous resources moved to deferred cleanup"); + ret = 0; } else {