Package: release.debian.org Severity: normal Tags: bookworm 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, but unlike in the trixie case I had to make some edits of my own. %-expansion of usernames was only introduced in OpenSSH 10.0, so that part of the problem isn't relevant to bookworm. I tried to stay as close to the upstream changes as I could, and just dropped the parts that were only relevant to %-expansion. [ 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 ] * Refuse usernames that include control characters. Add corresponding regression tests. * Don't allow \0 characters in URL-encoded strings. Thanks, -- Colin Watson (he/him) [[email protected]]
diff -Nru openssh-9.2p1/debian/.git-dpm openssh-9.2p1/debian/.git-dpm --- openssh-9.2p1/debian/.git-dpm 2025-07-28 12:58:38.000000000 +0100 +++ openssh-9.2p1/debian/.git-dpm 2026-01-08 19:17:36.000000000 +0000 @@ -1,6 +1,6 @@ # see git-dpm(1) from git-dpm package -d69f6291ca7b1d7315a54aa50c1538f97b7b1f8f -d69f6291ca7b1d7315a54aa50c1538f97b7b1f8f +e5402601353303321fb2953e0b7d45f0838b94db +e5402601353303321fb2953e0b7d45f0838b94db cf3c3acb2b8f74eeca7fcee269b1d33ac83f1188 cf3c3acb2b8f74eeca7fcee269b1d33ac83f1188 openssh_9.2p1.orig.tar.gz diff -Nru openssh-9.2p1/debian/changelog openssh-9.2p1/debian/changelog --- openssh-9.2p1/debian/changelog 2025-07-28 12:59:40.000000000 +0100 +++ openssh-9.2p1/debian/changelog 2026-01-08 19:17:36.000000000 +0000 @@ -1,3 +1,12 @@ +openssh (1:9.2p1-2+deb12u8) UNRELEASED; urgency=medium + + * CVE-2025-61984: ssh(1): disallow control characters in usernames passed + via the commandline (closes: #1117529). + * CVE-2025-61985: ssh(1): disallow \0 characters in ssh:// URIs (closes: + #1117530). + + -- Colin Watson <[email protected]> Thu, 08 Jan 2026 19:17:36 +0000 + openssh (1:9.2p1-2+deb12u7) bookworm; urgency=medium * Handle OpenSSL >=3 ABI compatibility; this helps to avoid new ssh diff -Nru openssh-9.2p1/debian/patches/CVE-2025-61984-tests.patch openssh-9.2p1/debian/patches/CVE-2025-61984-tests.patch --- openssh-9.2p1/debian/patches/CVE-2025-61984-tests.patch 1970-01-01 01:00:00.000000000 +0100 +++ openssh-9.2p1/debian/patches/CVE-2025-61984-tests.patch 2026-01-08 19:17:36.000000000 +0000 @@ -0,0 +1,82 @@ +From e5402601353303321fb2953e0b7d45f0838b94db Mon Sep 17 00:00:00 2001 +From: "[email protected]" <[email protected]> +Date: Thu, 4 Sep 2025 03:04:44 +0000 +Subject: Add more username validity checks + +[cjwatson: Reduced from a more extensive upstream change, since OpenSSH +< 10.0 doesn't support %-expansion of usernames.] + +OpenBSD-Regress-ID: ad4c12c70bdf1f959abfebd1637ecff1b49a484c + +Origin: backport, https://anongit.mindrot.org/openssh.git/commit/?id=f64701ca25795548a61614d0b13391d6dfa7f38c +Author: Colin Watson <[email protected]> +Bug-Debian: https://bugs.debian.org/1117530 +Last-Update: 2026-01-09 + +Patch-Name: CVE-2025-61984-tests.patch +--- + regress/percent.sh | 37 +++++++++++++++++++++++++++++++++++-- + 1 file changed, 35 insertions(+), 2 deletions(-) + +diff --git a/regress/percent.sh b/regress/percent.sh +index 3dfa8d2df..6b9c492b0 100644 +--- a/regress/percent.sh ++++ b/regress/percent.sh +@@ -34,6 +34,20 @@ trial() + somehost true + got=`cat $OBJ/actual` + ;; ++ user) ++ got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg" -G \ ++ remuser@somehost | awk '$1=="'$opt'"{print $2}'` ++ ;; ++ user-l) ++ # Also test ssh -l ++ got=`${SSH} -F $OBJ/ssh_proxy -l "$arg" -G \ ++ somehost | awk '$1=="'user'"{print $2}'` ++ ;; ++ user-at) ++ # Also test user@host ++ got=`${SSH} -F $OBJ/ssh_proxy -G "$arg@somehost" | \ ++ awk '$1=="'user'"{print $2}'` ++ ;; + userknownhostsfile) + # Move the userknownhosts file to what the expansion says, + # make sure ssh works then put it back. +@@ -111,11 +125,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 \ + userknownhostsfile; do + verbose $tid $i dollar +- FOO=bar +- export FOO + trial $i '${FOO}' $FOO + done + +@@ -126,3 +140,22 @@ for i in controlpath identityagent forwardagent; do + trial $i '~' $HOME/ + trial $i '~/.ssh' $HOME/.ssh + 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" diff -Nru openssh-9.2p1/debian/patches/CVE-2025-61984.patch openssh-9.2p1/debian/patches/CVE-2025-61984.patch --- openssh-9.2p1/debian/patches/CVE-2025-61984.patch 1970-01-01 01:00:00.000000000 +0100 +++ openssh-9.2p1/debian/patches/CVE-2025-61984.patch 2026-01-08 19:17:36.000000000 +0000 @@ -0,0 +1,108 @@ +From cab036bedba20f6f11a9fd3baab79645a2c30d4c Mon Sep 17 00:00:00 2001 +From: "[email protected]" <[email protected]> +Date: Thu, 4 Sep 2025 00:29:09 +0000 +Subject: Refuse usernames that include control characters + +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; 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 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@ + +[cjwatson: The original upstream change also improved rules for +%-expansion of usernames. However, %-expansion of usernames was only +introduced in OpenSSH 10.0 and so is not relevant to Debian 12 and +earlier.] + +OpenBSD-Commit-ID: e2f0c871fbe664aba30607321575e7c7fc798362 + +Origin: backport, https://anongit.mindrot.org/openssh.git/commit/?id=35d5917652106aede47621bb3f64044604164043 +Author: Colin Watson <[email protected]> +Bug-Debian: https://bugs.debian.org/1117529 +Last-Update: 2026-01-08 + +Patch-Name: CVE-2025-61984.patch +--- + ssh.c | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +diff --git a/ssh.c b/ssh.c +index 422405035..a45da5877 100644 +--- a/ssh.c ++++ b/ssh.c +@@ -646,6 +646,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 */ +@@ -667,6 +669,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; + char *p, *cp, *line, *argv0, *logfile; + char cname[NI_MAXHOST], thishost[NI_MAXHOST]; + struct stat st; +@@ -1008,8 +1011,10 @@ main(int ac, char **av) + } + break; + case 'l': +- if (options.user == NULL) ++ if (options.user == NULL) { + options.user = optarg; ++ user_on_commandline = 1; ++ } + break; + + case 'L': +@@ -1112,6 +1117,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) +@@ -1126,6 +1132,7 @@ main(int ac, char **av) + if (options.user == NULL) { + options.user = p; + p = NULL; ++ user_on_commandline = 1; + } + *cp++ = '\0'; + host = xstrdup(cp); +@@ -1147,8 +1154,6 @@ main(int ac, char **av) + + if (!valid_hostname(host)) + fatal("hostname contains invalid characters"); +- if (options.user != NULL && !valid_ruser(options.user)) +- fatal("remote username contains invalid characters"); + options.host_arg = xstrdup(host); + + /* Initialize the command to execute on remote host. */ +@@ -1428,6 +1433,14 @@ main(int ac, char **av) + cinfo->homedir = xstrdup(pw->pw_dir); + cinfo->locuser = xstrdup(pw->pw_name); + ++ /* ++ * Usernames specified on the commandline must be validated. ++ * Conversely, usernames from getpwnam(3) or specified as literals ++ * via configuration are not subject to validation. ++ */ ++ if (user_on_commandline && !valid_ruser(options.user)) ++ fatal("remote username contains invalid characters"); ++ + /* + * Expand tokens in arguments. NB. LocalCommand is expanded later, + * after port-forwarding is set up, so it may pick up any local diff -Nru openssh-9.2p1/debian/patches/CVE-2025-61985.patch openssh-9.2p1/debian/patches/CVE-2025-61985.patch --- openssh-9.2p1/debian/patches/CVE-2025-61985.patch 1970-01-01 01:00:00.000000000 +0100 +++ openssh-9.2p1/debian/patches/CVE-2025-61985.patch 2026-01-08 19:17:36.000000000 +0000 @@ -0,0 +1,46 @@ +From 48b09ff880d30b95d18273b02601097abeb12b9d 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: backport, 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 | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/misc.c b/misc.c +index 36e72f5b5..a50119446 100644 +--- a/misc.c ++++ b/misc.c +@@ -930,17 +930,21 @@ urldecode(const char *src) + { + char *ret, *dst; + int ch; ++ size_t srclen; + +- ret = xmalloc(strlen(src) + 1); ++ if ((srclen = strlen(src)) >= SIZE_MAX) ++ return NULL; ++ ret = xmalloc(srclen + 1); + for (dst = ret; *src != '\0'; src++) { + switch (*src) { + case '+': + *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-9.2p1/debian/patches/series openssh-9.2p1/debian/patches/series --- openssh-9.2p1/debian/patches/series 2025-07-28 12:58:38.000000000 +0100 +++ openssh-9.2p1/debian/patches/series 2026-01-08 19:17:36.000000000 +0000 @@ -40,3 +40,6 @@ CVE-2025-26465.patch incorrect-return-values.patch fix-disable-forwarding.patch +CVE-2025-61984.patch +CVE-2025-61985.patch +CVE-2025-61984-tests.patch

