diff mbox series

[meta-oe,scarthgap,3/5] libssh: patch CVE-2026-0968

Message ID 20260428050109.2099228-3-ankur.tyagi85@gmail.com
State Under Review
Delegated to: Anuj Mittal
Headers show
Series [meta-networking,scarthgap,1/5] corosync: patch CVE-2026-35091 | expand

Commit Message

Ankur Tyagi April 28, 2026, 5:01 a.m. UTC
From: Ankur Tyagi <ankur.tyagi85@gmail.com>

Backport patches [1] and [2] as mentioned in [3]

[1] https://git.libssh.org/projects/libssh.git/commit/?id=796d85f786dff62bd4bcc4408d9b7bbc855841e9
[2] https://git.libssh.org/projects/libssh.git/commit/?id=212121971fb26e1e00b72bd5402c0454a4d84c03
[3] https://security-tracker.debian.org/tracker/CVE-2026-0968

Certain functions from sftp.c were moved to a new file sftp_common.c
in version 0.11.0 by following commit:
https://git.libssh.org/projects/libssh.git/commit/src/sftp_common.c?id=c3e03ab4651e4f3382e3a51c0273ade894f0c48a

This is the backport of the changes using the original file sftp.c

Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
---
 .../libssh/libssh/CVE-2026-0968-1.patch       |  64 +++++++++
 .../libssh/libssh/CVE-2026-0968-2.patch       | 136 ++++++++++++++++++
 .../recipes-support/libssh/libssh_0.10.6.bb   |   2 +
 3 files changed, 202 insertions(+)
 create mode 100644 meta-oe/recipes-support/libssh/libssh/CVE-2026-0968-1.patch
 create mode 100644 meta-oe/recipes-support/libssh/libssh/CVE-2026-0968-2.patch
diff mbox series

Patch

diff --git a/meta-oe/recipes-support/libssh/libssh/CVE-2026-0968-1.patch b/meta-oe/recipes-support/libssh/libssh/CVE-2026-0968-1.patch
new file mode 100644
index 0000000000..5ed1a4e940
--- /dev/null
+++ b/meta-oe/recipes-support/libssh/libssh/CVE-2026-0968-1.patch
@@ -0,0 +1,64 @@ 
+From 9fd388141c973ba6fb7d45966c25d1fad9e1d419 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Mon, 22 Dec 2025 20:59:11 +0100
+Subject: [PATCH] CVE-2026-0968: sftp: Sanitize input handling in
+ sftp_parse_longname()
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
+
+CVE: CVE-2026-0968
+Upstream-Status: Backport [https://git.libssh.org/projects/libssh.git/commit/?id=796d85f786dff62bd4bcc4408d9b7bbc855841e9]
+
+Certain functions from sftp.c were moved to a new file sftp_common.c
+in version 0.11.0 by following commit:
+https://git.libssh.org/projects/libssh.git/commit/src/sftp_common.c?id=c3e03ab4651e4f3382e3a51c0273ade894f0c48a
+
+This is the backport of the changes which fixes the CVE in the original file
+sftp.c
+
+Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
+---
+ src/sftp.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/src/sftp.c b/src/sftp.c
+index 4a77141b..2194a9ef 100644
+--- a/src/sftp.c
++++ b/src/sftp.c
+@@ -1289,13 +1289,18 @@ static char *sftp_parse_longname(const char *longname,
+     const char *p, *q;
+     size_t len, field = 0;
+ 
++    if (longname == NULL || longname_field < SFTP_LONGNAME_PERM ||
++        longname_field > SFTP_LONGNAME_NAME) {
++        return NULL;
++    }
++
+     p = longname;
+     /* Find the beginning of the field which is specified by sftp_longname_field_e. */
+-    while(field != longname_field) {
++    while (*p != '\0' && field != longname_field) {
+         if(isspace(*p)) {
+             field++;
+             p++;
+-            while(*p && isspace(*p)) {
++            while (*p != '\0' && isspace(*p)) {
+                 p++;
+             }
+         } else {
+@@ -1303,8 +1308,13 @@ static char *sftp_parse_longname(const char *longname,
+         }
+     }
+ 
++    /* If we reached NULL before we got our field fail */
++    if (field != longname_field) {
++        return NULL;
++    }
++
+     q = p;
+-    while (! isspace(*q)) {
++    while (*q != '\0' && !isspace(*q)) {
+         q++;
+     }
+ 
diff --git a/meta-oe/recipes-support/libssh/libssh/CVE-2026-0968-2.patch b/meta-oe/recipes-support/libssh/libssh/CVE-2026-0968-2.patch
new file mode 100644
index 0000000000..42642ee1ed
--- /dev/null
+++ b/meta-oe/recipes-support/libssh/libssh/CVE-2026-0968-2.patch
@@ -0,0 +1,136 @@ 
+From 04cd54c7302195055d208e0ca00d6e519d674bb2 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Mon, 22 Dec 2025 21:00:03 +0100
+Subject: [PATCH] CVE-2026-0968 tests: Reproducer for invalid longname data
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
+(cherry picked from commit 90a5d8f47399e8db61b56793cd21476ff6a528e0)
+(cherry picked from commit 212121971fb26e1e00b72bd5402c0454a4d84c03)
+
+CVE: CVE-2026-0968
+Upstream-Status: Backport [https://git.libssh.org/projects/libssh.git/commit/?id=212121971fb26e1e00b72bd5402c0454a4d84c03]
+
+Certain functions from sftp.c were moved to a new file sftp_common.c
+in version 0.11.0 by following commit:
+https://git.libssh.org/projects/libssh.git/commit/src/sftp_common.c?id=c3e03ab4651e4f3382e3a51c0273ade894f0c48a
+
+Updated unit test to include sftp.c during the backport.
+
+Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
+---
+ tests/unittests/CMakeLists.txt      |  7 +++
+ tests/unittests/torture_unit_sftp.c | 86 +++++++++++++++++++++++++++++
+ 2 files changed, 93 insertions(+)
+ create mode 100644 tests/unittests/torture_unit_sftp.c
+
+diff --git a/tests/unittests/CMakeLists.txt b/tests/unittests/CMakeLists.txt
+index f85da72b..41f25830 100644
+--- a/tests/unittests/CMakeLists.txt
++++ b/tests/unittests/CMakeLists.txt
+@@ -101,6 +101,13 @@ if (UNIX AND NOT WIN32)
+     endif (WITH_SERVER)
+ endif (UNIX AND NOT WIN32)
+ 
++if (WITH_SFTP)
++    set(LIBSSH_UNIT_TESTS
++        ${LIBSSH_UNIT_TESTS}
++        torture_unit_sftp
++    )
++endif (WITH_SFTP)
++
+ foreach(_UNIT_TEST ${LIBSSH_UNIT_TESTS})
+     add_cmocka_test(${_UNIT_TEST}
+                     SOURCES ${_UNIT_TEST}.c
+diff --git a/tests/unittests/torture_unit_sftp.c b/tests/unittests/torture_unit_sftp.c
+new file mode 100644
+index 00000000..8cdaba8e
+--- /dev/null
++++ b/tests/unittests/torture_unit_sftp.c
+@@ -0,0 +1,86 @@
++#include "config.h"
++
++#include "sftp.c"
++#include "torture.h"
++
++#define LIBSSH_STATIC
++
++static void test_sftp_parse_longname(void **state)
++{
++    const char *lname = NULL;
++    char *value = NULL;
++
++    /* state not used */
++    (void)state;
++
++    /* Valid example from SFTP draft, page 18:
++     * https://datatracker.ietf.org/doc/draft-spaghetti-sshm-filexfer/
++     */
++    lname = "-rwxr-xr-x   1 mjos     staff      348911 Mar 25 14:29 t-filexfer";
++    value = sftp_parse_longname(lname, SFTP_LONGNAME_PERM);
++    assert_string_equal(value, "-rwxr-xr-x");
++    free(value);
++    value = sftp_parse_longname(lname, SFTP_LONGNAME_OWNER);
++    assert_string_equal(value, "mjos");
++    free(value);
++    value = sftp_parse_longname(lname, SFTP_LONGNAME_GROUP);
++    assert_string_equal(value, "staff");
++    free(value);
++    value = sftp_parse_longname(lname, SFTP_LONGNAME_SIZE);
++    assert_string_equal(value, "348911");
++    free(value);
++    /* This function is broken further as the date contains space which breaks
++     * the parsing altogether */
++    value = sftp_parse_longname(lname, SFTP_LONGNAME_DATE);
++    assert_string_equal(value, "Mar");
++    free(value);
++    value = sftp_parse_longname(lname, SFTP_LONGNAME_TIME);
++    assert_string_equal(value, "25");
++    free(value);
++    value = sftp_parse_longname(lname, SFTP_LONGNAME_NAME);
++    assert_string_equal(value, "14:29");
++    free(value);
++}
++
++static void test_sftp_parse_longname_invalid(void **state)
++{
++    const char *lname = NULL;
++    char *value = NULL;
++
++    /* state not used */
++    (void)state;
++
++    /* Invalid inputs should not crash
++     */
++    lname = NULL;
++    value = sftp_parse_longname(lname, SFTP_LONGNAME_PERM);
++    assert_null(value);
++    value = sftp_parse_longname(lname, SFTP_LONGNAME_NAME);
++    assert_null(value);
++
++    lname = "";
++    value = sftp_parse_longname(lname, SFTP_LONGNAME_PERM);
++    assert_string_equal(value, "");
++    free(value);
++    value = sftp_parse_longname(lname, SFTP_LONGNAME_NAME);
++    assert_null(value);
++
++    lname = "-rwxr-xr-x   1";
++    value = sftp_parse_longname(lname, SFTP_LONGNAME_PERM);
++    assert_string_equal(value, "-rwxr-xr-x");
++    free(value);
++    value = sftp_parse_longname(lname, SFTP_LONGNAME_NAME);
++    assert_null(value);
++}
++
++int torture_run_tests(void)
++{
++    int rc;
++    const struct CMUnitTest tests[] = {
++        cmocka_unit_test(test_sftp_parse_longname),
++        cmocka_unit_test(test_sftp_parse_longname_invalid),
++    };
++
++    rc = cmocka_run_group_tests(tests, NULL, NULL);
++    return rc;
++}
diff --git a/meta-oe/recipes-support/libssh/libssh_0.10.6.bb b/meta-oe/recipes-support/libssh/libssh_0.10.6.bb
index 30f68f87ce..e0ade7f67c 100644
--- a/meta-oe/recipes-support/libssh/libssh_0.10.6.bb
+++ b/meta-oe/recipes-support/libssh/libssh_0.10.6.bb
@@ -28,6 +28,8 @@  SRC_URI = "git://git.libssh.org/projects/libssh.git;protocol=https;branch=stable
            file://CVE-2026-0966-1.patch \
            file://CVE-2026-0966-2.patch \
            file://CVE-2026-0966-3.patch \
+           file://CVE-2026-0968-1.patch \
+           file://CVE-2026-0968-2.patch \
           "
 SRCREV = "10e09e273f69e149389b3e0e5d44b8c221c2e7f6"