Hi,

I have fixed CVE-2026-5917 for trixie and forky, and this is the patch for bookworm. I opted to backport the newer git_str_puts_escaped() function so I could use the actual one-line fix instead of reimplementing (and possibly breaking) it.

Cheers
Timo

PS. I am not subscribed to the list, so please Cc me.



--
⢀⣴⠾⠻⢶⣦⠀   ╭────────────────────────────────────────────────────╮
⣾⠁⢠⠒⠀⣿⡁   │ Timo Röhling                                       │
⢿⡄⠘⠷⠚⠋⠀   │ 9B03 EBB9 8300 DF97 C2B1  23BF CC8C 6BDD 1403 F4CA │
⠈⠳⣄⠀⠀⠀⠀   ╰────────────────────────────────────────────────────╯
diff --git a/debian/changelog b/debian/changelog
index 2ee49775a..13b31b6a3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+libgit2 (1.5.1+ds-1+deb12u2) bookworm-security; urgency=high
+
+  * Fix CVE-2026-5917: shell command injection in SSH transport
+    (Closes: #1144465)
+
+ -- Timo Röhling <[email protected]>  Sun, 16 Aug 2026 15:22:42 +0200
+
 libgit2 (1.5.1+ds-1+deb12u1) bookworm-security; urgency=high
 
   * Team upload.
diff --git a/debian/patches/backports/CVE-2026-5917.patch 
b/debian/patches/backports/CVE-2026-5917.patch
new file mode 100644
index 000000000..e548d36e9
--- /dev/null
+++ b/debian/patches/backports/CVE-2026-5917.patch
@@ -0,0 +1,92 @@
+From: =?utf-8?q?Timo_R=C3=B6hling?= <[email protected]>
+Date: Sun, 16 Aug 2026 15:22:23 +0200
+Subject: Fix CVE-2026-5917: shell command injection in SSH transport
+
+Origin: upstream, 
https://github.com/libgit2/libgit2/commit/b2105b8e60798cb28086d4c648b1cb4854eadccb
+---
+ src/libgit2/transports/ssh.c | 65 +++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 64 insertions(+), 1 deletion(-)
+
+diff --git a/src/libgit2/transports/ssh.c b/src/libgit2/transports/ssh.c
+index 85e7797..6ab762c 100644
+--- a/src/libgit2/transports/ssh.c
++++ b/src/libgit2/transports/ssh.c
+@@ -56,6 +56,69 @@ static void ssh_error(LIBSSH2_SESSION *session, const char 
*errmsg)
+       git_error_set(GIT_ERROR_SSH, "%s: %s", errmsg, ssherr);
+ }
+ 
++/* Backported to support not only escape prefix, but also escape suffix */
++static int backported_git_str_puts_escaped(
++      git_str *buf,
++      const char *string,
++      const char *esc_chars,
++      const char *esc_prefix,
++      const char *esc_suffix)
++{
++      const char *scan;
++      size_t total = 0, count, alloclen;
++      size_t esc_prefix_len = esc_prefix ? strlen(esc_prefix) : 0;
++      size_t esc_suffix_len = esc_suffix ? strlen(esc_suffix) : 0;
++
++      if (!string)
++              return 0;
++
++      for (scan = string; *scan; ) {
++              /* count run of non-escaped characters */
++              count = strcspn(scan, esc_chars);
++              total += count;
++              scan += count;
++              /* count run of escaped characters */
++              count = strspn(scan, esc_chars);
++              total += count * (esc_prefix_len + esc_suffix_len + 1);
++              scan += count;
++      }
++
++      GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, total, 1);
++      if (git_str_grow_by(buf, alloclen) < 0)
++              return -1;
++
++      for (scan = string; *scan; ) {
++              count = strcspn(scan, esc_chars);
++
++              memmove(buf->ptr + buf->size, scan, count);
++              scan += count;
++              buf->size += count;
++
++              for (count = strspn(scan, esc_chars); count > 0; --count) {
++                      /* copy escape prefix sequence */
++                      if (esc_prefix) {
++                              memmove(buf->ptr + buf->size, esc_prefix, 
esc_prefix_len);
++                              buf->size += esc_prefix_len;
++                      }
++
++                      /* copy character to be escaped */
++                      buf->ptr[buf->size] = *scan;
++                      buf->size++;
++                      scan++;
++
++                      /* copy escape suffix sequence */
++                      if (esc_suffix) {
++                              memmove(buf->ptr + buf->size, esc_suffix, 
esc_suffix_len);
++                              buf->size += esc_suffix_len;
++                      }
++              }
++      }
++
++      buf->ptr[buf->size] = '\0';
++
++      return 0;
++}
++
+ /*
+  * Create a git protocol request.
+  *
+@@ -77,7 +140,7 @@ static int gen_proto(git_str *request, const char *cmd, 
git_net_url *url)
+ 
+       git_str_puts(request, cmd);
+       git_str_puts(request, " '");
+-      git_str_puts(request, repo);
++      backported_git_str_puts_escaped(request, repo, "'!", "'\\", "'");
+       git_str_puts(request, "'");
+ 
+       if (git_str_oom(request))
diff --git a/debian/patches/series b/debian/patches/series
index bfd5de3ec..72aac1ac1 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -4,3 +4,4 @@ handle-bashism.patch
 disable-flaky-stat-tests.patch
 backports/CVE-2024-24575.patch
 backports/CVE-2024-24577.patch
+backports/CVE-2026-5917.patch

Attachment: signature.asc
Description: PGP signature

Reply via email to