diff --git a/SPECS/fluent-bit/CVE-2026-33630.patch b/SPECS/fluent-bit/CVE-2026-33630.patch new file mode 100644 index 00000000000..da3bc7d7806 --- /dev/null +++ b/SPECS/fluent-bit/CVE-2026-33630.patch @@ -0,0 +1,594 @@ +From d823199b688052dcdc1646f2ab4cb8c16b1c644a Mon Sep 17 00:00:00 2001 +From: Brad House +Date: Mon, 6 Jul 2026 11:19:36 -0400 +Subject: [PATCH] [Backport v1.34] Fix double-free in process_timeouts() and + consolidate requeue handling (#1237) + +Backports the double-free fix (GHSA-6wfj-rwm7-3542 / CVE-2026-33630) and the +requeue-recursion fix for #1043 to the v1.34 release branch. + +What it fixes: +- Double-free (self-cancellation): process_timeouts() invoked the query + callback without first detaching the query from queries_by_qid / + all_queries, so a reentrant ares_cancel() from the callback freed the query + which was then freed again by the caller. The same self-cancellation + double-free was also reachable via the deferred ENDQUERY flush. +- #1043 stack overflow: unbounded ares_requeue_query() -> ares_send_query() + recursion. + +Both share one root cause, deferred work being done immediately. Every flush +site now funnels through ares_flush_requeue(), which re-dispatches retries +iteratively and fully detaches each query before invoking its callback. + +Target release: 1.34.7. + +Modified to apply to Azure Linux + +The upstream commit targets the 1.34 branch and does not apply as-is to the +bundled 1.33.1 tree, which uses the older ares__ internal API (ares__array_t, +ares__send_query, ares__requeue_query), keeps read_tcp_data() and +read_udp_packets_fd() as separate functions rather than a unified +read_answers(), and has no requested_server argument on ares__send_query(). +The change was adapted accordingly: + + * ares_flush_requeue() is introduced as the single shared drain and all four + flush sites funnel through it. + * ares__send_query() is split into a public wrapper plus + ares__send_query_int(), with the wrapper re-checking queries_by_qid before + reporting success since a deferred retry may have freed the query. + * read_udp_packets_fd() previously ignored entry.type and re-sent + REQUEUE_ENDQUERY entries instead of completing them; routing it through + ares_flush_requeue() corrects that as well. + * end_query() also detaches on its remaining inline path, still reachable via + ares__requeue_query() from ares__close_connection(). + * read_tcp_data(), read_udp_packets_fd() and process_timeouts() are changed + from void to ares_status_t so that the ARES_ENOMEM result of + ares_flush_requeue() is propagated exactly as upstream does. On the 1.34 + branch read_answers() and process_timeouts() already returned a status, so + the upstream commit only had to add the check; here the signatures had to + be widened first. read_tcp_data() returns ARES_ENOMEM on its buffer + allocation failure, which is what the pre-existing "TODO: make this + function return error codes" comment there asked for. Their callers + read_packets() and processfds() stay void, as upstream does not touch them. + * The upstream regression tests are carried across, adapted to the 1.33.1 + test framework. + +Upstream Patch Reference: https://github.com/c-ares/c-ares/commit/d823199b688052dcdc1646f2ab4cb8c16b1c644a.patch + +Signed-off-by: SumitJenaHCL +--- + lib/c-ares-1.33.1/src/lib/ares_process.c | 239 ++++++++++++++++------- + lib/c-ares-1.33.1/test/ares-test-mock.cc | 108 ++++++++++ + 2 files changed, 278 insertions(+), 69 deletions(-) + +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 fa042dd..c413cc6 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 +@@ -50,7 +50,7 @@ static void write_tcp_data(ares_channel_t *channel, fd_set *write_fds, + ares_socket_t write_fd); + static void read_packets(ares_channel_t *channel, fd_set *read_fds, + ares_socket_t read_fd, const ares_timeval_t *now); +-static void process_timeouts(ares_channel_t *channel, ++static ares_status_t process_timeouts(ares_channel_t *channel, + const ares_timeval_t *now); + static ares_status_t process_answer(ares_channel_t *channel, + const unsigned char *abuf, size_t alen, +@@ -68,6 +68,10 @@ static void end_query(ares_channel_t *channel, ares_server_t *server, + ares_query_t *query, ares_status_t status, + ares_dns_record_t *dnsrec, + ares__array_t **requeue); ++static ares_status_t ares__send_query_int(ares_query_t *query, ++ const ares_timeval_t *now, ++ ares__array_t **requeue); ++static void ares_detach_query(ares_query_t *query); + + static void ares__query_disassociate_from_conn(ares_query_t *query) + { +@@ -359,16 +363,89 @@ static ares_status_t ares_append_endqueue(ares__array_t **requeue, + dnsrec); + } + ++/* Drain the deferred requeue/endqueue list iteratively. Every flush site ++ * (read_tcp_data(), read_udp_packets_fd(), process_timeouts() and ++ * ares__send_query()) funnels through here so that: ++ * 1. Retries are re-dispatched by appending back onto this same list and ++ * looping, rather than recursing ares__requeue_query() -> ++ * ares__send_query() until the stack is exhausted (upstream issue #1043). ++ * 2. A query is fully detached from all lookup lists before its callback is ++ * invoked, so a reentrant ares_cancel() from within that callback cannot ++ * find and free the same query, which would otherwise double-free it ++ * (CVE-2026-33630). ++ * ++ * On return the list has been fully processed, an empty-queue notification has ++ * been sent if appropriate, and *requeue has been destroyed and set to NULL. */ ++static ares_status_t ares_flush_requeue(ares_channel_t *channel, ++ const ares_timeval_t *now, ++ ares__array_t **requeue) ++{ ++ ares_status_t status = ARES_SUCCESS; ++ ++ if (requeue == NULL) { ++ return status; ++ } ++ ++ while (*requeue != NULL && ares__array_len(*requeue) > 0) { ++ ares_query_t *query; ++ ares_requeue_t entry; ++ ares_status_t internal_status; ++ ++ internal_status = ares__array_claim_at(&entry, sizeof(entry), *requeue, 0); ++ if (internal_status != ARES_SUCCESS) { ++ break; /* LCOV_EXCL_LINE: DefensiveCoding */ ++ } ++ ++ query = ares__htable_szvp_get_direct(channel->queries_by_qid, entry.qid); ++ ++ if (entry.type == REQUEUE_REQUEUE) { ++ /* Query disappeared (e.g. a prior callback in this drain cancelled it) */ ++ if (query == NULL) { ++ continue; ++ } ++ /* Re-dispatch via the internal entrypoint so any further requeues are ++ * appended back onto this same list and drained by the loop above, ++ * rather than recursing. */ ++ internal_status = ares__send_query_int(query, now, requeue); ++ /* We only care about ARES_ENOMEM */ ++ if (internal_status == ARES_ENOMEM) { ++ status = ARES_ENOMEM; ++ } ++ } else { /* REQUEUE_ENDQUERY */ ++ if (query != NULL) { ++ /* Detach from all lookup lists BEFORE invoking the callback, otherwise ++ * a reentrant ares_cancel() from within the callback would find this ++ * query still linked in all_queries/queries_by_qid, free it, and the ++ * ares__free_query() below would then double-free it. */ ++ ares_detach_query(query); ++ 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); ++ *requeue = NULL; ++ ++ return status; ++} ++ + /* If any TCP socket selects true for reading, read some data, + * allocate a buffer if we finish reading the length word, and process + * a packet if we finish reading one. + */ +-static void read_tcp_data(ares_channel_t *channel, ares_conn_t *conn, +- const ares_timeval_t *now) ++static ares_status_t read_tcp_data(ares_channel_t *channel, ares_conn_t *conn, ++ const ares_timeval_t *now) + { + ares_ssize_t count; + ares_server_t *server = conn->server; +- ares_status_t status; ++ ares_status_t status = ARES_SUCCESS; + ares__array_t *requeue = NULL; + + /* Fetch buffer to store data we are reading */ +@@ -380,8 +457,7 @@ static void read_tcp_data(ares_channel_t *channel, ares_conn_t *conn, + if (ptr == NULL) { + handle_conn_error(conn, ARES_FALSE /* not critical to connection */, + ARES_SUCCESS); +- return; /* bail out on malloc failure. TODO: make this +- function return error codes */ ++ return ARES_ENOMEM; /* bail out on malloc failure */ + } + + /* Read from socket */ +@@ -391,7 +467,7 @@ static void read_tcp_data(ares_channel_t *channel, ares_conn_t *conn, + if (!(count == -1 && ares__socket_try_again(SOCKERRNO))) { + handle_conn_error(conn, ARES_TRUE, ARES_ECONNREFUSED); + } +- return; ++ return ARES_SUCCESS; + } + + /* Record amount of data read */ +@@ -443,37 +519,13 @@ static void read_tcp_data(ares_channel_t *channel, ares_conn_t *conn, + + cleanup: + +- /* Flush requeue */ +- while (ares__array_len(requeue) > 0) { +- ares_query_t *query; +- ares_requeue_t entry; +- ares_status_t internal_status; +- +- internal_status = ares__array_claim_at(&entry, sizeof(entry), requeue, 0); +- if (internal_status != ARES_SUCCESS) { +- break; +- } +- +- query = ares__htable_szvp_get_direct(channel->queries_by_qid, entry.qid); +- 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); +- } ++ /* Flush requeue - re-dispatch retries and invoke deferred callbacks ++ * iteratively and safely */ ++ if (ares_flush_requeue(channel, now, &requeue) == ARES_ENOMEM) { ++ status = ARES_ENOMEM; + } +- /* Don't forget to send notification if queue emptied */ +- if (requeue != NULL) { +- ares_queue_notify_empty(channel); +- } +- ares__array_destroy(requeue); ++ ++ return status; + } + + static ares_socket_t *channel_socket_list(const ares_channel_t *channel, +@@ -516,11 +568,13 @@ static ares_socket_t *channel_socket_list(const ares_channel_t *channel, + } + + /* If any UDP sockets select true for reading, process them. */ +-static void read_udp_packets_fd(ares_channel_t *channel, ares_conn_t *conn, +- const ares_timeval_t *now) ++static ares_status_t read_udp_packets_fd(ares_channel_t *channel, ++ ares_conn_t *conn, ++ const ares_timeval_t *now) + { + ares_ssize_t read_len; + unsigned char buf[MAXENDSSZ + 1]; ++ ares_status_t status = ARES_SUCCESS; + ares__array_t *requeue = NULL; + + #ifdef HAVE_RECVFROM +@@ -581,26 +635,14 @@ static void read_udp_packets_fd(ares_channel_t *channel, ares_conn_t *conn, + + cleanup: + +- /* Flush requeue */ +- while (ares__array_len(requeue) > 0) { +- ares_query_t *query; +- ares_requeue_t entry; +- ares_status_t internal_status; +- +- internal_status = ares__array_claim_at(&entry, sizeof(entry), requeue, 0); +- if (internal_status != ARES_SUCCESS) { +- break; +- } +- +- /* Query disappeared */ +- query = ares__htable_szvp_get_direct(channel->queries_by_qid, entry.qid); +- if (query == NULL) { +- continue; +- } +- +- ares__send_query(query, now); ++ /* Flush requeue - re-dispatch retries and invoke deferred callbacks ++ * iteratively and safely. This path previously ignored entry.type and ++ * re-sent REQUEUE_ENDQUERY entries instead of completing them. */ ++ if (ares_flush_requeue(channel, now, &requeue) == ARES_ENOMEM) { ++ status = ARES_ENOMEM; + } +- ares__array_destroy(requeue); ++ ++ return status; + } + + static void read_packets(ares_channel_t *channel, fd_set *read_fds, +@@ -671,9 +713,12 @@ static void read_packets(ares_channel_t *channel, fd_set *read_fds, + } + + /* If any queries have timed out, note the timeout and move them on. */ +-static void process_timeouts(ares_channel_t *channel, const ares_timeval_t *now) ++static ares_status_t process_timeouts(ares_channel_t *channel, ++ const ares_timeval_t *now) + { + ares__slist_node_t *node; ++ ares_status_t status = ARES_SUCCESS; ++ ares__array_t *requeue = NULL; + + /* Just keep popping off the first as this list will re-sort as things come + * and go. We don't want to try to rely on 'next' as some operation might +@@ -692,8 +737,24 @@ static void process_timeouts(ares_channel_t *channel, const ares_timeval_t *now) + + conn = query->conn; + server_increment_failures(conn->server, query->using_tcp); +- ares__requeue_query(query, now, ARES_ETIMEOUT, ARES_TRUE, NULL, NULL); ++ status = ++ ares__requeue_query(query, now, ARES_ETIMEOUT, ARES_TRUE, NULL, &requeue); ++ if (status == ARES_ENOMEM) { ++ goto done; ++ } + } ++done: ++ /* Flush requeue - re-dispatch retries and invoke deferred callbacks ++ * iteratively and safely */ ++ if (ares_flush_requeue(channel, now, &requeue) == ARES_ENOMEM) { ++ status = ARES_ENOMEM; ++ } ++ ++ if (status == ARES_ENOMEM) { ++ return ARES_ENOMEM; ++ } ++ ++ return ARES_SUCCESS; + } + + static ares_status_t rewrite_without_edns(ares_query_t *query) +@@ -791,7 +852,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, NULL); ++ end_query(channel, server, query, status, NULL, requeue); + goto cleanup; + } + +@@ -1176,7 +1237,42 @@ static ares_status_t ares__conn_query_write(ares_conn_t *conn, + return ARES_SUCCESS; + } + ++/* Public entrypoint. Establishes a requeue list and drives ++ * ares__send_query_int() plus any retries/deferred callbacks it produces ++ * iteratively, so a chain of retryable failures can never recurse until the ++ * stack is exhausted (upstream issue #1043). */ + ares_status_t ares__send_query(ares_query_t *query, const ares_timeval_t *now) ++{ ++ ares_channel_t *channel = query->channel; ++ ares__array_t *requeue = NULL; ++ unsigned short qid = query->qid; ++ ares_status_t status; ++ ++ status = ares__send_query_int(query, now, &requeue); ++ ++ /* Drain any retries/deferred callbacks this send produced. ++ * ares_flush_requeue() always fully processes and destroys the list (even on ++ * ENOMEM), and sends the empty-queue notification if needed. */ ++ if (ares_flush_requeue(channel, now, &requeue) == ARES_ENOMEM) { ++ status = ARES_ENOMEM; ++ } ++ ++ /* A retry may have been deferred (returning ARES_SUCCESS from the append) ++ * and then terminally failed while draining, in which case the query has ++ * been freed. Do not dereference 'query' here. If it is no longer tracked ++ * it ended, so don't report success to the caller (which would, e.g., cause ++ * ares_send_nolock() to write to a now-freed *qid). */ ++ if (status == ARES_SUCCESS && ++ ares__htable_szvp_get_direct(channel->queries_by_qid, qid) == NULL) { ++ status = ARES_ETIMEOUT; ++ } ++ ++ return status; ++} ++ ++static ares_status_t ares__send_query_int(ares_query_t *query, ++ const ares_timeval_t *now, ++ ares__array_t **requeue) + { + ares_channel_t *channel = query->channel; + ares_server_t *server; +@@ -1194,7 +1290,7 @@ ares_status_t ares__send_query(ares_query_t *query, const ares_timeval_t *now) + } + + if (server == NULL) { +- end_query(channel, server, query, ARES_ENOSERVER /* ? */, NULL, NULL); ++ end_query(channel, server, query, ARES_ENOSERVER /* ? */, NULL, requeue); + return ARES_ENOSERVER; + } + +@@ -1211,11 +1307,11 @@ ares_status_t ares__send_query(ares_query_t *query, const ares_timeval_t *now) + case ARES_ECONNREFUSED: + case ARES_EBADFAMILY: + server_increment_failures(server, query->using_tcp); +- return ares__requeue_query(query, now, status, ARES_TRUE, NULL, NULL); ++ return ares__requeue_query(query, now, status, ARES_TRUE, NULL, requeue); + + /* Anything else is not retryable, likely ENOMEM */ + default: +- end_query(channel, server, query, status, NULL, NULL); ++ end_query(channel, server, query, status, NULL, requeue); + return status; + } + } +@@ -1229,7 +1325,7 @@ ares_status_t ares__send_query(ares_query_t *query, const ares_timeval_t *now) + + case ARES_ENOMEM: + /* Not retryable */ +- end_query(channel, server, query, status, NULL, NULL); ++ end_query(channel, server, query, status, NULL, requeue); + return status; + + /* These conditions are retryable as they are server-specific +@@ -1237,7 +1333,7 @@ ares_status_t ares__send_query(ares_query_t *query, const ares_timeval_t *now) + case ARES_ECONNREFUSED: + case ARES_EBADFAMILY: + handle_conn_error(conn, ARES_TRUE, status); +- status = ares__requeue_query(query, now, status, ARES_TRUE, NULL, NULL); ++ status = ares__requeue_query(query, now, status, ARES_TRUE, NULL, requeue); + if (status == ARES_ETIMEOUT) { + status = ARES_ECONNREFUSED; + } +@@ -1247,7 +1343,7 @@ ares_status_t ares__send_query(ares_query_t *query, const ares_timeval_t *now) + * just requeue to a different server/connection. */ + default: + server_increment_failures(server, query->using_tcp); +- status = ares__requeue_query(query, now, status, ARES_TRUE, NULL, NULL); ++ status = ares__requeue_query(query, now, status, ARES_TRUE, NULL, requeue); + return status; + } + +@@ -1263,7 +1359,7 @@ ares_status_t ares__send_query(ares_query_t *query, const ares_timeval_t *now) + ares__slist_insert(channel->queries_by_timeout, query); + if (!query->node_queries_by_timeout) { + /* LCOV_EXCL_START: OutOfMemory */ +- end_query(channel, server, query, ARES_ENOMEM, NULL, NULL); ++ end_query(channel, server, query, ARES_ENOMEM, NULL, requeue); + return ARES_ENOMEM; + /* LCOV_EXCL_STOP */ + } +@@ -1276,7 +1372,7 @@ ares_status_t ares__send_query(ares_query_t *query, const ares_timeval_t *now) + + if (query->node_queries_to_conn == NULL) { + /* LCOV_EXCL_START: OutOfMemory */ +- end_query(channel, server, query, ARES_ENOMEM, NULL, NULL); ++ end_query(channel, server, query, ARES_ENOMEM, NULL, requeue); + return ARES_ENOMEM; + /* LCOV_EXCL_STOP */ + } +@@ -1397,6 +1493,11 @@ static void end_query(ares_channel_t *channel, ares_server_t *server, + return; + } + ++ /* Callers that pass no requeue list (e.g. ares__requeue_query() from ++ * ares__close_connection()) invoke the callback inline, so detach here too ++ * for the same reason ares_flush_requeue() does (CVE-2026-33630). */ ++ ares_detach_query(query); ++ + /* Invoke the callback. */ + query->callback(query->arg, status, query->timeouts, dnsrec); + ares__free_query(query); +diff --git a/lib/c-ares-1.33.1/test/ares-test-mock.cc b/lib/c-ares-1.33.1/test/ares-test-mock.cc +index 920d322..4c6a1fd 100644 +--- a/lib/c-ares-1.33.1/test/ares-test-mock.cc ++++ b/lib/c-ares-1.33.1/test/ares-test-mock.cc +@@ -1658,6 +1658,112 @@ TEST_P(MockUDPChannelTest, TriggerResendThenConnFailEDNS) { + EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str()); + } + ++// Regression for upstream issue #1043: a long chain of retryable connection ++// failures used to recurse ares__requeue_query() -> ares__send_query() until ++// the stack was exhausted. With a very high retry count and a socket that ++// always fails to be created (a retryable ARES_ECONNREFUSED), the retries must ++// be processed iteratively and the query must terminate cleanly. ++class MockRetryDepthChannelTest : public MockChannelOptsTest, ++ public ::testing::WithParamInterface { ++public: ++ MockRetryDepthChannelTest() ++ : MockChannelOptsTest(1, GetParam(), false, false, FillOptions(&opts_), ++ ARES_OPT_TRIES) ++ { ++ } ++ ++ static struct ares_options *FillOptions(struct ares_options *opts) ++ { ++ memset(opts, 0, sizeof(struct ares_options)); ++ /* Large enough that the old recursive path would overflow the stack. */ ++ opts->tries = 100000; ++ return opts; ++ } ++ ++private: ++ struct ares_options opts_; ++}; ++ ++static size_t g_always_fail_socket_calls = 0; ++ ++static ares_socket_t always_fail_socket(int af, int type, int protocol, ++ void *user_data) ++{ ++ (void)af; ++ (void)type; ++ (void)protocol; ++ (void)user_data; ++ g_always_fail_socket_calls++; ++ return ARES_SOCKET_BAD; ++} ++ ++TEST_P(MockRetryDepthChannelTest, HighRetryNoStackOverflow) { ++ struct ares_socket_functions sock_funcs; ++ memset(&sock_funcs, 0, sizeof(sock_funcs)); ++ sock_funcs.asocket = always_fail_socket; ++ ares_set_socket_functions(channel_, &sock_funcs, NULL); ++ ++ g_always_fail_socket_calls = 0; ++ ++ QueryResult result; ++ ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, ++ QueryCallback, &result, NULL); ++ Process(); ++ ++ /* If the retries didn't drive the query to a terminal state on their own, ++ * cancel it so the query terminates deterministically. */ ++ if (!result.done_) { ++ ares_cancel(channel_); ++ Process(); ++ } ++ ++ /* The essential property is that we reached this point at all: on unpatched ++ * code the retryable failures recursed until the stack overflowed and the ++ * process aborted before getting here. */ ++ EXPECT_GT(g_always_fail_socket_calls, (size_t)1); ++ EXPECT_TRUE(result.done_); ++} ++ ++// Regression for CVE-2026-33630 / GHSA-6wfj-rwm7-3542: invoking ares_cancel() ++// from within a normal response callback must not double-free the query. The ++// callback is dispatched from the deferred requeue flush, so the query must be ++// detached from all lookup lists before the callback runs, otherwise the ++// reentrant ares_cancel() finds and frees it a second time. ++struct CancelInCbData { ++ ares_channel_t *channel; ++ bool done; ++}; ++ ++static void CancelChannelCallback(void *arg, ares_status_t status, ++ size_t timeouts, ++ const ares_dns_record_t *dnsrec) ++{ ++ CancelInCbData *data = static_cast(arg); ++ (void)status; ++ (void)timeouts; ++ (void)dnsrec; ++ data->done = true; ++ /* Reentrant cancel from within the callback. Must not double-free. */ ++ ares_cancel(data->channel); ++} ++ ++TEST_P(MockUDPChannelTest, CancelInCallbackNoDoubleFree) { ++ DNSPacket reply; ++ reply.set_response().set_aa() ++ .add_question(new DNSQuestion("www.google.com", T_A)) ++ .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04})); ++ ON_CALL(server_, OnRequest("www.google.com", T_A)) ++ .WillByDefault(SetReply(&server_, &reply)); ++ ++ CancelInCbData data; ++ data.channel = channel_; ++ data.done = false; ++ ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, ++ CancelChannelCallback, &data, NULL); ++ Process(); ++ EXPECT_TRUE(data.done); ++} ++ + static const unsigned char * + fetch_server_cookie(const ares_dns_record_t *dnsrec, size_t *len) + { +@@ -2345,6 +2451,8 @@ INSTANTIATE_TEST_SUITE_P(AddressFamilies, ContainedMockChannelSysConfig, ::testi + + INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockUDPChannelTest, ::testing::ValuesIn(ares::test::families), PrintFamily); + ++INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockRetryDepthChannelTest, ::testing::ValuesIn(ares::test::families), PrintFamily); ++ + INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockUDPMaxQueriesTest, ::testing::ValuesIn(ares::test::families), PrintFamily); + + INSTANTIATE_TEST_SUITE_P(AddressFamilies, CacheQueriesTest, ::testing::ValuesIn(ares::test::families), PrintFamily); +-- +2.45.4 + diff --git a/SPECS/fluent-bit/fluent-bit.spec b/SPECS/fluent-bit/fluent-bit.spec index 6686d447420..18f3ed5e91e 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: 6%{?dist} +Release: 7%{?dist} License: Apache-2.0 Vendor: Microsoft Corporation Distribution: Azure Linux @@ -21,6 +21,7 @@ Patch10: CVE-2025-12969.patch Patch11: CVE-2025-62408.patch Patch12: CVE-2025-63657.patch Patch13: CVE-2025-63652.patch +Patch14: CVE-2026-33630.patch BuildRequires: bison BuildRequires: cmake BuildRequires: cyrus-sasl-devel @@ -95,6 +96,9 @@ Development files for %{name} %{_libdir}/fluent-bit/*.so %changelog +* Wed Sep 09 2026 Sumit Jena - 3.1.10-7 +- Patch for CVE-2026-33630 + * Thu Apr 23 2026 Azure Linux Security Servicing Account - 3.1.10-6 - Patch for CVE-2025-63652