Your message dated Sat, 14 Mar 2026 11:48:35 +0000
with message-id <[email protected]>
and subject line Released with 13.4
has caused the Debian Bug report #1125139,
regarding trixie-pu: package openssh/1:10.0p1-7+deb13u1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
1125139: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1125139
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:openssh
User: [email protected]
Usertags: pu

[ Reason ]
The security team asked me to fix CVE-2025-61984 and CVE-2025-61985 in 
the next available point release.

[ Impact ]
Control characters in usernames from some untrusted sources can result 
in code execution when a ProxyCommand is used.

[ Tests ]
I've included backports of upstream's regression tests for these cases.

[ Risks ]
I think the changes are all fairly readable and straightforward.  For 
trixie, they were all simple cherry-picks.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[ Changes ]
* Improve rules for %-expansion of username: usernames passed on the 
  command line will no longer be subject to %-expansion.  Add 
  corresponding regression tests.
* Don't allow \0 characters in URL-encoded strings.

Thanks,

-- 
Colin Watson (he/him)                              [[email protected]]
diff -Nru openssh-10.0p1/debian/.git-dpm openssh-10.0p1/debian/.git-dpm
--- openssh-10.0p1/debian/.git-dpm      2025-08-01 16:02:27.000000000 +0100
+++ openssh-10.0p1/debian/.git-dpm      2026-01-08 17:39:42.000000000 +0000
@@ -1,6 +1,6 @@
 # see git-dpm(1) from git-dpm package
-f5c89caec93130da905a95602cf36a4e25f2303e
-f5c89caec93130da905a95602cf36a4e25f2303e
+4aa3f8603893eba6937b6ea2addc85bbf5f8f737
+4aa3f8603893eba6937b6ea2addc85bbf5f8f737
 860fa104f07024318a40065f07708daa5753f55d
 860fa104f07024318a40065f07708daa5753f55d
 openssh_10.0p1.orig.tar.gz
diff -Nru openssh-10.0p1/debian/changelog openssh-10.0p1/debian/changelog
--- openssh-10.0p1/debian/changelog     2025-08-01 16:02:27.000000000 +0100
+++ openssh-10.0p1/debian/changelog     2026-01-08 17:39:42.000000000 +0000
@@ -1,3 +1,13 @@
+openssh (1:10.0p1-7+deb13u1) UNRELEASED; urgency=medium
+
+  * CVE-2025-61984: ssh(1): disallow control characters in usernames passed
+    via the commandline or expanded using %-sequences from the configuration
+    file (closes: #1117529).
+  * CVE-2025-61985: ssh(1): disallow \0 characters in ssh:// URIs (closes:
+    #1117530).
+
+ -- Colin Watson <[email protected]>  Thu, 08 Jan 2026 17:39:42 +0000
+
 openssh (1:10.0p1-7) unstable; urgency=medium
 
   * Make postinst logic for cleaning up the sshd diversion more robust.
diff -Nru openssh-10.0p1/debian/patches/CVE-2025-61984-tests.patch 
openssh-10.0p1/debian/patches/CVE-2025-61984-tests.patch
--- openssh-10.0p1/debian/patches/CVE-2025-61984-tests.patch    1970-01-01 
01:00:00.000000000 +0100
+++ openssh-10.0p1/debian/patches/CVE-2025-61984-tests.patch    2026-01-08 
17:39:42.000000000 +0000
@@ -0,0 +1,106 @@
+From 4aa3f8603893eba6937b6ea2addc85bbf5f8f737 Mon Sep 17 00:00:00 2001
+From: "[email protected]" <[email protected]>
+Date: Thu, 4 Sep 2025 03:04:44 +0000
+Subject: upstream: repair test after changes to percent expansion of usernames
+
+on the commandline.
+
+Test more cases that should/shouldn't expand and lightly test
+username validity checks.
+
+OpenBSD-Regress-ID: ad4c12c70bdf1f959abfebd1637ecff1b49a484c
+
+Origin: 
https://anongit.mindrot.org/openssh.git/commit/?id=f64701ca25795548a61614d0b13391d6dfa7f38c
+Bug-Debian: https://bugs.debian.org/1117530
+Last-Update: 2026-01-08
+
+Patch-Name: CVE-2025-61984-tests.patch
+---
+ regress/percent.sh | 45 +++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 37 insertions(+), 8 deletions(-)
+
+diff --git a/regress/percent.sh b/regress/percent.sh
+index 7ce9e8a1d..c607c8d23 100644
+--- a/regress/percent.sh
++++ b/regress/percent.sh
+@@ -1,4 +1,4 @@
+-#     $OpenBSD: percent.sh,v 1.21 2025/04/08 23:10:46 djm Exp $
++#     $OpenBSD: percent.sh,v 1.22 2025/09/04 03:04:44 djm Exp $
+ #     Placed in the Public Domain.
+ 
+ tid="percent expansions"
+@@ -33,14 +33,14 @@ trial()
+               if [ "$arg" = '%r' ] || [ "$arg" = '%C' ]; then
+                       # User does not support %r, ie itself or %C.  Skip test.
+                       got="$expect"
+-              elif [ "$i" = "user" ]; then
++              elif [ "$opt" = "user" ]; then
+                       got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg" -G \
+                           remuser@somehost | awk '$1=="'$opt'"{print $2}'`
+-              elif [ "$i" = "user-l" ]; then
++              elif [ "$opt" = "user-l" ]; then
+                       # Also test ssh -l
+                       got=`${SSH} -F $OBJ/ssh_proxy -l "$arg" -G \
+                           somehost | awk '$1=="'user'"{print $2}'`
+-              elif [ "$i" = "user-at" ]; then
++              elif [ "$opt" = "user-at" ]; then
+                       # Also test user@host
+                       got=`${SSH} -F $OBJ/ssh_proxy -G "$arg@somehost" | \
+                           awk '$1=="'user'"{print $2}'`
+@@ -91,7 +91,7 @@ trial()
+ 
+ for i in matchexec localcommand remotecommand controlpath identityagent \
+     forwardagent localforward remoteforward revokedhostkeys \
+-    user user-l user-at setenv userknownhostsfile; do
++    user setenv userknownhostsfile; do
+       verbose $tid $i percent
+       case "$i" in
+       localcommand|userknownhostsfile)
+@@ -137,11 +137,11 @@ done
+ 
+ # Subset of above since we don't expand shell-style variables on anything that
+ # runs a command because the shell will expand those.
++FOO=bar
++export FOO
+ for i in controlpath identityagent forwardagent localforward remoteforward \
+-    user user-l user-at setenv userknownhostsfile; do
++    user setenv userknownhostsfile; do
+       verbose $tid $i dollar
+-      FOO=bar
+-      export FOO
+       trial $i '${FOO}' $FOO
+ done
+ 
+@@ -152,3 +152,32 @@ for i in controlpath identityagent forwardagent; do
+       trial $i '~' $HOME/
+       trial $i '~/.ssh' $HOME/.ssh
+ done
++
++for i in user-l user-at; do
++      verbose $tid $i noexpand
++      trial $i '%u' '%u'
++done
++
++# These should be not be expanded but rejected for containing shell 
characters.
++verbose $tid user-l noenv
++${SSH} -F $OBJ/ssh_proxy -l '${FOO}' -G somehost && fail "user-l expanded env"
++verbose $tid user-at noenv
++${SSH} -F $OBJ/ssh_proxy -G '${FOO}@somehost' && fail "user-at expanded env"
++
++FOO=`printf 'x\ay'`
++export FOO
++
++# These should be rejected as containing control characters.
++verbose $tid user-l badchar
++${SSH} -F $OBJ/ssh_proxy -l "${FOO}" -G somehost && fail "user-l expanded env"
++verbose $tid user-at badchar
++${SSH} -F $OBJ/ssh_proxy -G "${FOO}@somehost" && fail "user-at expanded env"
++
++# Literal control characters in config is acceptable
++verbose $tid user control-literal
++trial user "$FOO" "$FOO"
++
++# Control characters expanded from config aren't.
++${SSH} -F $OBJ/ssh_proxy -G '-oUser=${FOO}' somehost && \
++    fail "user expanded ctrl"
++
diff -Nru openssh-10.0p1/debian/patches/CVE-2025-61984.patch 
openssh-10.0p1/debian/patches/CVE-2025-61984.patch
--- openssh-10.0p1/debian/patches/CVE-2025-61984.patch  1970-01-01 
01:00:00.000000000 +0100
+++ openssh-10.0p1/debian/patches/CVE-2025-61984.patch  2026-01-08 
17:39:42.000000000 +0000
@@ -0,0 +1,132 @@
+From 7e076cb419a27153e81243b339ce2efbc3c1f6f3 Mon Sep 17 00:00:00 2001
+From: "[email protected]" <[email protected]>
+Date: Thu, 4 Sep 2025 00:29:09 +0000
+Subject: upstream: Improve rules for %-expansion of username.
+
+Usernames passed on the commandline will no longer be subject to
+% expansion. Some tools invoke ssh with connection information
+(i.e. usernames and host names) supplied from untrusted sources.
+These may contain % expansion sequences which could yield
+unexpected results.
+
+Since openssh-9.6, all usernames have been subject to validity
+checking. This change tightens the validity checks by refusing
+usernames that include control characters (again, these can cause
+surprises when supplied adversarially).
+
+This change also relaxes the validity checks in one small way:
+usernames supplied via the configuration file as literals (i.e.
+include no % expansion characters) are not subject to these
+validity checks. This allows usernames that contain arbitrary
+characters to be used, but only via configuration files. This
+is done on the basis that ssh's configuration is trusted.
+
+Pointed out by David Leadbeater, ok deraadt@
+
+OpenBSD-Commit-ID: e2f0c871fbe664aba30607321575e7c7fc798362
+
+Origin: upstream, 
https://anongit.mindrot.org/openssh.git/commit/?id=35d5917652106aede47621bb3f64044604164043
+Bug-Debian: https://bugs.debian.org/1117529
+Last-Update: 2026-01-08
+
+Patch-Name: CVE-2025-61984.patch
+---
+ ssh.c | 31 +++++++++++++++++++++++++------
+ 1 file changed, 25 insertions(+), 6 deletions(-)
+
+diff --git a/ssh.c b/ssh.c
+index 55463e5ad..9a8267869 100644
+--- a/ssh.c
++++ b/ssh.c
+@@ -654,6 +654,8 @@ valid_ruser(const char *s)
+       if (*s == '-')
+               return 0;
+       for (i = 0; s[i] != 0; i++) {
++              if (iscntrl((u_char)s[i]))
++                      return 0;
+               if (strchr("'`\";&<>|(){}", s[i]) != NULL)
+                       return 0;
+               /* Disallow '-' after whitespace */
+@@ -675,6 +677,7 @@ main(int ac, char **av)
+       struct ssh *ssh = NULL;
+       int i, r, opt, exit_status, use_syslog, direct, timeout_ms;
+       int was_addr, config_test = 0, opt_terminated = 0, want_final_pass = 0;
++      int user_on_commandline = 0, user_was_default = 0, user_expanded = 0;
+       char *p, *cp, *line, *argv0, *logfile, *args;
+       char cname[NI_MAXHOST], thishost[NI_MAXHOST];
+       struct stat st;
+@@ -1026,8 +1029,10 @@ main(int ac, char **av)
+                       }
+                       break;
+               case 'l':
+-                      if (options.user == NULL)
++                      if (options.user == NULL) {
+                               options.user = xstrdup(optarg);
++                              user_on_commandline = 1;
++                      }
+                       break;
+ 
+               case 'L':
+@@ -1130,6 +1135,7 @@ main(int ac, char **av)
+                       if (options.user == NULL) {
+                               options.user = tuser;
+                               tuser = NULL;
++                              user_on_commandline = 1;
+                       }
+                       free(tuser);
+                       if (options.port == -1 && tport != -1)
+@@ -1144,6 +1150,7 @@ main(int ac, char **av)
+                               if (options.user == NULL) {
+                                       options.user = p;
+                                       p = NULL;
++                                      user_on_commandline = 1;
+                               }
+                               *cp++ = '\0';
+                               host = xstrdup(cp);
+@@ -1303,8 +1310,10 @@ main(int ac, char **av)
+       if (fill_default_options(&options) != 0)
+               cleanup_exit(255);
+ 
+-      if (options.user == NULL)
++      if (options.user == NULL) {
++              user_was_default = 1;
+               options.user = xstrdup(pw->pw_name);
++      }
+ 
+       /*
+        * If ProxyJump option specified, then construct a ProxyCommand now.
+@@ -1451,20 +1460,30 @@ main(int ac, char **av)
+           "" : options.jump_host);
+ 
+       /*
+-       * Expand User. It cannot contain %r (itself) or %C since User is
++       * If the user was specified via a configuration directive then attempt
++       * to expand it. It cannot contain %r (itself) or %C since User is
+        * a component of the hash.
+        */
+-      if (options.user != NULL) {
++      if (!user_on_commandline && !user_was_default) {
+               if ((p = percent_dollar_expand(options.user,
+                   DEFAULT_CLIENT_PERCENT_EXPAND_ARGS_NOUSER(cinfo),
+                   (char *)NULL)) == NULL)
+                       fatal("invalid environment variable expansion");
++              user_expanded = strcmp(p, options.user) != 0;
+               free(options.user);
+               options.user = p;
+-              if (!valid_ruser(options.user))
+-                      fatal("remote username contains invalid characters");
+       }
+ 
++      /*
++       * Usernames specified on the commandline or expanded from the
++       * configuration file must be validated.
++       * Conversely, usernames from getpwnam(3) or specified as literals
++       * via configuration (i.e. not expanded) are not subject to validation.
++       */
++      if ((user_on_commandline || user_expanded) &&
++          !valid_ruser(options.user))
++              fatal("remote username contains invalid characters");
++
+       /* Now User is expanded, store it and calculate hash. */
+       cinfo->remuser = xstrdup(options.user);
+       cinfo->conn_hash_hex = ssh_connection_hash(cinfo->thishost,
diff -Nru openssh-10.0p1/debian/patches/CVE-2025-61985.patch 
openssh-10.0p1/debian/patches/CVE-2025-61985.patch
--- openssh-10.0p1/debian/patches/CVE-2025-61985.patch  1970-01-01 
01:00:00.000000000 +0100
+++ openssh-10.0p1/debian/patches/CVE-2025-61985.patch  2026-01-08 
17:39:42.000000000 +0000
@@ -0,0 +1,43 @@
+From 0bd8630712ee27da7aebfec79c96239657ae9369 Mon Sep 17 00:00:00 2001
+From: "[email protected]" <[email protected]>
+Date: Thu, 4 Sep 2025 00:30:06 +0000
+Subject: upstream: don't allow \0 characters in url-encoded strings.
+
+Suggested by David Leadbeater, ok deraadt@
+
+OpenBSD-Commit-ID: c92196cef0f970ceabc1e8007a80b01e9b7cd49c
+
+Origin: upstream, 
https://anongit.mindrot.org/openssh.git/commit/?id=43b3bff47bb029f2299bacb6a36057981b39fdb0
+Bug-Debian: https://bugs.debian.org/1117530
+Last-Update: 2026-01-08
+
+Patch-Name: CVE-2025-61985.patch
+---
+ misc.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/misc.c b/misc.c
+index 081d07993..3b02281bb 100644
+--- a/misc.c
++++ b/misc.c
+@@ -990,7 +990,7 @@ urldecode(const char *src)
+       size_t srclen;
+ 
+       if ((srclen = strlen(src)) >= SIZE_MAX)
+-              fatal_f("input too large");
++              return NULL;
+       ret = xmalloc(srclen + 1);
+       for (dst = ret; *src != '\0'; src++) {
+               switch (*src) {
+@@ -998,9 +998,10 @@ urldecode(const char *src)
+                       *dst++ = ' ';
+                       break;
+               case '%':
++                      /* note: don't allow \0 characters */
+                       if (!isxdigit((unsigned char)src[1]) ||
+                           !isxdigit((unsigned char)src[2]) ||
+-                          (ch = hexchar(src + 1)) == -1) {
++                          (ch = hexchar(src + 1)) == -1 || ch == 0) {
+                               free(ret);
+                               return NULL;
+                       }
diff -Nru openssh-10.0p1/debian/patches/series 
openssh-10.0p1/debian/patches/series
--- openssh-10.0p1/debian/patches/series        2025-08-01 16:02:27.000000000 
+0100
+++ openssh-10.0p1/debian/patches/series        2026-01-08 17:39:42.000000000 
+0000
@@ -26,3 +26,6 @@
 regress-conch-dev-zero.patch
 configure-cache-vars.patch
 pam-avoid-unknown-host.patch
+CVE-2025-61984.patch
+CVE-2025-61985.patch
+CVE-2025-61984-tests.patch

--- End Message ---
--- Begin Message ---
Package: release.debian.org
Version: 13.4

This update has been released as part of Debian 13.4.

--- End Message ---

Reply via email to