diff --git a/net-libs/libssh2/files/libssh2-1.11.1-CVE-2025-15661-sftp.patch b/net-libs/libssh2/files/libssh2-1.11.1-CVE-2025-15661-sftp.patch new file mode 100644 index 0000000000000..816e08f363c7b --- /dev/null +++ b/net-libs/libssh2/files/libssh2-1.11.1-CVE-2025-15661-sftp.patch @@ -0,0 +1,107 @@ +https://github.com/libssh2/libssh2/commit/2dae3024897e1898d389835151f4e9606227721d +https://bugs.gentoo.org/977961#c9 +--- a/src/sftp.c 2024-10-16 10:03:21.000000000 +0200 ++++ b/src/sftp.c 2026-07-07 00:53:47.620941153 +0200 +@@ -3795,15 +3795,19 @@ + { + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; +- size_t data_len = 0, link_len; ++ size_t data_len = 0, lk_len; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + ssize_t packet_len = + path_len + 13 + + ((link_type == LIBSSH2_SFTP_SYMLINK) ? (4 + target_len) : 0); + unsigned char *s, *data = NULL; ++ struct string_buf buf; + static const unsigned char link_responses[2] = + { SSH_FXP_NAME, SSH_FXP_STATUS }; + int retcode; ++ unsigned char packet_type; ++ uint32_t tmp_u32; ++ unsigned char *lk_target; + + if(sftp->symlink_state == libssh2_NB_state_idle) { + sftp->last_errno = LIBSSH2_FX_OK; +@@ -3891,8 +3895,25 @@ + + sftp->symlink_state = libssh2_NB_state_idle; + +- if(data[0] == SSH_FXP_STATUS) { +- retcode = _libssh2_ntohu32(data + 5); ++ buf.data = data; ++ buf.dataptr = buf.data; ++ buf.len = data_len; ++ ++ if(_libssh2_get_byte(&buf, &packet_type)) { ++ LIBSSH2_FREE(session, data); ++ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, ++ "SFTP Protocol Error (type)"); ++ } ++ ++ if(packet_type == SSH_FXP_STATUS) { ++ if(_libssh2_get_u32(&buf, &tmp_u32)) { ++ LIBSSH2_FREE(session, data); ++ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, ++ "SFTP Protocol Error (code)"); ++ } ++ ++ retcode = (int)tmp_u32; ++ + LIBSSH2_FREE(session, data); + if(retcode == LIBSSH2_FX_OK) + return LIBSSH2_ERROR_NONE; +@@ -3903,30 +3924,37 @@ + } + } + +- if(_libssh2_ntohu32(data + 5) < 1) { ++ /* advance past id */ ++ if(_libssh2_get_u32(&buf, &tmp_u32)) { + LIBSSH2_FREE(session, data); + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, +- "Invalid READLINK/REALPATH response, " +- "no name entries"); ++ "SFTP Protocol Error (id)"); + } + +- if(data_len < 13) { +- if(data_len > 0) { +- LIBSSH2_FREE(session, data); +- } ++ /* look for at least one link */ ++ if(_libssh2_get_u32(&buf, &tmp_u32) || tmp_u32 < 1) { ++ LIBSSH2_FREE(session, data); + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, +- "SFTP stat packet too short"); ++ "Invalid READLINK/REALPATH response, " ++ "no name entries"); + } + +- /* this reads a u32 and stores it into a signed 32bit value */ +- link_len = _libssh2_ntohu32(data + 9); +- if(link_len < target_len) { +- memcpy(target, data + 13, link_len); +- target[link_len] = 0; +- retcode = (int)link_len; ++ if(_libssh2_get_string(&buf, &lk_target, &lk_len) == LIBSSH2_ERROR_NONE) { ++ if(lk_len < target_len) { ++ memcpy(target, lk_target, lk_len); ++ target[lk_len] = '\0'; ++ retcode = (int)lk_len; ++ } ++ else { ++ retcode = LIBSSH2_ERROR_BUFFER_TOO_SMALL; ++ } + } +- else +- retcode = LIBSSH2_ERROR_BUFFER_TOO_SMALL; ++ else { ++ LIBSSH2_FREE(session, data); ++ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, ++ "SFTP Protocol Error (filename)"); ++ } ++ + LIBSSH2_FREE(session, data); + + return retcode; diff --git a/net-libs/libssh2/files/libssh2-1.11.1-CVE-2026-55200-transport.patch b/net-libs/libssh2/files/libssh2-1.11.1-CVE-2026-55200-transport.patch new file mode 100644 index 0000000000000..dae5db1c25d1a --- /dev/null +++ b/net-libs/libssh2/files/libssh2-1.11.1-CVE-2026-55200-transport.patch @@ -0,0 +1,18 @@ +https://github.com/libssh2/libssh2/commit/97acf3dfda80c91c3a8c9f2372546301d4a1a7a8 +https://bugs.gentoo.org/977961#c11 +--- a/src/transport.c 2024-10-16 10:03:21.000000000 +0200 ++++ b/src/transport.c 2026-07-07 02:38:20.942968610 +0200 +@@ -639,8 +639,12 @@ + total_num = 4; + + p->packet_length = _libssh2_ntohu32(block); +- if(p->packet_length < 1) ++ if(p->packet_length < 1) { + return LIBSSH2_ERROR_DECRYPT; ++ } ++ else if(p->packet_length > LIBSSH2_PACKET_MAXPAYLOAD) { ++ return LIBSSH2_ERROR_OUT_OF_BOUNDARY; ++ } + + /* total_num may include size field, however due to existing + * logic it needs to be removed after the entire packet is read diff --git a/net-libs/libssh2/files/libssh2-1.11.1-CVE-2026-7598.patch b/net-libs/libssh2/files/libssh2-1.11.1-CVE-2026-7598.patch new file mode 100644 index 0000000000000..fd321b2fd2314 --- /dev/null +++ b/net-libs/libssh2/files/libssh2-1.11.1-CVE-2026-7598.patch @@ -0,0 +1,55 @@ +https://github.com/libssh2/libssh2/commit/256d04b60d80bf1190e96b0ad1e91b2174d744b1 + +From 256d04b60d80bf1190e96b0ad1e91b2174d744b1 Mon Sep 17 00:00:00 2001 +From: Will Cosgrove +Date: Mon, 13 Apr 2026 11:18:25 -0700 +Subject: [PATCH] userauth.c: username_len bounds checking (#1858) + +Return errors when username_len will exceed bounds, fix existing bounds +check. + +Credit: +[dapickle](https://github.com/dapickle) +--- + src/userauth.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/src/userauth.c b/src/userauth.c +index f8e02651c4..43d9ab9b9d 100644 +--- a/src/userauth.c ++++ b/src/userauth.c +@@ -80,6 +80,12 @@ static char *userauth_list(LIBSSH2_SESSION *session, const char *username, + memset(&session->userauth_list_packet_requirev_state, 0, + sizeof(session->userauth_list_packet_requirev_state)); + ++ if(username_len > UINT32_MAX - 27) { ++ _libssh2_error(session, LIBSSH2_ERROR_PROTO, ++ "username_len out of bounds"); ++ return NULL; ++ } ++ + session->userauth_list_data_len = username_len + 27; + + if(session->userauth_list_data) { +@@ -316,6 +322,11 @@ userauth_password(LIBSSH2_SESSION *session, + * 40 = packet_type(1) + username_len(4) + service_len(4) + + * service(14)"ssh-connection" + method_len(4) + method(8)"password" + + * chgpwdbool(1) + password_len(4) */ ++ if(username_len > UINT32_MAX - 40) { ++ return _libssh2_error(session, LIBSSH2_ERROR_PROTO, ++ "username_len out of bounds"); ++ } ++ + session->userauth_pswd_data_len = username_len + 40; + + session->userauth_pswd_data0 = +@@ -456,7 +467,7 @@ userauth_password(LIBSSH2_SESSION *session, + } + + /* basic data_len + newpw_len(4) */ +- if(username_len + password_len + 44 <= UINT_MAX) { ++ if(username_len <= UINT32_MAX - password_len - 44) { + session->userauth_pswd_data_len = + username_len + password_len + 44; + s = session->userauth_pswd_data = + diff --git a/net-libs/libssh2/libssh2-1.11.1-r1.ebuild b/net-libs/libssh2/libssh2-1.11.1-r1.ebuild new file mode 100644 index 0000000000000..3eeb3513f3f66 --- /dev/null +++ b/net-libs/libssh2/libssh2-1.11.1-r1.ebuild @@ -0,0 +1,78 @@ +# Copyright 1999-2026 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +VERIFY_SIG_OPENPGP_KEY_PATH=/usr/share/openpgp-keys/danielstenberg.asc +inherit cmake-multilib verify-sig + +DESCRIPTION="Library implementing the SSH2 protocol" +HOMEPAGE="https://libssh2.org" +SRC_URI=" + https://libssh2.org/download/${P}.tar.xz + verify-sig? ( + https://libssh2.org/download/${P}.tar.xz.asc + ) +" + +LICENSE="BSD" +SLOT="0" +KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~loong ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86 ~x64-macos" +IUSE="gcrypt mbedtls test zlib" +REQUIRED_USE="?? ( gcrypt mbedtls )" +RESTRICT="!test? ( test )" + +RDEPEND=" + gcrypt? ( >=dev-libs/libgcrypt-1.5.3:0[${MULTILIB_USEDEP}] ) + !gcrypt? ( + mbedtls? ( net-libs/mbedtls:0=[${MULTILIB_USEDEP}] ) + !mbedtls? ( + >=dev-libs/openssl-1.0.1h-r2:0=[${MULTILIB_USEDEP}] + ) + ) + zlib? ( >=virtual/zlib-1.2.8-r1:=[${MULTILIB_USEDEP}] ) +" +DEPEND=" + ${RDEPEND} +" +BDEPEND=" + verify-sig? ( sec-keys/openpgp-keys-danielstenberg ) +" + +PATCHES=( + "${FILESDIR}"/${PN}-1.11.0-mansyntax_sh.patch + "${FILESDIR}"/${PN}-1.11.1-CVE-2025-15661-sftp.patch + "${FILESDIR}"/${PN}-1.11.1-CVE-2026-55200-transport.patch + "${FILESDIR}"/${PN}-1.11.1-CVE-2026-7598.patch +) + +multilib_src_configure() { + local crypto_backend=OpenSSL + if use gcrypt; then + crypto_backend=Libgcrypt + elif use mbedtls; then + crypto_backend=mbedTLS + fi + + local mycmakeargs=( + -DBUILD_SHARED_LIBS=ON + -DBUILD_STATIC_LIBS=OFF + -DBUILD_TESTING=$(usex test) + -DCRYPTO_BACKEND=${crypto_backend} + -DENABLE_ZLIB_COMPRESSION=$(usex zlib) + ) + + if use test ; then + # Pass separately to avoid unused var warnings w/ USE=-test + mycmakeargs+=( + -DRUN_SSHD_TESTS=OFF + -DRUN_DOCKER_TESTS=OFF + ) + fi + + cmake_src_configure +} + +multilib_src_install_all() { + einstalldocs +}