diff --git a/SPECS/fluent-bit/CVE-2025-63657.patch b/SPECS/fluent-bit/CVE-2025-63657.patch new file mode 100644 index 00000000000..05ce176424c --- /dev/null +++ b/SPECS/fluent-bit/CVE-2025-63657.patch @@ -0,0 +1,314 @@ +From 8453990adf71d8093a42259892ac36c4f1d47e11 Mon Sep 17 00:00:00 2001 +From: Eduardo Silva +Date: Thu, 9 Apr 2026 12:11:52 -0600 +Subject: [PATCH 1/3] server: http: fix malformed request crash paths + +Fix the reproducible malformed-request crash paths in the HTTP +request lifecycle. + +Handle missing Host data in directory redirects, reject malformed +range delimiters before substring parsing, and avoid reusing invalid +request state while advancing pipelined requests. + +Verified by rebuilding with cmake --build build and replaying the +reported crash-inducing request fixtures against build/bin/monkey. + +Signed-off-by: Eduardo Silva +--- + lib/monkey/mk_core/mk_memory.c | 10 ++++++++ + lib/monkey/mk_server/mk_http.c | 46 +++++++++++++++++++++++++++++++--- + 2 files changed, 52 insertions(+), 4 deletions(-) + +diff --git a/lib/monkey/mk_core/mk_memory.c b/lib/monkey/mk_core/mk_memory.c +index c4073e2..008f7ac 100644 +--- a/lib/monkey/mk_core/mk_memory.c ++++ b/lib/monkey/mk_core/mk_memory.c +@@ -52,6 +52,16 @@ char *mk_ptr_to_buf(mk_ptr_t p) + { + char *buf; + ++ if (!p.data || p.len == 0) { ++ buf = mk_mem_alloc(1); ++ if (!buf) { ++ return NULL; ++ } ++ ++ buf[0] = '\0'; ++ return buf; ++ } ++ + buf = mk_mem_alloc(p.len + 1); + if (!buf) return NULL; + +diff --git a/lib/monkey/mk_server/mk_http.c b/lib/monkey/mk_server/mk_http.c +index 1e2d219..3fb34e0 100644 +--- a/lib/monkey/mk_server/mk_http.c ++++ b/lib/monkey/mk_server/mk_http.c +@@ -447,6 +447,10 @@ static int mk_http_range_parse(struct mk_http_request *sr) + if ((sep_pos = mk_string_char_search(sr->range.data, '-', sr->range.len)) < 0) + return -1; + ++ if (sep_pos < eq_pos) { ++ return -1; ++ } ++ + len = sr->range.len; + sh = &sr->headers; + +@@ -466,10 +470,16 @@ static int mk_http_range_parse(struct mk_http_request *sr) + /* =yyy-xxx */ + if ((eq_pos + 1 != sep_pos) && (len > sep_pos + 1)) { + buffer = mk_string_copy_substr(sr->range.data, eq_pos + 1, sep_pos); ++ if (!buffer) { ++ return -1; ++ } + sh->ranges[0] = (unsigned long) atol(buffer); + mk_mem_free(buffer); + + buffer = mk_string_copy_substr(sr->range.data, sep_pos + 1, len); ++ if (!buffer) { ++ return -1; ++ } + sh->ranges[1] = (unsigned long) atol(buffer); + mk_mem_free(buffer); + +@@ -483,6 +493,9 @@ static int mk_http_range_parse(struct mk_http_request *sr) + /* =yyy- */ + if ((eq_pos + 1 != sep_pos) && (len == sep_pos + 1)) { + buffer = mk_string_copy_substr(sr->range.data, eq_pos + 1, len); ++ if (!buffer) { ++ return -1; ++ } + sr->headers.ranges[0] = (unsigned long) atol(buffer); + mk_mem_free(buffer); + +@@ -512,7 +525,16 @@ static int mk_http_directory_redirect_check(struct mk_http_session *cs, + return 0; + } + ++ if (!sr->host.data || sr->host.len <= 0) { ++ mk_http_error(MK_CLIENT_BAD_REQUEST, cs, sr, server); ++ return -1; ++ } ++ + host = mk_ptr_to_buf(sr->host); ++ if (!host) { ++ mk_http_error(MK_CLIENT_BAD_REQUEST, cs, sr, server); ++ return -1; ++ } + + /* + * Add ending slash to the location string +@@ -578,6 +600,9 @@ static inline char *mk_http_index_lookup(mk_ptr_t *path_base, + } + + off = path_base->len; ++ if ((size_t) off >= buf_size) { ++ return NULL; ++ } + memcpy(buf, path_base->data, off); + + mk_list_foreach(head, server->index_files) { +@@ -1136,15 +1161,27 @@ int mk_http_request_end(struct mk_http_session *cs, struct mk_server *server) + ret = mk_http_parser_more(&cs->parser, cs->body_length); + if (ret == MK_TRUE) { + /* Our pipeline request limit is the same that our keepalive limit */ ++ if (cs->parser.i < 0 || ++ (unsigned int) (cs->parser.i + 1) >= cs->body_length) { ++ goto shutdown; ++ } ++ + cs->counter_connections++; + len = (cs->body_length - cs->parser.i) -1; ++ if (len <= 0) { ++ goto shutdown; ++ } + memmove(cs->body, + cs->body + cs->parser.i + 1, + len); + cs->body_length = len; + + /* Prepare for next one */ +- sr = mk_list_entry_first(&cs->request_list, struct mk_http_request, _head); ++ if (mk_list_is_empty(&cs->request_list) == 0) { ++ cs->close_now = MK_TRUE; ++ goto shutdown; ++ } ++ sr = &cs->sr_fixed; + mk_http_request_free(sr, server); + mk_http_request_init(cs, sr, server); + mk_http_parser_init(&cs->parser); +@@ -1621,9 +1658,10 @@ int mk_http_sched_done(struct mk_sched_conn *conn, + struct mk_http_request *sr; + + session = mk_http_session_get(conn); +- sr = mk_list_entry_first(&session->request_list, +- struct mk_http_request, _head); +- mk_plugin_stage_run_40(session, sr, server); ++ if (mk_list_is_empty(&session->request_list) != 0) { ++ sr = &session->sr_fixed; ++ mk_plugin_stage_run_40(session, sr, server); ++ } + + return mk_http_request_end(session, server); + } +-- +2.45.4 + + +From fcbb70eec4c9fa9201b3b71044e794d3bd11f82f Mon Sep 17 00:00:00 2001 +From: Eduardo Silva +Date: Thu, 9 Apr 2026 12:11:57 -0600 +Subject: [PATCH 2/3] server: parser: harden boundary checks + +Tighten parser and helper validation around explicit lengths and +buffer boundaries. + +Require exact header literal matches, validate chunk length tokens, +and guard helper routines that previously trusted inconsistent +pointer or length state. + +Verified by rebuilding with cmake --build build and replaying the +reported malformed request fixtures against build/bin/monkey. + +Signed-off-by: Eduardo Silva +--- + lib/monkey/include/monkey/mk_http_parser.h | 6 +++++- + lib/monkey/mk_server/mk_http_parser.c | 13 +++++++++++++ + lib/monkey/mk_server/mk_mimetype.c | 7 ++++++- + lib/monkey/mk_server/mk_user.c | 2 +- + 4 files changed, 25 insertions(+), 3 deletions(-) + +diff --git a/lib/monkey/include/monkey/mk_http_parser.h b/lib/monkey/include/monkey/mk_http_parser.h +index 6d45c39..5ae5c60 100644 +--- a/lib/monkey/include/monkey/mk_http_parser.h ++++ b/lib/monkey/include/monkey/mk_http_parser.h +@@ -335,7 +335,11 @@ static inline void mk_http_parser_init(struct mk_http_parser *p) + + static inline int mk_http_parser_more(struct mk_http_parser *p, int len) + { +- if (abs(len - p->i) - 1 > 0) { ++ if (len <= 0 || p->i < 0) { ++ return MK_FALSE; ++ } ++ ++ if ((p->i + 1) < len) { + return MK_TRUE; + } + +diff --git a/lib/monkey/mk_server/mk_http_parser.c b/lib/monkey/mk_server/mk_http_parser.c +index 4e7aa31..8fc4da1 100644 +--- a/lib/monkey/mk_server/mk_http_parser.c ++++ b/lib/monkey/mk_server/mk_http_parser.c +@@ -172,6 +172,16 @@ static inline void request_set(mk_ptr_t *ptr, struct mk_http_parser *p, char *bu + static inline int header_cmp(const char *expected, char *value, int len) + { + int i = 0; ++ size_t expected_len; ++ ++ if (len < 0) { ++ return -1; ++ } ++ ++ expected_len = strlen(expected); ++ if ((size_t) len != expected_len) { ++ return -1; ++ } + + if (len >= 8) { + if (expected[0] != tolower(value[0])) return -1; +@@ -503,6 +513,9 @@ int mk_http_parser(struct mk_http_request *req, struct mk_http_parser *p, + if (p->start + 6 >= p->i) { + continue; + } ++ if (ptr == tmp || *ptr != '\0') { ++ return MK_HTTP_PARSER_ERROR; ++ } + + tmp = p->start; + if (buffer[tmp] == 'H' && +diff --git a/lib/monkey/mk_server/mk_mimetype.c b/lib/monkey/mk_server/mk_mimetype.c +index b86b4ef..5462ea5 100644 +--- a/lib/monkey/mk_server/mk_mimetype.c ++++ b/lib/monkey/mk_server/mk_mimetype.c +@@ -197,7 +197,12 @@ struct mk_mimetype *mk_mimetype_find(struct mk_server *server, mk_ptr_t *filenam + { + int j, len; + +- j = len = filename->len; ++ if (!filename->data || filename->len <= 0) { ++ return NULL; ++ } ++ ++ len = filename->len; ++ j = len - 1; + + /* looking for extension */ + while (j >= 0 && filename->data[j] != '.') { +diff --git a/lib/monkey/mk_server/mk_user.c b/lib/monkey/mk_server/mk_user.c +index 7200ff0..716331a 100644 +--- a/lib/monkey/mk_server/mk_user.c ++++ b/lib/monkey/mk_server/mk_user.c +@@ -46,7 +46,7 @@ int mk_user_init(struct mk_http_session *cs, struct mk_http_request *sr, + } + + limit = mk_string_char_search(sr->uri_processed.data + offset, '/', +- sr->uri_processed.len); ++ sr->uri_processed.len - offset); + + if (limit == -1) { + limit = (sr->uri_processed.len) - offset; +-- +2.45.4 + + +From d9be8a3839d0e024cb219702076357f9f054b3d3 Mon Sep 17 00:00:00 2001 +From: Eduardo Silva +Date: Thu, 9 Apr 2026 12:43:31 -0600 +Subject: [PATCH 3/3] server: scheduler: guard protocol close callback + +Avoid calling a null cb_close handler from the scheduler close +and timeout paths. + +This fixes the HTTP/2 upgrade case where the protocol handler can be +switched to mk_http2_handler even though that handler does not +implement cb_close. + +Verified by rebuilding with cmake --build build. + +Signed-off-by: Eduardo Silva +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/monkey/monkey/pull/434.patch +--- + lib/monkey/mk_server/mk_scheduler.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/lib/monkey/mk_server/mk_scheduler.c b/lib/monkey/mk_server/mk_scheduler.c +index a680d3c..3cf0ba4 100644 +--- a/lib/monkey/mk_server/mk_scheduler.c ++++ b/lib/monkey/mk_server/mk_scheduler.c +@@ -598,8 +598,10 @@ int mk_sched_check_timeouts(struct mk_sched_worker *sched, + MK_TRACE("Scheduler, closing fd %i due TIMEOUT", + conn->event.fd); + MK_LT_SCHED(conn->event.fd, "TIMEOUT_CONN_PENDING"); +- conn->protocol->cb_close(conn, sched, MK_SCHED_CONN_TIMEOUT, +- server); ++ if (conn->protocol->cb_close) { ++ conn->protocol->cb_close(conn, sched, MK_SCHED_CONN_TIMEOUT, ++ server); ++ } + mk_sched_drop_connection(conn, sched, server); + } + } +@@ -749,7 +751,7 @@ int mk_sched_event_close(struct mk_sched_conn *conn, + MK_TRACE("[FD %i] Connection Handler, closed", conn->event.fd); + mk_event_del(sched->loop, &conn->event); + +- if (type != MK_EP_SOCKET_DONE) { ++ if (type != MK_EP_SOCKET_DONE && conn->protocol->cb_close) { + conn->protocol->cb_close(conn, sched, type, server); + } + /* +-- +2.45.4 + diff --git a/SPECS/fluent-bit/fluent-bit.spec b/SPECS/fluent-bit/fluent-bit.spec index 1d6a694d634..0344a2b60d9 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: 4%{?dist} +Release: 5%{?dist} License: Apache-2.0 Vendor: Microsoft Corporation Distribution: Azure Linux @@ -19,6 +19,7 @@ Patch8: CVE-2025-12970.patch Patch9: CVE-2025-12977.patch Patch10: CVE-2025-12969.patch Patch11: CVE-2025-62408.patch +Patch12: CVE-2025-63657.patch BuildRequires: bison BuildRequires: cmake BuildRequires: cyrus-sasl-devel @@ -93,6 +94,9 @@ Development files for %{name} %{_libdir}/fluent-bit/*.so %changelog +* Mon Apr 13 2026 Azure Linux Security Servicing Account - 3.1.10-5 +- Patch for CVE-2025-63657 + * Wed Dec 17 2025 Azure Linux Security Servicing Account - 3.1.10-4 - Patch for CVE-2025-62408 @@ -120,7 +124,7 @@ Development files for %{name} * Tue Dec 10 2024 Sudipta Pandit - 3.1.9-2 - Backport fixes for CVE-2024-27532 -* Tue Nov 23 2024 Paul Meyer - 3.1.9-1 +* Sat Nov 23 2024 Paul Meyer - 3.1.9-1 - Update to 3.1.9 to enable Lua filter plugin using system luajit library. - Remove patches for CVE-2024-25629 and CVE-2024-28182 as they are fixed in 3.1.9. - [Jon Slobodzian] Reconciled with Fasttrack/3.0 on 11/23, updated Changelog date from 11/5.