From: "Hugo SIMELIERE (Schneider Electric)" <[email protected]>
Pick patch from [1] as mentioned in Debian report in [2]. Pick pre-patch [3] to minimize conflicts. [1] https://gitlab.com/gnutls/gnutls/-/commit/e5b72c53c7d789d19d1d1cd10b275e87d0415413 [2] https://security-tracker.debian.org/tracker/CVE-2026-33845 [3] https://gitlab.com/gnutls/gnutls/-/commit/bd70e112d4d1f063223f0f0886aaaf33699390d0 Signed-off-by: Hugo SIMELIERE (Schneider Electric) <[email protected]> Reviewed-by: Bruno VERNAY <[email protected]> --- .../gnutls/gnutls/CVE-2026-33845-pre.patch | 97 ++++++++++ .../gnutls/gnutls/CVE-2026-33845.patch | 172 ++++++++++++++++++ meta/recipes-support/gnutls/gnutls_3.8.4.bb | 2 + 3 files changed, 271 insertions(+) create mode 100644 meta/recipes-support/gnutls/gnutls/CVE-2026-33845-pre.patch create mode 100644 meta/recipes-support/gnutls/gnutls/CVE-2026-33845.patch diff --git a/meta/recipes-support/gnutls/gnutls/CVE-2026-33845-pre.patch b/meta/recipes-support/gnutls/gnutls/CVE-2026-33845-pre.patch new file mode 100644 index 0000000000..0eaccd5ba9 --- /dev/null +++ b/meta/recipes-support/gnutls/gnutls/CVE-2026-33845-pre.patch @@ -0,0 +1,97 @@ +From f2f852f604d73f890f977bab9792fbc4c20adbcd Mon Sep 17 00:00:00 2001 +From: Alexander Sosedkin <[email protected]> +Date: Wed, 22 Apr 2026 14:19:57 +0200 +Subject: [PATCH 1/2] buffers: rename a variable in parse_handshake_header + +CVE: CVE-2026-33845 +Upstream-Status: Backport [https://gitlab.com/gnutls/gnutls/-/commit/bd70e112d4d1f063223f0f0886aaaf33699390d0] + +Signed-off-by: Alexander Sosedkin <[email protected]> +(cherry picked from commit bd70e112d4d1f063223f0f0886aaaf33699390d0) +Signed-off-by: Hugo SIMELIERE (Schneider Electric) <[email protected]> +--- + lib/buffers.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/lib/buffers.c b/lib/buffers.c +index 5d4d16276..705c77f91 100644 +--- a/lib/buffers.c ++++ b/lib/buffers.c +@@ -857,7 +857,7 @@ static int parse_handshake_header(gnutls_session_t session, mbuffer_st *bufel, + { + uint8_t *dataptr = NULL; /* for realloc */ + size_t handshake_header_size = HANDSHAKE_HEADER_SIZE(session), +- data_size, frag_size; ++ data_size, frag_length; + + /* Note: SSL2_HEADERS == 1 */ + if (_mbuffer_get_udata_size(bufel) < handshake_header_size) +@@ -872,7 +872,7 @@ static int parse_handshake_header(gnutls_session_t session, mbuffer_st *bufel, + handshake_header_size = + SSL2_HEADERS; /* we've already read one byte */ + +- frag_size = ++ frag_length = + _mbuffer_get_udata_size(bufel) - + handshake_header_size; /* we've read the first byte */ + +@@ -883,7 +883,7 @@ static int parse_handshake_header(gnutls_session_t session, mbuffer_st *bufel, + + hsk->sequence = 0; + hsk->start_offset = 0; +- hsk->length = frag_size; ++ hsk->length = frag_length; + } else + #endif + { /* TLS or DTLS handshake headers */ +@@ -898,13 +898,13 @@ static int parse_handshake_header(gnutls_session_t session, mbuffer_st *bufel, + if (IS_DTLS(session)) { + hsk->sequence = _gnutls_read_uint16(&dataptr[4]); + hsk->start_offset = _gnutls_read_uint24(&dataptr[6]); +- frag_size = _gnutls_read_uint24(&dataptr[9]); ++ frag_length = _gnutls_read_uint24(&dataptr[9]); + } else { + hsk->sequence = 0; + hsk->start_offset = 0; +- frag_size = MIN((_mbuffer_get_udata_size(bufel) - +- handshake_header_size), +- hsk->length); ++ frag_length = MIN((_mbuffer_get_udata_size(bufel) - ++ handshake_header_size), ++ hsk->length); + } + + /* TLS1.3: distinguish server hello versus hello retry request. +@@ -923,8 +923,8 @@ static int parse_handshake_header(gnutls_session_t session, mbuffer_st *bufel, + } + data_size = _mbuffer_get_udata_size(bufel) - handshake_header_size; + +- if (frag_size > 0) +- hsk->end_offset = hsk->start_offset + frag_size - 1; ++ if (frag_length > 0) ++ hsk->end_offset = hsk->start_offset + frag_length - 1; + else + hsk->end_offset = 0; + +@@ -932,15 +932,15 @@ static int parse_handshake_header(gnutls_session_t session, mbuffer_st *bufel, + "HSK[%p]: %s (%u) was received. Length %d[%d], frag offset %d, frag length: %d, sequence: %d\n", + session, _gnutls_handshake2str(hsk->htype), + (unsigned)hsk->htype, (int)hsk->length, (int)data_size, +- hsk->start_offset, (int)frag_size, (int)hsk->sequence); ++ hsk->start_offset, (int)frag_length, (int)hsk->sequence); + + hsk->header_size = handshake_header_size; + memcpy(hsk->header, _mbuffer_get_udata_ptr(bufel), + handshake_header_size); + + if (hsk->length > 0 && +- (frag_size > data_size || +- (frag_size > 0 && hsk->end_offset >= hsk->length))) { ++ (frag_length > data_size || ++ (frag_length > 0 && hsk->end_offset >= hsk->length))) { + return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); + } else if (hsk->length == 0 && hsk->end_offset != 0 && + hsk->start_offset != 0) +-- +2.43.0 + diff --git a/meta/recipes-support/gnutls/gnutls/CVE-2026-33845.patch b/meta/recipes-support/gnutls/gnutls/CVE-2026-33845.patch new file mode 100644 index 0000000000..d9af55d263 --- /dev/null +++ b/meta/recipes-support/gnutls/gnutls/CVE-2026-33845.patch @@ -0,0 +1,172 @@ +From a6fc5c6fbfe10acd087cd233e73c5cfefbd2762a Mon Sep 17 00:00:00 2001 +From: Alexander Sosedkin <[email protected]> +Date: Mon, 23 Mar 2026 15:09:43 +0100 +Subject: [PATCH 2/2] 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'd think it'd 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 <[email protected]> +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 + +CVE: CVE-2026-33845 +Upstream-Status: Backport [https://gitlab.com/gnutls/gnutls/-/commit/e5b72c53c7d789d19d1d1cd10b275e87d0415413] + +Signed-off-by: Alexander Sosedkin <[email protected]> +(cherry picked from commit e5b72c53c7d789d19d1d1cd10b275e87d0415413) +Signed-off-by: Hugo SIMELIERE (Schneider Electric) <[email protected]> +--- + 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 705c77f91..9075a2009 100644 +--- a/lib/buffers.c ++++ b/lib/buffers.c +@@ -923,10 +923,7 @@ static int parse_handshake_header(gnutls_session_t session, mbuffer_st *bufel, + } + data_size = _mbuffer_get_udata_size(bufel) - handshake_header_size; + +- if (frag_length > 0) +- hsk->end_offset = hsk->start_offset + frag_length - 1; +- else +- hsk->end_offset = 0; ++ hsk->frag_length = frag_length; + + _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 @@ static int parse_handshake_header(gnutls_session_t session, mbuffer_st *bufel, + + if (hsk->length > 0 && + (frag_length > data_size || +- (frag_length > 0 && hsk->end_offset >= hsk->length))) { ++ (frag_length > 0 && ++ hsk->start_offset + frag_length > 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_length != hsk->start_offset && + hsk->start_offset != 0) + return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); + +@@ -993,11 +992,10 @@ static int merge_handshake_packet(gnutls_session_t session, + 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++; +@@ -1031,20 +1029,27 @@ static int merge_handshake_packet(gnutls_session_t session, + } + + if (hsk->start_offset < recv_buf[pos].start_offset && +- hsk->end_offset + 1 >= recv_buf[pos].start_offset) { ++ hsk->start_offset + hsk->frag_length >= ++ recv_buf[pos].start_offset) { + memcpy(&recv_buf[pos].data.data[hsk->start_offset], + hsk->data.data, hsk->data.length); + recv_buf[pos].start_offset = hsk->start_offset; +- recv_buf[pos].end_offset = +- MIN(hsk->end_offset, recv_buf[pos].end_offset); +- } else if (hsk->end_offset > recv_buf[pos].end_offset && +- hsk->start_offset <= recv_buf[pos].end_offset + 1) { ++ recv_buf[pos].frag_length = MIN( ++ hsk->frag_length, recv_buf[pos].frag_length); ++ } else if (hsk->start_offset + hsk->frag_length > ++ recv_buf[pos].start_offset + ++ recv_buf[pos].frag_length && ++ hsk->start_offset <= ++ recv_buf[pos].start_offset + ++ recv_buf[pos].frag_length) { + memcpy(&recv_buf[pos].data.data[hsk->start_offset], + hsk->data.data, hsk->data.length); + +- recv_buf[pos].end_offset = hsk->end_offset; + recv_buf[pos].start_offset = MIN( + hsk->start_offset, recv_buf[pos].start_offset); ++ recv_buf[pos].frag_length = hsk->start_offset + ++ hsk->frag_length - ++ recv_buf[pos].start_offset; + } + _gnutls_handshake_buffer_clear(hsk); + } +@@ -1104,8 +1109,8 @@ static int get_last_packet(gnutls_session_t session, + } + + 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, +@@ -1116,8 +1121,9 @@ static int get_last_packet(gnutls_session_t session, + /* 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); +@@ -1304,9 +1310,7 @@ int _gnutls_parse_record_buffered_msgs(gnutls_session_t session) + &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, +@@ -1322,7 +1326,6 @@ int _gnutls_parse_record_buffered_msgs(gnutls_session_t session) + ret = merge_handshake_packet(session, &tmp); + if (ret < 0) + return gnutls_assert_val(ret); +- + } while (_mbuffer_get_udata_size(bufel) > 0); + + prev = bufel; +diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h +index 8cf9a8715..689dcdc41 100644 +--- a/lib/gnutls_int.h ++++ b/lib/gnutls_int.h +@@ -479,10 +479,10 @@ typedef struct { + 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; /* used exclusively in DTLS reassembly */ + + uint8_t header[MAX_HANDSHAKE_HEADER_SIZE]; + int header_size; +-- +2.43.0 + diff --git a/meta/recipes-support/gnutls/gnutls_3.8.4.bb b/meta/recipes-support/gnutls/gnutls_3.8.4.bb index e40a654a8e..702a83fc85 100644 --- a/meta/recipes-support/gnutls/gnutls_3.8.4.bb +++ b/meta/recipes-support/gnutls/gnutls_3.8.4.bb @@ -45,6 +45,8 @@ SRC_URI = "https://www.gnupg.org/ftp/gcrypt/gnutls/v${SHRT_VER}/gnutls-${PV}.tar file://CVE-2025-14831-9.patch \ file://CVE-2026-33846-pre.patch \ file://CVE-2026-33846.patch \ + file://CVE-2026-33845-pre.patch \ + file://CVE-2026-33845.patch \ " SRC_URI[sha256sum] = "2bea4e154794f3f00180fa2a5c51fe8b005ac7a31cd58bd44cdfa7f36ebc3a9b" -- 2.43.0
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#237394): https://lists.openembedded.org/g/openembedded-core/message/237394 Mute This Topic: https://lists.openembedded.org/mt/119404640/21656 Group Owner: [email protected] Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
