diff --git a/SPECS/gnutls/CVE-2026-33845.patch b/SPECS/gnutls/CVE-2026-33845.patch new file mode 100644 index 00000000000..bbbef96c8d6 --- /dev/null +++ b/SPECS/gnutls/CVE-2026-33845.patch @@ -0,0 +1,177 @@ +From e5b72c53c7d789d19d1d1cd10b275e87d0415413 Mon Sep 17 00:00:00 2001 +From: Alexander Sosedkin +Date: Mon, 23 Mar 2026 15:09:43 +0100 +Subject: [PATCH] buffers: switch from end_offset over to frag_length + +Instead of maintaining an inclusive [start_offset, end_offset] range +when reassembling DTLS handshake, +track start_offset and a relative frag_length instead. + +You would think it would be a no-op, but it fixes: + +* 0-length fragments triggering completion if message was 1 byte long +* a remotely triggerable underflow and an ensuing heap overrun + +Reported-by: Joshua Rogers of AISLE Research Team +Fixes: #1811 +Fixes: CVE-2026-33845 +Fixes: GNUTLS-SA-2026-04-29-3 +CVSS: 7.5 High CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H +Signed-off-by: Alexander Sosedkin + +Upstream Patch Reference: https://gitlab.com/gnutls/gnutls/-/commit/e5b72c53c7d789d19d1d1cd10b275e87d0415413.patch +Signed-off-by: Alexander Sosedkin +--- + lib/buffers.c | 51 +++++++++++++++++++++++++----------------------- + lib/gnutls_int.h | 4 ++-- + 2 files changed, 29 insertions(+), 26 deletions(-) + +diff --git a/lib/buffers.c b/lib/buffers.c +index e9ddf0403b..c3df8a37bc 100644 +--- a/lib/buffers.c ++++ b/lib/buffers.c +@@ -923,10 +923,7 @@ + } + data_size = _mbuffer_get_udata_size(bufel) - handshake_header_size; + +- if (frag_size > 0) +- hsk->end_offset = hsk->start_offset + frag_size - 1; +- else +- hsk->end_offset = 0; ++ hsk->frag_length = frag_size; + + _gnutls_handshake_log( + "HSK[%p]: %s (%u) was received. Length %d[%d], frag offset %d, frag length: %d, sequence: %d\n", +@@ -940,9 +937,11 @@ + + if (hsk->length > 0 && + (frag_size > data_size || +- (frag_size > 0 && hsk->end_offset >= hsk->length))) { ++ (frag_size > 0 && ++ hsk->start_offset + frag_size > hsk->length))) { + return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); +- } else if (hsk->length == 0 && hsk->end_offset != 0 && ++ } else if (hsk->length == 0 && ++ hsk->start_offset + frag_size != hsk->start_offset && + hsk->start_offset != 0) + return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); + +@@ -991,11 +990,10 @@ + hsk->data.length = hsk->length; + } + +- if (hsk->length > 0 && hsk->end_offset > 0 && +- hsk->end_offset - hsk->start_offset + 1 != hsk->length) { ++ if (hsk->length > 0 && hsk->frag_length > 0 && ++ hsk->frag_length != hsk->length) { + memmove(&hsk->data.data[hsk->start_offset], +- hsk->data.data, +- hsk->end_offset - hsk->start_offset + 1); ++ hsk->data.data, hsk->frag_length); + } + + session->internals.handshake_recv_buffer_size++; +@@ -1012,7 +1010,7 @@ + if (hsk->start_offset < + session->internals.handshake_recv_buffer[pos] + .start_offset && +- hsk->end_offset + 1 >= ++ hsk->start_offset + hsk->frag_length >= + session->internals.handshake_recv_buffer[pos] + .start_offset) { + memcpy(&session->internals.handshake_recv_buffer[pos] +@@ -1021,28 +1019,34 @@ + session->internals.handshake_recv_buffer[pos] + .start_offset = hsk->start_offset; + session->internals.handshake_recv_buffer[pos] +- .end_offset = MIN( +- hsk->end_offset, ++ .frag_length = MIN( ++ hsk->frag_length, + session->internals.handshake_recv_buffer[pos] +- .end_offset); +- } else if (hsk->end_offset > ++ .frag_length); ++ } else if (hsk->start_offset + hsk->frag_length > + session->internals.handshake_recv_buffer[pos] +- .end_offset && ++ .start_offset + ++ session->internals.handshake_recv_buffer[pos] ++ .frag_length && + hsk->start_offset <= + session->internals.handshake_recv_buffer[pos] +- .end_offset + +- 1) { ++ .start_offset + ++ session->internals.handshake_recv_buffer[pos] ++ .frag_length) { + memcpy(&session->internals.handshake_recv_buffer[pos] + .data.data[hsk->start_offset], + hsk->data.data, hsk->data.length); + + session->internals.handshake_recv_buffer[pos] +- .end_offset = hsk->end_offset; +- session->internals.handshake_recv_buffer[pos] + .start_offset = MIN( + hsk->start_offset, + session->internals.handshake_recv_buffer[pos] + .start_offset); ++ session->internals.handshake_recv_buffer[pos] ++ .frag_length = hsk->start_offset + ++ hsk->frag_length - ++ session->internals.handshake_recv_buffer[pos] ++ .start_offset; + } + _gnutls_handshake_buffer_clear(hsk); + } +@@ -1102,8 +1106,8 @@ + } + + else if ((recv_buf[LAST_ELEMENT].start_offset == 0 && +- recv_buf[LAST_ELEMENT].end_offset == +- recv_buf[LAST_ELEMENT].length - 1) || ++ recv_buf[LAST_ELEMENT].frag_length == ++ recv_buf[LAST_ELEMENT].length) || + recv_buf[LAST_ELEMENT].length == 0) { + session->internals.dtls.hsk_read_seq++; + _gnutls_handshake_buffer_move(hsk, +@@ -1114,8 +1118,9 @@ + /* if we don't have a complete handshake message, but we + * have queued data waiting, try again to reconstruct the + * handshake packet, using the queued */ +- if (recv_buf[LAST_ELEMENT].end_offset != +- recv_buf[LAST_ELEMENT].length - 1 && ++ if ((recv_buf[LAST_ELEMENT].start_offset + ++ recv_buf[LAST_ELEMENT].frag_length) != ++ recv_buf[LAST_ELEMENT].length && + record_check_unprocessed(session) > 0) + return gnutls_assert_val( + GNUTLS_E_INT_CHECK_AGAIN); +@@ -1302,9 +1307,7 @@ + &session->internals.record_buffer, + bufel, ret); + +- data_size = MIN(tmp.length, +- tmp.end_offset - +- tmp.start_offset + 1); ++ data_size = MIN(tmp.length, tmp.frag_length); + + ret = _gnutls_buffer_append_data( + &tmp.data, +diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h +index d1643be9d4..3e5a8f3614 100644 +--- a/lib/gnutls_int.h ++++ b/lib/gnutls_int.h +@@ -475,10 +475,10 @@ + uint16_t sequence; + + /* indicate whether that message is complete. +- * complete means start_offset == 0 and end_offset == length ++ * complete means start_offset == 0 and frag_length == length + */ + uint32_t start_offset; +- uint32_t end_offset; ++ uint32_t frag_length; + + uint8_t header[MAX_HANDSHAKE_HEADER_SIZE]; + int header_size; diff --git a/SPECS/gnutls/gnutls.spec b/SPECS/gnutls/gnutls.spec index 1e7de6aa25d..4f3f59cf9e7 100644 --- a/SPECS/gnutls/gnutls.spec +++ b/SPECS/gnutls/gnutls.spec @@ -1,7 +1,7 @@ Summary: The GnuTLS Transport Layer Security Library Name: gnutls Version: 3.8.3 -Release: 8%{?dist} +Release: 9%{?dist} License: GPLv3+ AND LGPLv2.1+ Vendor: Microsoft Corporation Distribution: Azure Linux @@ -20,6 +20,7 @@ Patch7: CVE-2025-32988.patch Patch8: CVE-2025-6395.patch Patch9: CVE-2025-13151.patch Patch10: CVE-2025-9820.patch +Patch11: CVE-2026-33845.patch BuildRequires: autogen-libopts-devel BuildRequires: gc-devel BuildRequires: libtasn1-devel @@ -101,6 +102,9 @@ sed -i 's/TESTS += test-ciphers-openssl.sh//' tests/slow/Makefile.am %{_mandir}/man3/* %changelog +* Thu May 07 2026 Akarsh Chaudhary - 3.8.3-9 +- Patch for CVE-2026-33845 + * Wed Jan 28 2026 Akhila Guruju - 3.8.3-8 - Patch CVE-2025-9820