diff --git a/SPECS/fluent-bit/CVE-2025-62408.patch b/SPECS/fluent-bit/CVE-2025-62408.patch new file mode 100644 index 00000000000..9f46ab6e5f0 --- /dev/null +++ b/SPECS/fluent-bit/CVE-2025-62408.patch @@ -0,0 +1,266 @@ +From 38bffdf0b097a45e9b1ab681c3ee29a6b1d77cfc Mon Sep 17 00:00:00 2001 +From: AllSpark +Date: Thu, 11 Dec 2025 08:49:23 +0000 +Subject: [PATCH] Backport patch: requeue/endqueue combined, delayed callbacks + in process_answer, qcache insert duplicates DNS record, adjust prototypes; + notify empty queue + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: AI Backport of https://github.com/c-ares/c-ares/commit/714bf5675c541bd1e668a8db8e67ce012651e618.patch +--- + lib/c-ares-1.33.1/src/lib/ares_private.h | 10 +-- + lib/c-ares-1.33.1/src/lib/ares_process.c | 92 +++++++++++++++++++----- + lib/c-ares-1.33.1/src/lib/ares_qcache.c | 20 ++++-- + 3 files changed, 93 insertions(+), 29 deletions(-) + +diff --git a/lib/c-ares-1.33.1/src/lib/ares_private.h b/lib/c-ares-1.33.1/src/lib/ares_private.h +index 2605c9e..c1bf536 100644 +--- a/lib/c-ares-1.33.1/src/lib/ares_private.h ++++ b/lib/c-ares-1.33.1/src/lib/ares_private.h +@@ -466,7 +466,7 @@ ares_status_t ares__requeue_query(ares_query_t *query, + const ares_timeval_t *now, + ares_status_t status, + ares_bool_t inc_try_count, +- const ares_dns_record_t *dnsrec, ++ ares_dns_record_t *dnsrec, + ares__array_t **requeue); + + /*! Count the number of labels (dots+1) in a domain */ +@@ -764,10 +764,10 @@ ares_status_t ares__qcache_create(ares_rand_state *rand_state, + unsigned int max_ttl, + ares__qcache_t **cache_out); + void ares__qcache_flush(ares__qcache_t *cache); +-ares_status_t ares_qcache_insert(ares_channel_t *channel, +- const ares_timeval_t *now, +- const ares_query_t *query, +- ares_dns_record_t *dnsrec); ++ares_status_t ares_qcache_insert(ares_channel_t *channel, ++ const ares_timeval_t *now, ++ const ares_query_t *query, ++ const ares_dns_record_t *dnsrec); + ares_status_t ares_qcache_fetch(ares_channel_t *channel, + const ares_timeval_t *now, + const ares_dns_record_t *dnsrec, +diff --git a/lib/c-ares-1.33.1/src/lib/ares_process.c b/lib/c-ares-1.33.1/src/lib/ares_process.c +index e84c36a..754ff91 100644 +--- a/lib/c-ares-1.33.1/src/lib/ares_process.c ++++ b/lib/c-ares-1.33.1/src/lib/ares_process.c +@@ -66,7 +66,8 @@ static ares_bool_t same_address(const struct sockaddr *sa, + const struct ares_addr *aa); + static void end_query(ares_channel_t *channel, ares_server_t *server, + ares_query_t *query, ares_status_t status, +- const ares_dns_record_t *dnsrec); ++ ares_dns_record_t *dnsrec, ++ ares__array_t **requeue); + + static void ares__query_disassociate_from_conn(ares_query_t *query) + { +@@ -300,16 +301,27 @@ static void write_tcp_data(ares_channel_t *channel, fd_set *write_fds, + } + } + ++typedef enum { ++ REQUEUE_REQUEUE = 1, ++ REQUEUE_ENDQUERY = 2 ++} requeue_type_t; ++ + /* Simple data structure to store a query that needs to be requeued with + * optional server */ + typedef struct { +- unsigned short qid; +- ares_server_t *server; /* optional */ ++ requeue_type_t type; /* type of entry, requeue or endquery */ ++ unsigned short qid; /* query id */ ++ ares_server_t *server; /* requeue only: optional */ ++ ares_status_t status; /* endquery only */ ++ ares_dns_record_t *dnsrec; /* endquery only: optional */ + } ares_requeue_t; + +-static ares_status_t ares_append_requeue(ares__array_t **requeue, +- ares_query_t *query, +- ares_server_t *server) ++static ares_status_t ares_append_requeue_int(ares__array_t **requeue, ++ requeue_type_t type, ++ ares_query_t *query, ++ ares_server_t *server, ++ ares_status_t status, ++ ares_dns_record_t *dnsrec) + { + ares_requeue_t entry; + +@@ -322,11 +334,31 @@ static ares_status_t ares_append_requeue(ares__array_t **requeue, + + ares__query_disassociate_from_conn(query); + ++ entry.type = type; + entry.qid = query->qid; + entry.server = server; ++ entry.status = status; ++ entry.dnsrec = dnsrec; + return ares__array_insertdata_last(*requeue, &entry); + } + ++static ares_status_t ares_append_requeue(ares__array_t **requeue, ++ ares_query_t *query, ++ ares_server_t *server) ++{ ++ return ares_append_requeue_int(requeue, REQUEUE_REQUEUE, query, server, 0, ++ NULL); ++} ++ ++static ares_status_t ares_append_endqueue(ares__array_t **requeue, ++ ares_query_t *query, ++ ares_status_t status, ++ ares_dns_record_t *dnsrec) ++{ ++ return ares_append_requeue_int(requeue, REQUEUE_ENDQUERY, query, NULL, status, ++ dnsrec); ++} ++ + + /* If any TCP socket selects true for reading, read some data, + * allocate a buffer if we finish reading the length word, and process +@@ -423,13 +455,25 @@ cleanup: + break; + } + +- /* Query disappeared */ + query = ares__htable_szvp_get_direct(channel->queries_by_qid, entry.qid); +- if (query == NULL) { +- continue; +- } + +- ares__send_query(query, now); ++ if (entry.type == REQUEUE_REQUEUE) { ++ /* Query disappeared */ ++ if (query == NULL) { ++ continue; ++ } ++ ares__send_query(query, now); ++ } else { /* REQUEUE_ENDQUERY */ ++ if (query != NULL) { ++ query->callback(query->arg, entry.status, query->timeouts, entry.dnsrec); ++ ares__free_query(query); ++ } ++ ares_dns_record_destroy(entry.dnsrec); ++ } ++ } ++ /* Don't forget to send notification if queue emptied */ ++ if (requeue != NULL) { ++ ares_queue_notify_empty(channel); + } + ares__array_destroy(requeue); + } +@@ -558,6 +602,10 @@ cleanup: + + ares__send_query(query, now); + } ++ /* Don't forget to send notification if queue emptied */ ++ if (requeue != NULL) { ++ ares_queue_notify_empty(channel); ++ } + ares__array_destroy(requeue); + } + +@@ -749,7 +797,7 @@ static ares_status_t process_answer(ares_channel_t *channel, + ares_dns_get_opt_rr_const(rdnsrec) == NULL) { + status = rewrite_without_edns(query); + if (status != ARES_SUCCESS) { +- end_query(channel, server, query, status, NULL); ++ end_query(channel, server, query, status, NULL, NULL); + goto cleanup; + } + +@@ -795,6 +843,7 @@ static ares_status_t process_answer(ares_channel_t *channel, + server_increment_failures(server, query->using_tcp); + status = ares__requeue_query(query, now, status, ARES_TRUE, rdnsrec, + requeue); ++ rdnsrec = NULL; /* Free'd by ares__requeue_query() */ + + if (status != ARES_ENOMEM) { + /* Should any of these cause a connection termination? +@@ -807,12 +856,11 @@ static ares_status_t process_answer(ares_channel_t *channel, + + /* If cache insertion was successful, it took ownership. We ignore + * other cache insertion failures. */ +- if (ares_qcache_insert(channel, now, query, rdnsrec) == ARES_SUCCESS) { +- is_cached = ARES_TRUE; +- } ++ ares_qcache_insert(channel, now, query, rdnsrec); + + server_set_good(server, query->using_tcp); +- end_query(channel, server, query, ARES_SUCCESS, rdnsrec); ++ end_query(channel, server, query, ARES_SUCCESS, rdnsrec, requeue); ++ rdnsrec = NULL; /* Free'd by the requeue */ + + status = ARES_SUCCESS; + +@@ -845,7 +893,7 @@ ares_status_t ares__requeue_query(ares_query_t *query, + const ares_timeval_t *now, + ares_status_t status, + ares_bool_t inc_try_count, +- const ares_dns_record_t *dnsrec, ++ ares_dns_record_t *dnsrec, + ares__array_t **requeue) + { + ares_channel_t *channel = query->channel; +@@ -873,7 +921,7 @@ ares_status_t ares__requeue_query(ares_query_t *query, + query->error_status = ARES_ETIMEOUT; + } + +- end_query(channel, NULL, query, query->error_status, dnsrec); ++ end_query(channel, NULL, query, query->error_status, dnsrec, requeue); + return ARES_ETIMEOUT; + } + +@@ -1344,10 +1392,16 @@ static void ares_detach_query(ares_query_t *query) + + static void end_query(ares_channel_t *channel, ares_server_t *server, + ares_query_t *query, ares_status_t status, +- const ares_dns_record_t *dnsrec) ++ ares_dns_record_t *dnsrec, ares__array_t **requeue) + { + ares_metrics_record(query, server, status, dnsrec); + ++ /* Delay calling the query callback */ ++ if (requeue != NULL) { ++ ares_append_endqueue(requeue, query, status, dnsrec); ++ return; ++ } ++ + /* Invoke the callback. */ + query->callback(query->arg, status, query->timeouts, dnsrec); + ares__free_query(query); +diff --git a/lib/c-ares-1.33.1/src/lib/ares_qcache.c b/lib/c-ares-1.33.1/src/lib/ares_qcache.c +index 9725212..3785f6b 100644 +--- a/lib/c-ares-1.33.1/src/lib/ares_qcache.c ++++ b/lib/c-ares-1.33.1/src/lib/ares_qcache.c +@@ -422,10 +422,20 @@ done: + return status; + } + +-ares_status_t ares_qcache_insert(ares_channel_t *channel, +- const ares_timeval_t *now, +- const ares_query_t *query, +- ares_dns_record_t *dnsrec) ++ares_status_t ares_qcache_insert(ares_channel_t *channel, ++ const ares_timeval_t *now, ++ const ares_query_t *query, ++ const ares_dns_record_t *dnsrec) + { +- return ares__qcache_insert(channel->qcache, dnsrec, query->query, now); ++ ares_dns_record_t *dupdns = ares_dns_record_duplicate(dnsrec); ++ ares_status_t status; ++ ++ if (dupdns == NULL) { ++ return ARES_ENOMEM; ++ } ++ status = ares__qcache_insert(channel->qcache, dupdns, query->query, now); ++ if (status != ARES_SUCCESS) { ++ ares_dns_record_destroy(dupdns); ++ } ++ return status; + } +-- +2.45.4 + diff --git a/SPECS/fluent-bit/fluent-bit.spec b/SPECS/fluent-bit/fluent-bit.spec index b2f7852f214..bdef8e922df 100644 --- a/SPECS/fluent-bit/fluent-bit.spec +++ b/SPECS/fluent-bit/fluent-bit.spec @@ -1,7 +1,7 @@ Summary: Fast and Lightweight Log processor and forwarder for Linux, BSD and OSX Name: fluent-bit Version: 3.1.10 -Release: 2%{?dist} +Release: 3%{?dist} License: Apache-2.0 Vendor: Microsoft Corporation Distribution: Azure Linux @@ -16,6 +16,7 @@ Patch5: CVE-2025-31498.patch Patch6: CVE-2025-54126.patch Patch7: CVE-2025-58749.patch Patch8: CVE-2025-12970.patch +Patch9: CVE-2025-62408.patch BuildRequires: bison BuildRequires: cmake BuildRequires: cyrus-sasl-devel @@ -90,6 +91,9 @@ Development files for %{name} %{_libdir}/fluent-bit/*.so %changelog +* Thu Dec 11 2025 Azure Linux Security Servicing Account - 3.1.10-3 +- Patch for CVE-2025-62408 + * Mon Dec 01 2025 Azure Linux Security Servicing Account - 3.1.10-2 - Patch for CVE-2025-12970