Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
266 changes: 266 additions & 0 deletions SPECS/fluent-bit/CVE-2025-62408.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
From 38bffdf0b097a45e9b1ab681c3ee29a6b1d77cfc Mon Sep 17 00:00:00 2001
From: AllSpark <allspark@microsoft.com>
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 <azurelinux-security@microsoft.com>
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

6 changes: 5 additions & 1 deletion SPECS/fluent-bit/fluent-bit.spec
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down Expand Up @@ -90,6 +91,9 @@ Development files for %{name}
%{_libdir}/fluent-bit/*.so

%changelog
* Thu Dec 11 2025 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 3.1.10-3
- Patch for CVE-2025-62408

* Mon Dec 01 2025 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 3.1.10-2
- Patch for CVE-2025-12970

Expand Down
Loading