Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 183 additions & 0 deletions SPECS/libssh2/CVE-2025-15661.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
From 12b8dfcc82b91fedad0a9fabf88da66061d1eb20 Mon Sep 17 00:00:00 2001
From: AllSpark <allspark@microsoft.com>
Date: Sat, 27 Jun 2026 08:25:53 +0000
Subject: [PATCH] Update sftp_symlink to avoid out of bounds read on malformed
packet

Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
Upstream-reference: AI Backport of https://github.com/libssh2/libssh2/commit/2dae3024897e1898d389835151f4e9606227721d
---
src/sftp.c | 118 ++++++++++++++++++++++++++++++-----------------------
1 file changed, 68 insertions(+), 50 deletions(-)

diff --git a/src/sftp.c b/src/sftp.c
index 6ede311..cf08ed4 100644
--- a/src/sftp.c
+++ b/src/sftp.c
@@ -3790,55 +3790,49 @@ libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, const char *path,
* Read or set a symlink
*/
static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
- unsigned int path_len, char *target,
- unsigned int target_len, int link_type)
+ uint32_t path_len, char *target, uint32_t target_len,
+ int link_type)
{
LIBSSH2_CHANNEL *channel = sftp->channel;
LIBSSH2_SESSION *session = channel->session;
- size_t data_len = 0, link_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);
+ size_t data_len = 0, lk_len;
+ uint32_t packet_len;
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;
-
- if((sftp->version < 3) && (link_type != LIBSSH2_SFTP_REALPATH)) {
- return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
- "Server does not support SYMLINK or"
- " READLINK");
- }
+ /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */
+ packet_len = 13;
+ if(link_type == LIBSSH2_SFTP_SYMLINK) {
+ /* source_len(4) + dest_len(4) */
+ packet_len += target_len + 4;
+ }
+ packet_len += path_len;

- s = sftp->symlink_packet = LIBSSH2_ALLOC(session, packet_len);
- if(!sftp->symlink_packet) {
+ if(sftp->symlink_state == libssh2_NB_state_idle) {
+ sftp->symlink_packet = LIBSSH2_ALLOC(session, packet_len);
+ if(!sftp->symlink_packet)
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
- "Unable to allocate memory for "
- "SYMLINK/READLINK/REALPATH packet");
- }
-
- _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "%s %s on %s",
- (link_type ==
- LIBSSH2_SFTP_SYMLINK) ? "Creating" : "Reading",
- (link_type ==
- LIBSSH2_SFTP_REALPATH) ? "realpath" : "symlink",
- path));
+ "Unable to allocate memory for FXP "
+ "SYMLINK/READLINK packet");

- _libssh2_store_u32(&s, (uint32_t)(packet_len - 4));
+ s = sftp->symlink_packet;
+ _libssh2_store_u32(&s, packet_len - 4);

switch(link_type) {
- case LIBSSH2_SFTP_REALPATH:
- *(s++) = SSH_FXP_REALPATH;
- break;
-
case LIBSSH2_SFTP_SYMLINK:
*(s++) = SSH_FXP_SYMLINK;
break;

+ case LIBSSH2_SFTP_REALPATH:
+ *(s++) = SSH_FXP_REALPATH;
+ break;
+
case LIBSSH2_SFTP_READLINK:
default:
*(s++) = SSH_FXP_READLINK;
@@ -3891,8 +3885,25 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,

sftp->symlink_state = libssh2_NB_state_idle;

- if(data[0] == SSH_FXP_STATUS) {
- retcode = _libssh2_ntohu32(data + 5);
+ buf.data = (unsigned char *)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 +3914,37 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
}
}

- 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;
--
2.45.4

45 changes: 45 additions & 0 deletions SPECS/libssh2/CVE-2026-55199.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
From c1ee41bd414465b274cba1e686ea8c47dcdb25f9 Mon Sep 17 00:00:00 2001
From: TristanInSec <tristan.mtn@gmail.com>
Date: Wed, 15 Apr 2026 14:51:08 -0400
Subject: [PATCH] packet: check `_libssh2_get_string()` return in `EXT_INFO`
handler

The `SSH_MSG_EXT_INFO` handler discards the return values from
`_libssh2_get_string()` when parsing extension name/value pairs. When
the buffer is exhausted before all claimed extensions are parsed,
the loop continues with no-op iterations until `nr_extensions` reaches
zero.

The `nr_extensions >= 1024` cap limits the worst case, but the loop
should still break on parse failure for correctness and consistency
with other parsers in this file (e.g. `SSH_MSG_CHANNEL_OPEN`,
`SSH_MSG_KEXINIT`) that check `_libssh2_get_string()` return values.

Closes #1864

Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
Upstream-reference: https://github.com/libssh2/libssh2/commit/17626857d20b3c9a1addfa45979dadcee1cd84a4.patch
---
src/packet.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/packet.c b/src/packet.c
index 6da14e9..ebaddae 100644
--- a/src/packet.c
+++ b/src/packet.c
@@ -868,8 +868,10 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,

nr_extensions -= 1;

- _libssh2_get_string(&buf, &name, &name_len);
- _libssh2_get_string(&buf, &value, &value_len);
+ if(_libssh2_get_string(&buf, &name, &name_len))
+ break;
+ if(_libssh2_get_string(&buf, &value, &value_len))
+ break;

if(name && value) {
_libssh2_debug((session,
--
2.45.4

7 changes: 6 additions & 1 deletion SPECS/libssh2/libssh2.spec
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Summary: libssh2 is a library implementing the SSH2 protocol.
Name: libssh2
Version: 1.11.1
Release: 3%{?dist}
Release: 4%{?dist}
License: BSD
URL: https://www.libssh2.org/
Group: System Environment/NetworkingLibraries
Expand All @@ -12,6 +12,8 @@ Distribution: Azure Linux
Source0: https://www.libssh2.org/download/libssh2-%{version}.tar.gz
Patch0: CVE-2026-7598.patch
Patch1: CVE-2026-55200.patch
Patch2: CVE-2025-15661.patch
Patch3: CVE-2026-55199.patch
BuildRequires: openssl-devel
BuildRequires: zlib-devel

Expand Down Expand Up @@ -59,6 +61,9 @@ find %{buildroot} -name '*.la' -exec rm -f {} ';'
%{_mandir}/man3/*

%changelog
* Sat Jun 27 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 1.11.1-4
- Patch for CVE-2026-55199, CVE-2025-15661

* Thu Jun 25 2026 Omkhar Arasaratnam <omkhar@linkedin.com> - 1.11.1-3
- Patch for CVE-2026-55200

Expand Down
4 changes: 2 additions & 2 deletions toolkit/resources/manifests/package/pkggen_core_aarch64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,8 @@ e2fsprogs-1.47.0-2.azl3.aarch64.rpm
e2fsprogs-devel-1.47.0-2.azl3.aarch64.rpm
libsolv-0.7.28-4.azl3.aarch64.rpm
libsolv-devel-0.7.28-4.azl3.aarch64.rpm
libssh2-1.11.1-3.azl3.aarch64.rpm
libssh2-devel-1.11.1-3.azl3.aarch64.rpm
libssh2-1.11.1-4.azl3.aarch64.rpm
libssh2-devel-1.11.1-4.azl3.aarch64.rpm
krb5-1.21.3-5.azl3.aarch64.rpm
krb5-devel-1.21.3-5.azl3.aarch64.rpm
nghttp2-1.61.0-3.azl3.aarch64.rpm
Expand Down
4 changes: 2 additions & 2 deletions toolkit/resources/manifests/package/pkggen_core_x86_64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,8 @@ e2fsprogs-1.47.0-2.azl3.x86_64.rpm
e2fsprogs-devel-1.47.0-2.azl3.x86_64.rpm
libsolv-0.7.28-4.azl3.x86_64.rpm
libsolv-devel-0.7.28-4.azl3.x86_64.rpm
libssh2-1.11.1-3.azl3.x86_64.rpm
libssh2-devel-1.11.1-3.azl3.x86_64.rpm
libssh2-1.11.1-4.azl3.x86_64.rpm
libssh2-devel-1.11.1-4.azl3.x86_64.rpm
krb5-1.21.3-5.azl3.x86_64.rpm
krb5-devel-1.21.3-5.azl3.x86_64.rpm
nghttp2-1.61.0-3.azl3.x86_64.rpm
Expand Down
6 changes: 3 additions & 3 deletions toolkit/resources/manifests/package/toolchain_aarch64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,9 @@ libsolv-0.7.28-4.azl3.aarch64.rpm
libsolv-debuginfo-0.7.28-4.azl3.aarch64.rpm
libsolv-devel-0.7.28-4.azl3.aarch64.rpm
libsolv-tools-0.7.28-4.azl3.aarch64.rpm
libssh2-1.11.1-3.azl3.aarch64.rpm
libssh2-debuginfo-1.11.1-3.azl3.aarch64.rpm
libssh2-devel-1.11.1-3.azl3.aarch64.rpm
libssh2-1.11.1-4.azl3.aarch64.rpm
libssh2-debuginfo-1.11.1-4.azl3.aarch64.rpm
libssh2-devel-1.11.1-4.azl3.aarch64.rpm
libstdc++-13.2.0-7.azl3.aarch64.rpm
libstdc++-devel-13.2.0-7.azl3.aarch64.rpm
libtasn1-4.19.0-3.azl3.aarch64.rpm
Expand Down
6 changes: 3 additions & 3 deletions toolkit/resources/manifests/package/toolchain_x86_64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,9 @@ libsolv-0.7.28-4.azl3.x86_64.rpm
libsolv-debuginfo-0.7.28-4.azl3.x86_64.rpm
libsolv-devel-0.7.28-4.azl3.x86_64.rpm
libsolv-tools-0.7.28-4.azl3.x86_64.rpm
libssh2-1.11.1-3.azl3.x86_64.rpm
libssh2-debuginfo-1.11.1-3.azl3.x86_64.rpm
libssh2-devel-1.11.1-3.azl3.x86_64.rpm
libssh2-1.11.1-4.azl3.x86_64.rpm
libssh2-debuginfo-1.11.1-4.azl3.x86_64.rpm
libssh2-devel-1.11.1-4.azl3.x86_64.rpm
libstdc++-13.2.0-7.azl3.x86_64.rpm
libstdc++-devel-13.2.0-7.azl3.x86_64.rpm
libtasn1-4.19.0-3.azl3.x86_64.rpm
Expand Down
Loading