From c32fa6335fb4d60aef2cd809a190c6f0701be05e Mon Sep 17 00:00:00 2001 From: Flatcar Buildbot Date: Mon, 13 Oct 2025 07:11:16 +0000 Subject: [PATCH] net-libs/gnutls: Sync with Gentoo It's from Gentoo commit cbdd4551ab43dfbdca5a91939888bb86bf4f0934. Signed-off-by: Flatcar Buildbot --- ...3.8.10-tls-migration-qemu-regression.patch | 299 ++++++++++++++++++ .../net-libs/gnutls/gnutls-3.8.10-r1.ebuild | 167 ++++++++++ 2 files changed, 466 insertions(+) create mode 100644 sdk_container/src/third_party/portage-stable/net-libs/gnutls/files/gnutls-3.8.10-tls-migration-qemu-regression.patch create mode 100644 sdk_container/src/third_party/portage-stable/net-libs/gnutls/gnutls-3.8.10-r1.ebuild diff --git a/sdk_container/src/third_party/portage-stable/net-libs/gnutls/files/gnutls-3.8.10-tls-migration-qemu-regression.patch b/sdk_container/src/third_party/portage-stable/net-libs/gnutls/files/gnutls-3.8.10-tls-migration-qemu-regression.patch new file mode 100644 index 0000000000..f3d3f05e45 --- /dev/null +++ b/sdk_container/src/third_party/portage-stable/net-libs/gnutls/files/gnutls-3.8.10-tls-migration-qemu-regression.patch @@ -0,0 +1,299 @@ +https://bugs.gentoo.org/961867 +https://issues.redhat.com/browse/RHEL-98672 +https://gitlab.com/gnutls/gnutls/-/issues/1717 +https://gitlab.com/gnutls/gnutls/-/merge_requests/1990 + +From 5376a0cabf94314316005e6bf411ffcc7628b386 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Tue, 22 Jul 2025 10:49:33 +0900 +Subject: [PATCH 1/3] key_update: fix state transition in KTLS code path + +Signed-off-by: Daiki Ueno +--- + lib/record.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/record.c b/lib/record.c +index d37f79a550..ebc75addec 100644 +--- a/lib/record.c ++++ b/lib/record.c +@@ -2045,7 +2045,7 @@ ssize_t gnutls_record_send2(gnutls_session_t session, const void *data, + FALLTHROUGH; + case RECORD_SEND_KEY_UPDATE_3: + if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_SEND)) { +- return _gnutls_ktls_send( ++ ret = _gnutls_ktls_send( + session, + session->internals.record_key_update_buffer.data, + session->internals.record_key_update_buffer +-- +GitLab + + +From 30c264b661d49d135ef342426c6c4cd853209c06 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Thu, 31 Jul 2025 15:34:48 +0900 +Subject: [PATCH 2/3] constate: switch epoch lookup to linear search + +The previous logic of epoch lookup was utilizing the fact that epoch +numbers are monotonically increasing and there are no gaps in between +after garbarge collection. That is, however, no longer true when a TLS +1.3 key update is happening in only one direction. + +This patch switches to using linear search instead, at the cost of +approx MAX_EPOCH_INDEX * 2 (= 8) comparison. + +Signed-off-by: Daiki Ueno +--- + lib/constate.c | 47 ++++++++++++++++------------------------------- + lib/gnutls_int.h | 3 --- + 2 files changed, 16 insertions(+), 34 deletions(-) + +diff --git a/lib/constate.c b/lib/constate.c +index ca253a2bea..b091d891ff 100644 +--- a/lib/constate.c ++++ b/lib/constate.c +@@ -932,17 +932,23 @@ static inline int epoch_resolve(gnutls_session_t session, + static inline record_parameters_st **epoch_get_slot(gnutls_session_t session, + uint16_t epoch) + { +- uint16_t epoch_index = epoch - session->security_parameters.epoch_min; ++ /* First look for a non-empty slot */ ++ for (size_t i = 0; i < MAX_EPOCH_INDEX; i++) { ++ record_parameters_st **slot = &session->record_parameters[i]; ++ if (*slot != NULL && (*slot)->epoch == epoch) ++ return slot; ++ } + +- if (epoch_index >= MAX_EPOCH_INDEX) { +- _gnutls_handshake_log( +- "Epoch %d out of range (idx: %d, max: %d)\n", +- (int)epoch, (int)epoch_index, MAX_EPOCH_INDEX); +- gnutls_assert(); +- return NULL; ++ /* Then look for an empty slot */ ++ for (size_t i = 0; i < MAX_EPOCH_INDEX; i++) { ++ record_parameters_st **slot = &session->record_parameters[i]; ++ if (*slot == NULL) ++ return slot; + } +- /* The slot may still be empty (NULL) */ +- return &session->record_parameters[epoch_index]; ++ ++ gnutls_assert(); ++ _gnutls_handshake_log("No slot available for epoch %u\n", epoch); ++ return NULL; + } + + int _gnutls_epoch_get(gnutls_session_t session, unsigned int epoch_rel, +@@ -1063,8 +1069,7 @@ static inline int epoch_alive(gnutls_session_t session, + + void _gnutls_epoch_gc(gnutls_session_t session) + { +- int i, j; +- unsigned int min_index = 0; ++ int i; + + _gnutls_record_log("REC[%p]: Start of epoch cleanup\n", session); + +@@ -1091,26 +1096,6 @@ void _gnutls_epoch_gc(gnutls_session_t session) + } + } + +- /* Look for contiguous NULLs at the start of the array */ +- for (i = 0; +- i < MAX_EPOCH_INDEX && session->record_parameters[i] == NULL; i++) +- ; +- min_index = i; +- +- /* Pick up the slack in the epoch window. */ +- if (min_index != 0) { +- for (i = 0, j = min_index; j < MAX_EPOCH_INDEX; i++, j++) { +- session->record_parameters[i] = +- session->record_parameters[j]; +- session->record_parameters[j] = NULL; +- } +- } +- +- /* Set the new epoch_min */ +- if (session->record_parameters[0] != NULL) +- session->security_parameters.epoch_min = +- session->record_parameters[0]->epoch; +- + gnutls_mutex_unlock(&session->internals.epoch_lock); + + _gnutls_record_log("REC[%p]: End of epoch cleanup\n", session); +diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h +index 539486bc7d..e083520055 100644 +--- a/lib/gnutls_int.h ++++ b/lib/gnutls_int.h +@@ -876,9 +876,6 @@ typedef struct { + /* The epoch that the next handshake will initialize. */ + uint16_t epoch_next; + +- /* The epoch at index 0 of record_parameters. */ +- uint16_t epoch_min; +- + /* this is the ciphersuite we are going to use + * moved here from internals in order to be restored + * on resume; +-- +GitLab + + +From 1d830baac2f8a08a40b13e9eecfcc64ad032e7b5 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Sat, 19 Jul 2025 07:08:24 +0900 +Subject: [PATCH 3/3] key_update: rework the rekeying logic + +While RFC 8446 4.6.3 says that the sender of a KeyUpdate message +should only update its sending key, the previous implementation +updated both the sending and receiving keys, preventing that any +application data interleaved being decrypted. + +This splits the key update logic into 2 phases: when sending a +KeyUpdate, only update the sending key, and when receiving a +KeyUpdate, only update the receiving key. In both cases, KeyUpdate +messages are encrypted/decrypted with the old keys. + +Signed-off-by: Daiki Ueno +--- + lib/gnutls_int.h | 2 +- + lib/tls13/key_update.c | 72 +++++++++++++++++++++++++++--------------- + 2 files changed, 47 insertions(+), 27 deletions(-) + +diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h +index e083520055..f3caea1170 100644 +--- a/lib/gnutls_int.h ++++ b/lib/gnutls_int.h +@@ -1672,7 +1672,7 @@ typedef struct { + } internals_st; + + /* Maximum number of epochs we keep around. */ +-#define MAX_EPOCH_INDEX 4 ++#define MAX_EPOCH_INDEX 16 + + #define reset_cand_groups(session) \ + session->internals.cand_ec_group = session->internals.cand_dh_group = \ +diff --git a/lib/tls13/key_update.c b/lib/tls13/key_update.c +index 41243651b5..beee1dc41a 100644 +--- a/lib/tls13/key_update.c ++++ b/lib/tls13/key_update.c +@@ -52,45 +52,47 @@ static inline int set_ktls_keys(gnutls_session_t session, + return 0; + } + +-static int update_keys(gnutls_session_t session, hs_stage_t stage) ++static int update_sending_key(gnutls_session_t session, hs_stage_t stage) + { + int ret; + +- ret = _tls13_update_secret(session, +- session->key.proto.tls13.temp_secret, +- session->key.proto.tls13.temp_secret_size); ++ _gnutls_epoch_bump(session); ++ ret = _gnutls_epoch_dup(session, EPOCH_WRITE_CURRENT); + if (ret < 0) + return gnutls_assert_val(ret); + +- _gnutls_epoch_bump(session); +- ret = _gnutls_epoch_dup(session, EPOCH_READ_CURRENT); ++ ret = _tls13_write_connection_state_init(session, stage); + if (ret < 0) + return gnutls_assert_val(ret); + +- /* If we send a key update during early start, only update our +- * write keys */ +- if (session->internals.recv_state == RECV_STATE_EARLY_START) { +- ret = _tls13_write_connection_state_init(session, stage); ++ if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_SEND)) { ++ ret = set_ktls_keys(session, GNUTLS_KTLS_SEND); + if (ret < 0) + return gnutls_assert_val(ret); ++ } + +- if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_SEND)) +- ret = set_ktls_keys(session, GNUTLS_KTLS_SEND); +- } else { +- ret = _tls13_connection_state_init(session, stage); +- if (ret < 0) +- return gnutls_assert_val(ret); ++ return 0; ++} + +- if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_SEND) && +- stage == STAGE_UPD_OURS) +- ret = set_ktls_keys(session, GNUTLS_KTLS_SEND); +- else if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_RECV) && +- stage == STAGE_UPD_PEERS) +- ret = set_ktls_keys(session, GNUTLS_KTLS_RECV); +- } ++static int update_receiving_key(gnutls_session_t session, hs_stage_t stage) ++{ ++ int ret; ++ ++ _gnutls_epoch_bump(session); ++ ret = _gnutls_epoch_dup(session, EPOCH_READ_CURRENT); ++ if (ret < 0) ++ return gnutls_assert_val(ret); ++ ++ ret = _tls13_read_connection_state_init(session, stage); + if (ret < 0) + return gnutls_assert_val(ret); + ++ if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_RECV)) { ++ ret = set_ktls_keys(session, GNUTLS_KTLS_RECV); ++ if (ret < 0) ++ return gnutls_assert_val(ret); ++ } ++ + return 0; + } + +@@ -128,7 +130,13 @@ int _gnutls13_recv_key_update(gnutls_session_t session, gnutls_buffer_st *buf) + switch (buf->data[0]) { + case 0: + /* peer updated its key, not requested our key update */ +- ret = update_keys(session, STAGE_UPD_PEERS); ++ ret = _tls13_update_secret( ++ session, session->key.proto.tls13.temp_secret, ++ session->key.proto.tls13.temp_secret_size); ++ if (ret < 0) ++ return gnutls_assert_val(ret); ++ ++ ret = update_receiving_key(session, STAGE_UPD_PEERS); + if (ret < 0) + return gnutls_assert_val(ret); + +@@ -141,7 +149,13 @@ int _gnutls13_recv_key_update(gnutls_session_t session, gnutls_buffer_st *buf) + } + + /* peer updated its key, requested our key update */ +- ret = update_keys(session, STAGE_UPD_PEERS); ++ ret = _tls13_update_secret( ++ session, session->key.proto.tls13.temp_secret, ++ session->key.proto.tls13.temp_secret_size); ++ if (ret < 0) ++ return gnutls_assert_val(ret); ++ ++ ret = update_receiving_key(session, STAGE_UPD_PEERS); + if (ret < 0) + return gnutls_assert_val(ret); + +@@ -248,7 +262,13 @@ int gnutls_session_key_update(gnutls_session_t session, unsigned flags) + _gnutls_epoch_gc(session); + + /* it was completely sent, update the keys */ +- ret = update_keys(session, STAGE_UPD_OURS); ++ ret = _tls13_update_secret(session, ++ session->key.proto.tls13.temp_secret, ++ session->key.proto.tls13.temp_secret_size); ++ if (ret < 0) ++ return gnutls_assert_val(ret); ++ ++ ret = update_sending_key(session, STAGE_UPD_OURS); + if (ret < 0) + return gnutls_assert_val(ret); + +-- +GitLab diff --git a/sdk_container/src/third_party/portage-stable/net-libs/gnutls/gnutls-3.8.10-r1.ebuild b/sdk_container/src/third_party/portage-stable/net-libs/gnutls/gnutls-3.8.10-r1.ebuild new file mode 100644 index 0000000000..4156212331 --- /dev/null +++ b/sdk_container/src/third_party/portage-stable/net-libs/gnutls/gnutls-3.8.10-r1.ebuild @@ -0,0 +1,167 @@ +# Copyright 1999-2025 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +VERIFY_SIG_OPENPGP_KEY_PATH=/usr/share/openpgp-keys/gnutls.asc +inherit libtool multilib-minimal verify-sig + +DESCRIPTION="A secure communications library implementing the SSL, TLS and DTLS protocols" +HOMEPAGE="https://www.gnutls.org/" +SRC_URI="mirror://gnupg/gnutls/v$(ver_cut 1-2)/${P}.tar.xz" +SRC_URI+=" verify-sig? ( mirror://gnupg/gnutls/v$(ver_cut 1-2)/${P}.tar.xz.sig )" + +LICENSE="GPL-3 LGPL-2.1+" +# As of 3.8.0, the C++ library is header-only, but we won't drop the subslot +# component for it until libgnutls.so breaks ABI, to avoid pointless rebuilds. +# Subslot format: +# . +SLOT="0/30.30" +KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~loong ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86 ~amd64-linux ~x86-linux ~arm64-macos ~ppc-macos ~x64-macos ~x64-solaris" +IUSE="brotli +cxx dane doc examples +idn nls +openssl pkcs11 sslv2 sslv3 static-libs test test-full +tls-heartbeat tools zlib zstd" +REQUIRED_USE="test-full? ( cxx dane doc examples idn nls openssl pkcs11 tls-heartbeat tools )" +RESTRICT="!test? ( test )" + +# >=nettle-3.10 as a workaround for bug #936011 +RDEPEND=" + >=dev-libs/libtasn1-4.9:=[${MULTILIB_USEDEP}] + dev-libs/libunistring:=[${MULTILIB_USEDEP}] + >=dev-libs/nettle-3.10:=[gmp,${MULTILIB_USEDEP}] + >=dev-libs/gmp-5.1.3-r1:=[${MULTILIB_USEDEP}] + brotli? ( >=app-arch/brotli-1.0.0:=[${MULTILIB_USEDEP}] ) + dane? ( >=net-dns/unbound-1.4.20:=[${MULTILIB_USEDEP}] ) + nls? ( >=virtual/libintl-0-r1:=[${MULTILIB_USEDEP}] ) + pkcs11? ( >=app-crypt/p11-kit-0.23.1[${MULTILIB_USEDEP}] ) + idn? ( >=net-dns/libidn2-0.16-r1:=[${MULTILIB_USEDEP}] ) + zlib? ( sys-libs/zlib[${MULTILIB_USEDEP}] ) + zstd? ( >=app-arch/zstd-1.3.0:=[${MULTILIB_USEDEP}] ) +" +DEPEND=" + ${RDEPEND} + test-full? ( sys-libs/libseccomp ) +" +BDEPEND=" + dev-build/gtk-doc-am + >=virtual/pkgconfig-0-r1 + doc? ( dev-util/gtk-doc ) + nls? ( sys-devel/gettext ) + test-full? ( + app-crypt/dieharder + || ( sys-libs/libfaketime >=app-misc/datefudge-1.22 ) + dev-libs/softhsm:2[-bindist(-)] + net-dialup/ppp + net-misc/socat + ) + verify-sig? ( >=sec-keys/openpgp-keys-gnutls-20240415 ) +" + +DOCS=( README.md doc/certtool.cfg ) + +HTML_DOCS=() + +QA_CONFIG_IMPL_DECL_SKIP=( + # gnulib FPs + MIN + alignof + static_assert +) + +PATCHES=( + "${FILESDIR}"/${PN}-3.8.10-tests.patch + "${FILESDIR}"/${PN}-3.8.10-tls-migration-qemu-regression.patch +) + +src_prepare() { + default + + # bug #520818 + export TZ=UTC + + use doc && HTML_DOCS+=( doc/gnutls.html ) + + # don't try to use system certificate store on macOS, it is + # confusingly ignoring our ca-certificates and more importantly + # fails to compile in certain configurations + sed -i -e 's/__APPLE__/__NO_APPLE__/' lib/system/certs.c || die + + # Fails with some combinations of USE="brotli zlib zstd" + # https://gitlab.com/gnutls/gnutls/-/issues/1721 + # https://gitlab.com/gnutls/gnutls/-/merge_requests/1980 + cat <<-EOF > tests/system-override-compress-cert.sh || die + #!/bin/sh + exit 77 + EOF + chmod +x tests/system-override-compress-cert.sh || die + + elibtoolize +} + +multilib_src_configure() { + LINGUAS="${LINGUAS//en/en@boldquot en@quot}" + + local libconf=() + + # TPM needs to be tested before being enabled + # Note that this may add a libltdl dep when enabled. Check configure.ac. + libconf+=( + --without-tpm + --without-tpm2 + ) + + # hardware-accel is disabled on OSX because the asm files force + # GNU-stack (as doesn't support that) and when that's removed ld + # complains about duplicate symbols + [[ ${CHOST} == *-darwin* ]] && libconf+=( --disable-hardware-acceleration ) + + # -fanalyzer substantially slows down the build and isn't useful for + # us. It's useful for upstream as it's static analysis, but it's not + # useful when just getting something built. + export gl_cv_warn_c__fanalyzer=no + + local myeconfargs=( + --disable-valgrind-tests + $(multilib_native_enable manpages) + $(multilib_native_use_enable doc gtk-doc) + $(multilib_native_use_enable doc) + $(multilib_native_use_enable test tests) + $(multilib_native_use_enable test-full full-test-suite) + $(multilib_native_use_enable test-full seccomp-tests) + $(multilib_native_use_enable tools) + $(use_enable cxx) + $(use_enable dane libdane) + $(use_enable nls) + $(use_enable openssl openssl-compatibility) + $(use_enable sslv2 ssl2-support) + $(use_enable sslv3 ssl3-support) + $(use_enable static-libs static) + $(use_enable tls-heartbeat heartbeat-support) + $(use_with brotli '' link) + $(use_with idn) + $(use_with pkcs11 p11-kit) + $(use_with zlib '' link) + $(use_with zstd '' link) + --disable-rpath + --with-default-trust-store-file="${EPREFIX}"/etc/ssl/certs/ca-certificates.crt + --with-unbound-root-key-file="${EPREFIX}"/etc/dnssec/root-anchors.txt + --without-included-libtasn1 + $("${S}/configure" --help | grep -o -- '--without-.*-prefix') + ) + + ECONF_SOURCE="${S}" econf "${libconf[@]}" "${myeconfargs[@]}" + + if [[ ${CHOST} == *-solaris* ]] ; then + # gnulib ends up defining its own pthread_mutexattr_gettype + # otherwise, which is causing versioning problems + echo "#define PTHREAD_IN_USE_DETECTION_HARD 1" >> config.h || die + fi +} + +multilib_src_install_all() { + einstalldocs + find "${ED}" -type f -name '*.la' -delete || die + + if use examples; then + docinto examples + dodoc doc/examples/*.c + fi +}