libssh: Fix CVE-2026-3731

Pick commits according to [1]

[1] https://security-tracker.debian.org/tracker/CVE-2026-3731
[2] https://www.libssh.org/security/advisories/libssh-2026-sftp-extensions.txt

Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
Vijay Anusuri 2026-03-11 13:07:51 +05:30 committed by Anuj Mittal
parent a88f173ed0
commit 59b94e41bf
No known key found for this signature in database
GPG Key ID: 4340AEFE69F5085C
3 changed files with 148 additions and 0 deletions

View File

@ -0,0 +1,44 @@
From f80670a7aba86cbb442c9b115c9eaf4ca04601b8 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Thu, 11 Dec 2025 13:22:44 +0100
Subject: [PATCH] sftp: Fix out-of-bound read from sftp extensions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Pavol Žáčik <pzacik@redhat.com>
(cherry picked from commit 855a0853ad3abd4a6cd85ce06fce6d8d4c7a0b60)
Upstream-Status: Backport [https://git.libssh.org/projects/libssh.git/commit/?id=f80670a7aba86cbb442c9b115c9eaf4ca04601b8]
CVE: CVE-2026-3731
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
---
src/sftp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/sftp.c b/src/sftp.c
index e01012a8..4a77141b 100644
--- a/src/sftp.c
+++ b/src/sftp.c
@@ -768,7 +768,7 @@ const char *sftp_extensions_get_name(sftp_session sftp, unsigned int idx) {
return NULL;
}
- if (idx > sftp->ext->count) {
+ if (idx >= sftp->ext->count) {
ssh_set_error_invalid(sftp->session);
return NULL;
}
@@ -784,7 +784,7 @@ const char *sftp_extensions_get_data(sftp_session sftp, unsigned int idx) {
return NULL;
}
- if (idx > sftp->ext->count) {
+ if (idx >= sftp->ext->count) {
ssh_set_error_invalid(sftp->session);
return NULL;
}
--
2.43.0

View File

@ -0,0 +1,102 @@
From 02c6f5f7ec8629a7cff6a28cde9701ab10304540 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Thu, 11 Dec 2025 13:21:23 +0100
Subject: Reproducer for out of bounds read of SFTP extensions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Pavol Žáčik <pzacik@redhat.com>
(cherry picked from commit b90b7f24517efa7ab21506db9379aa3dce9fee7d)
Upstream-Status: Backport [https://git.libssh.org/projects/libssh.git/commit/?id=02c6f5f7ec8629a7cff6a28cde9701ab10304540]
CVE: CVE-2026-3731
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
---
tests/client/torture_sftp_init.c | 62 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 61 insertions(+), 1 deletion(-)
diff --git a/tests/client/torture_sftp_init.c b/tests/client/torture_sftp_init.c
index a17f01fe2..cdc244263 100644
--- a/tests/client/torture_sftp_init.c
+++ b/tests/client/torture_sftp_init.c
@@ -72,6 +72,63 @@ static void session_setup_channel(void **state)
assert_non_null(s->ssh.tsftp);
}
+static void session_setup_extensions(void **state)
+{
+ struct torture_state *s = *state;
+ struct passwd *pwd = NULL;
+ int rc, count;
+ const char *name = NULL, *data = NULL;
+ sftp_session sftp = NULL;
+
+ pwd = getpwnam("bob");
+ assert_non_null(pwd);
+
+ rc = setuid(pwd->pw_uid);
+ assert_return_code(rc, errno);
+
+ s->ssh.session = torture_ssh_session(s,
+ TORTURE_SSH_SERVER,
+ NULL,
+ TORTURE_SSH_USER_ALICE,
+ NULL);
+ assert_non_null(s->ssh.session);
+
+ s->ssh.tsftp = torture_sftp_session(s->ssh.session);
+ assert_non_null(s->ssh.tsftp);
+ sftp = s->ssh.tsftp->sftp;
+
+ /* null parameter */
+ count = sftp_extensions_get_count(NULL);
+ assert_int_equal(count, 0);
+
+ count = sftp_extensions_get_count(sftp);
+ assert_int_not_equal(count, 0);
+
+ /* first null parameter */
+ name = sftp_extensions_get_name(NULL, 0);
+ assert_null(name);
+ data = sftp_extensions_get_data(NULL, 0);
+ assert_null(data);
+
+ /* First extension */
+ name = sftp_extensions_get_name(sftp, 0);
+ assert_non_null(name);
+ data = sftp_extensions_get_data(sftp, 0);
+ assert_non_null(data);
+
+ /* Last extension */
+ name = sftp_extensions_get_name(sftp, count - 1);
+ assert_non_null(name);
+ data = sftp_extensions_get_data(sftp, count - 1);
+ assert_non_null(data);
+
+ /* Overrun */
+ name = sftp_extensions_get_name(sftp, count);
+ assert_null(name);
+ data = sftp_extensions_get_data(sftp, count);
+ assert_null(data);
+}
+
static int session_teardown(void **state)
{
struct torture_state *s = *state;
@@ -92,7 +149,10 @@ int torture_run_tests(void) {
session_teardown),
cmocka_unit_test_setup_teardown(session_setup_channel,
NULL,
- session_teardown)
+ session_teardown),
+ cmocka_unit_test_setup_teardown(session_setup_extensions,
+ NULL,
+ session_teardown),
};
ssh_init();
--
cgit v1.2.3

View File

@ -22,6 +22,8 @@ SRC_URI = "git://git.libssh.org/projects/libssh.git;protocol=https;branch=stable
file://CVE-2025-8277-2.patch \
file://CVE-2025-8277-3.patch \
file://CVE-2025-8277-4.patch \
file://CVE-2026-3731-1.patch \
file://CVE-2026-3731-2.patch \
"
SRCREV = "10e09e273f69e149389b3e0e5d44b8c221c2e7f6"