From 4bda3f22da4fbc9c0c65a32cd23f08f992886942 Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Tue, 14 Jul 2026 22:27:29 +0700 Subject: [PATCH] build(ssh): patch libssh2 against CVE-2026-55200 --- CHANGELOG.md | 4 +++ Libs/checksums.sha256 | 8 ++--- scripts/build-libssh2.sh | 20 +++++++++++ scripts/ios/build-libssh2-ios.sh | 7 ++++ scripts/patches/libssh2-cve-2026-55200.patch | 36 ++++++++++++++++++++ 5 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 scripts/patches/libssh2-cve-2026-55200.patch diff --git a/CHANGELOG.md b/CHANGELOG.md index 319617737..96fd0b8e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Cancel now stops a connection attempt right away instead of letting it run on in the background. A cancelled connection is also dropped from the last session, so restarting no longer reconnects to a host you gave up on, and it can no longer interrupt a later successful connection. (#1358) - Fixed a crash when clicking a column header on a table whose columns have comments. Sorting such a table quit the app immediately. (#1869) +### Security + +- Patched CVE-2026-55200 in libssh2, a critical out-of-bounds write that let a malicious SSH server corrupt memory and run code before authentication finished. It affected every SSH tunnel and jump host. + ## [0.57.0] - 2026-07-14 ### Added diff --git a/Libs/checksums.sha256 b/Libs/checksums.sha256 index 16dbd1a20..f9dd53589 100644 --- a/Libs/checksums.sha256 +++ b/Libs/checksums.sha256 @@ -42,10 +42,10 @@ efba529b1ad767de988a58ca2c3fdcc26c38ce79df044a988f41fddbf9fde118 Libs/libpgport b86ecf68d2b0dd8aa7712d13607c9584df2297aca4cd651428e8ee974c6bdf80 Libs/libpq_universal.a 1ce2b45af228915fad05e07f54e96621af7143e199e002e5100777261a7f4a13 Libs/libpq_x86_64.a b86ecf68d2b0dd8aa7712d13607c9584df2297aca4cd651428e8ee974c6bdf80 Libs/libpq.a -166e0e23ce60fd2edcae38b6005de106394f7e2bc922a4944317d6aa576f284c Libs/libssh2_arm64.a -445b51e6fdaa0a0eceb8090e6d552a551ec15d91e4370a4cc356c8f561e8b469 Libs/libssh2_universal.a -76681299c4305273cea62e59cfa366ceb5cc320831b87fd6a06143d342f8b7db Libs/libssh2_x86_64.a -445b51e6fdaa0a0eceb8090e6d552a551ec15d91e4370a4cc356c8f561e8b469 Libs/libssh2.a +6d737d744b5a2494bca0eee9091166d7e15912a3eca5aa0f74644393cc2ce087 Libs/libssh2_arm64.a +c6e3dbcb3d79d740a8bcab355ae10389a39d99e0c8594528202d0eb8c78a5e18 Libs/libssh2_universal.a +bd4dab1e2b24fa695bad8c951d5a2c3271c4c4436f0651f276c09899126fe088 Libs/libssh2_x86_64.a +c6e3dbcb3d79d740a8bcab355ae10389a39d99e0c8594528202d0eb8c78a5e18 Libs/libssh2.a b3861975896ebf35255d8c3efccdc59ad39874c9b70fdd710ebd15f0a58c4e10 Libs/libssl_arm64.a 3ca208dedf57dbae4f5cb0a22bfbedeba80dc6740d626484d9d815811d64a2aa Libs/libssl_universal.a 34de647ccd0951095f987591562a5236348bac2d4b3e217877559a7b170cf4e4 Libs/libssl_x86_64.a diff --git a/scripts/build-libssh2.sh b/scripts/build-libssh2.sh index 2bcca7f0e..c1cb957f7 100755 --- a/scripts/build-libssh2.sh +++ b/scripts/build-libssh2.sh @@ -111,6 +111,24 @@ build_openssl() { echo "✅ OpenSSL $arch: $(ls -lh "$prefix/lib/libssl.a" | awk '{print $5}') (libssl) $(ls -lh "$prefix/lib/libcrypto.a" | awk '{print $5}') (libcrypto)" } +# libssh2 1.11.1 is the newest release and is still vulnerable to CVE-2026-55200 (CVSS 9.2): +# ssh2_transport_read() enforces no upper bound on packet_length, so a malicious server can +# overflow the heap before authentication. Upstream fixed it in 97acf3df with no release cut +# since, so the fix rides as a patch on top of the pinned release tarball. Drop the patch once +# a release contains it. +apply_patches() { + local source_dir=$1 + local patch_dir="$SCRIPT_DIR/patches" + + [ -d "$patch_dir" ] || return 0 + + for patch in "$patch_dir"/*.patch; do + [ -e "$patch" ] || continue + echo "🩹 Applying $(basename "$patch")" + patch -p1 -d "$source_dir" -i "$patch" + done +} + build_libssh2() { local arch=$1 local openssl_prefix="$BUILD_DIR/install-openssl-$arch" @@ -124,6 +142,8 @@ build_libssh2() { mkdir -p "$BUILD_DIR/libssh2-$LIBSSH2_VERSION-$arch" tar xzf "$BUILD_DIR/libssh2-$LIBSSH2_VERSION.tar.gz" -C "$BUILD_DIR/libssh2-$LIBSSH2_VERSION-$arch" --strip-components=1 + apply_patches "$BUILD_DIR/libssh2-$LIBSSH2_VERSION-$arch" + local build_dir="$BUILD_DIR/libssh2-$LIBSSH2_VERSION-$arch/cmake-build" mkdir -p "$build_dir" cd "$build_dir" diff --git a/scripts/ios/build-libssh2-ios.sh b/scripts/ios/build-libssh2-ios.sh index f8d936be7..f63d9eb4d 100755 --- a/scripts/ios/build-libssh2-ios.sh +++ b/scripts/ios/build-libssh2-ios.sh @@ -68,6 +68,13 @@ curl -fSL "https://github.com/libssh2/libssh2/releases/download/libssh2-$LIBSSH2 echo "$LIBSSH2_SHA256 $BUILD_DIR/libssh2.tar.gz" | shasum -a 256 -c - > /dev/null tar xzf "$BUILD_DIR/libssh2.tar.gz" -C "$BUILD_DIR" LIBSSH2_SRC="$BUILD_DIR/libssh2-$LIBSSH2_VERSION" + +for patch in "$SCRIPT_DIR/../patches"/*.patch; do + [ -e "$patch" ] || continue + echo "=> Applying $(basename "$patch")" + patch -p1 -d "$LIBSSH2_SRC" -i "$patch" +done + echo " Done." # --- Build function --- diff --git a/scripts/patches/libssh2-cve-2026-55200.patch b/scripts/patches/libssh2-cve-2026-55200.patch new file mode 100644 index 000000000..7feb12868 --- /dev/null +++ b/scripts/patches/libssh2-cve-2026-55200.patch @@ -0,0 +1,36 @@ +CVE-2026-55200: out-of-bounds write in ssh2_transport_read() + +libssh2 through 1.11.1 enforces no upper bound on the packet_length field when the cipher +requires a full packet (the encrypted + REQUIRES_FULL_PACKET branch). A malicious server can +send a crafted packet length, corrupt the heap before authentication completes, and reach +remote code execution. CVSS 4.0 base score 9.2. + +The sibling branch already carries this bound check; only this path was missed. + +Backported from upstream 97acf3dfda80c91c3a8c9f2372546301d4a1a7a8 ("transport.c: Additional +boundary checks for packet length", libssh2/libssh2#2052). The upstream commit does not apply +as-is: master renamed _libssh2_ntohu32() to ssh2_ntohu32() after 1.11.1 was cut. The guard +itself is unchanged. + +1.11.1 is the newest release and no release carries the fix yet. Delete this patch and bump +LIBSSH2_VERSION once one does. + +https://nvd.nist.gov/vuln/detail/CVE-2026-55200 +https://github.com/libssh2/libssh2/pull/2052 + +--- a/src/transport.c ++++ b/src/transport.c +@@ -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