Compare commits
1 Commits
| Author | SHA256 | Date | |
|---|---|---|---|
|
|
ee2cb50958 |
126
openssh-cve-2025-61984-username-validation.patch
Normal file
126
openssh-cve-2025-61984-username-validation.patch
Normal file
@@ -0,0 +1,126 @@
|
||||
From 35d5917652106aede47621bb3f64044604164043 Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Thu, 4 Sep 2025 00:29:09 +0000
|
||||
Subject: [PATCH] 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
|
||||
---
|
||||
ssh.c | 33 ++++++++++++++++++++++++++-------
|
||||
1 file changed, 26 insertions(+), 7 deletions(-)
|
||||
|
||||
Index: openssh-10.0p1/ssh.c
|
||||
===================================================================
|
||||
--- openssh-10.0p1.orig/ssh.c
|
||||
+++ openssh-10.0p1/ssh.c
|
||||
@@ -670,6 +670,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 */
|
||||
@@ -691,6 +693,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;
|
||||
@@ -1046,8 +1049,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':
|
||||
@@ -1150,6 +1155,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)
|
||||
@@ -1164,6 +1170,7 @@ main(int ac, char **av)
|
||||
if (options.user == NULL) {
|
||||
options.user = p;
|
||||
p = NULL;
|
||||
+ user_on_commandline = 1;
|
||||
}
|
||||
*cp++ = '\0';
|
||||
host = xstrdup(cp);
|
||||
@@ -1323,8 +1330,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.
|
||||
@@ -1471,20 +1480,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,
|
||||
37
openssh-cve-2025-61985-nul-url-encode.patch
Normal file
37
openssh-cve-2025-61985-nul-url-encode.patch
Normal file
@@ -0,0 +1,37 @@
|
||||
From 43b3bff47bb029f2299bacb6a36057981b39fdb0 Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Thu, 4 Sep 2025 00:30:06 +0000
|
||||
Subject: [PATCH] upstream: don't allow \0 characters in url-encoded strings.
|
||||
|
||||
Suggested by David Leadbeater, ok deraadt@
|
||||
|
||||
OpenBSD-Commit-ID: c92196cef0f970ceabc1e8007a80b01e9b7cd49c
|
||||
---
|
||||
misc.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
Index: openssh-10.0p1/misc.c
|
||||
===================================================================
|
||||
--- openssh-10.0p1.orig/misc.c
|
||||
+++ openssh-10.0p1/misc.c
|
||||
@@ -998,7 +998,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) {
|
||||
@@ -1006,9 +1006,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;
|
||||
}
|
||||
@@ -1,3 +1,11 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Nov 7 20:29:16 UTC 2025 - Hans Petter Jansson <hpj@suse.com>
|
||||
|
||||
- Add openssh-cve-2025-61984-username-validation.patch
|
||||
(bsc#1251198, CVE-2025-61984).
|
||||
- Add openssh-cve-2025-61985-nul-url-encode.patch
|
||||
(bsc#1251199, CVE-2025-61985).
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Apr 22 16:45:33 UTC 2025 - Hans Petter Jansson <hpj@suse.com>
|
||||
|
||||
|
||||
@@ -146,6 +146,8 @@ Patch104: openssh-6.6p1-keycat.patch
|
||||
Patch105: openssh-6.6.1p1-selinux-contexts.patch
|
||||
Patch106: openssh-7.6p1-cleanup-selinux.patch
|
||||
Patch107: openssh-send-extra-term-env.patch
|
||||
Patch108: openssh-cve-2025-61984-username-validation.patch
|
||||
Patch109: openssh-cve-2025-61985-nul-url-encode.patch
|
||||
# 200 - 300 -- Patches submitted to upstream
|
||||
# PATCH-FIX-UPSTREAM -- https://github.com/openssh/openssh-portable/pull/452 boo#1229010
|
||||
Patch200: 0001-auth-pam-Immediately-report-instructions-to-clients-and-fix-handling-in-ssh-client.patch
|
||||
|
||||
Reference in New Issue
Block a user