mirror of
https://git.yoctoproject.org/poky
synced 2026-08-30 00:26:36 +00:00
openssh: Fix CVE-2026-60002
This patch applies the upstream OpenSSH 10.4 backport for CVE-2026-60002. The upstream fix commit is referenced in [1], and the public CVE advisory is referenced in [2]. [1] https://github.com/openssh/openssh-portable/commit/e8bdfb151a356d0171fea4194dd205fbb252be23 [2] https://nvd.nist.gov/vuln/detail/CVE-2026-60002 (From OE-Core rev: c46f65e3f938efa983b24c53206972972d51da24) Signed-off-by: Devansh Patel <devanshp@cisco.com> Signed-off-by: Yoann Congal <yoann.congal@smile.fr> Signed-off-by: Paul Barker <paul@pbarker.dev>
This commit is contained in:
committed by
Paul Barker
parent
b2a7dabed0
commit
cb5e6f65a5
@@ -0,0 +1,226 @@
|
||||
From 767104acedd68c317b9d8fb603561e1a8be9e76a Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Mon, 6 Jul 2026 07:49:58 +0000
|
||||
Subject: [PATCH] upstream: fix ownership and lifetime of several bits of
|
||||
client
|
||||
|
||||
state that need to persist for the life of the connection, especially the
|
||||
cached hostkey that was being incorrectly freed early on some paths, possibly
|
||||
allowing its use after free.
|
||||
|
||||
Reported by Zhenpeng (Leo) Lin from depthfirst.com
|
||||
|
||||
CVE: CVE-2026-60002
|
||||
Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/e8bdfb151a356d0171fea4194dd205fbb252be23]
|
||||
|
||||
Backport Changes:
|
||||
- Retained Scarthgap's valid_hostname() and valid_ruser() helpers when
|
||||
relocating ssh_conn_info_free() from ssh.c to sshconnect.c.
|
||||
- Retained Scarthgap's ext-info-c proposal handling while applying the
|
||||
upstream connection-state ownership and lifetime changes.
|
||||
- Retained the Scarthgap OpenBSD revision identifiers in ssh.c,
|
||||
sshconnect.c, sshconnect.h, and sshconnect2.c.
|
||||
|
||||
OpenBSD-Commit-ID: faaa6ad72e7d69d41fa8b197b606265b7d9bc73f
|
||||
(cherry picked from commit e8bdfb151a356d0171fea4194dd205fbb252be23)
|
||||
Signed-off-by: Devansh Patel <devanshp@cisco.com>
|
||||
---
|
||||
ssh.c | 24 ++----------------------
|
||||
sshconnect.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
|
||||
sshconnect.h | 7 +++++--
|
||||
sshconnect2.c | 20 +++++++++++---------
|
||||
4 files changed, 63 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/ssh.c b/ssh.c
|
||||
index 9c49f98a8..aecdb79ea 100644
|
||||
--- a/ssh.c
|
||||
+++ b/ssh.c
|
||||
@@ -606,26 +606,6 @@ set_addrinfo_port(struct addrinfo *addrs, int port)
|
||||
}
|
||||
}
|
||||
|
||||
-static void
|
||||
-ssh_conn_info_free(struct ssh_conn_info *cinfo)
|
||||
-{
|
||||
- if (cinfo == NULL)
|
||||
- return;
|
||||
- free(cinfo->conn_hash_hex);
|
||||
- free(cinfo->shorthost);
|
||||
- free(cinfo->uidstr);
|
||||
- free(cinfo->keyalias);
|
||||
- free(cinfo->thishost);
|
||||
- free(cinfo->host_arg);
|
||||
- free(cinfo->portstr);
|
||||
- free(cinfo->remhost);
|
||||
- free(cinfo->remuser);
|
||||
- free(cinfo->homedir);
|
||||
- free(cinfo->locuser);
|
||||
- free(cinfo->jmphost);
|
||||
- free(cinfo);
|
||||
-}
|
||||
-
|
||||
static int
|
||||
valid_hostname(const char *s)
|
||||
{
|
||||
@@ -1771,8 +1751,8 @@ main(int ac, char **av)
|
||||
ssh_signal(SIGCHLD, main_sigchld_handler);
|
||||
|
||||
/* Log into the remote system. Never returns if the login fails. */
|
||||
- ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr,
|
||||
- options.port, pw, timeout_ms, cinfo);
|
||||
+ ssh_login(ssh, &sensitive_data, host, &hostaddr, options.port,
|
||||
+ pw, timeout_ms, cinfo);
|
||||
|
||||
/* We no longer need the private host keys. Clear them now. */
|
||||
if (sensitive_data.nkeys != 0) {
|
||||
diff --git a/sshconnect.c b/sshconnect.c
|
||||
index bd077c75c..7823b6782 100644
|
||||
--- a/sshconnect.c
|
||||
+++ b/sshconnect.c
|
||||
@@ -83,6 +83,49 @@ extern char *__progname;
|
||||
static int show_other_keys(struct hostkeys *, struct sshkey *);
|
||||
static void warn_changed_key(struct sshkey *);
|
||||
|
||||
+void
|
||||
+ssh_conn_info_free(struct ssh_conn_info *cinfo)
|
||||
+{
|
||||
+ if (cinfo == NULL)
|
||||
+ return;
|
||||
+ free(cinfo->conn_hash_hex);
|
||||
+ free(cinfo->shorthost);
|
||||
+ free(cinfo->uidstr);
|
||||
+ free(cinfo->keyalias);
|
||||
+ free(cinfo->thishost);
|
||||
+ free(cinfo->host_arg);
|
||||
+ free(cinfo->portstr);
|
||||
+ free(cinfo->remhost);
|
||||
+ free(cinfo->remuser);
|
||||
+ free(cinfo->homedir);
|
||||
+ free(cinfo->locuser);
|
||||
+ free(cinfo->jmphost);
|
||||
+ freezero(cinfo, sizeof(*cinfo));
|
||||
+}
|
||||
+
|
||||
+struct ssh_conn_info *
|
||||
+ssh_conn_info_dup(const struct ssh_conn_info *cinfo)
|
||||
+{
|
||||
+ struct ssh_conn_info *ret;
|
||||
+
|
||||
+ if (cinfo == NULL)
|
||||
+ return NULL;
|
||||
+ ret = xcalloc(1, sizeof(*ret));
|
||||
+ ret->conn_hash_hex = xstrdup(cinfo->conn_hash_hex);
|
||||
+ ret->shorthost = xstrdup(cinfo->shorthost);
|
||||
+ ret->uidstr = xstrdup(cinfo->uidstr);
|
||||
+ ret->keyalias = xstrdup(cinfo->keyalias);
|
||||
+ ret->thishost = xstrdup(cinfo->thishost);
|
||||
+ ret->host_arg = xstrdup(cinfo->host_arg);
|
||||
+ ret->portstr = xstrdup(cinfo->portstr);
|
||||
+ ret->remhost = xstrdup(cinfo->remhost);
|
||||
+ ret->remuser = xstrdup(cinfo->remuser);
|
||||
+ ret->homedir = xstrdup(cinfo->homedir);
|
||||
+ ret->locuser = xstrdup(cinfo->locuser);
|
||||
+ ret->jmphost = xstrdup(cinfo->jmphost);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/* Expand a proxy command */
|
||||
static char *
|
||||
expand_proxy_command(const char *proxy_command, const char *user,
|
||||
@@ -1559,8 +1602,8 @@ out:
|
||||
*/
|
||||
void
|
||||
ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost,
|
||||
- struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms,
|
||||
- const struct ssh_conn_info *cinfo)
|
||||
+ struct sockaddr_storage *hostaddr, u_short port, struct passwd *pw,
|
||||
+ int timeout_ms, const struct ssh_conn_info *cinfo)
|
||||
{
|
||||
char *host;
|
||||
char *server_user, *local_user;
|
||||
diff --git a/sshconnect.h b/sshconnect.h
|
||||
index 79d35cc19..da2a73f5a 100644
|
||||
--- a/sshconnect.h
|
||||
+++ b/sshconnect.h
|
||||
@@ -71,7 +71,7 @@ int ssh_connect(struct ssh *, const char *, const char *,
|
||||
void ssh_kill_proxy_command(void);
|
||||
|
||||
void ssh_login(struct ssh *, Sensitive *, const char *,
|
||||
- struct sockaddr *, u_short, struct passwd *, int,
|
||||
+ struct sockaddr_storage *, u_short, struct passwd *, int,
|
||||
const struct ssh_conn_info *);
|
||||
|
||||
int verify_host_key(char *, struct sockaddr *, struct sshkey *,
|
||||
@@ -80,7 +80,7 @@ int verify_host_key(char *, struct sockaddr *, struct sshkey *,
|
||||
void get_hostfile_hostname_ipaddr(char *, struct sockaddr *, u_short,
|
||||
char **, char **);
|
||||
|
||||
-void ssh_kex2(struct ssh *ssh, char *, struct sockaddr *, u_short,
|
||||
+void ssh_kex2(struct ssh *ssh, char *, struct sockaddr_storage *, u_short,
|
||||
const struct ssh_conn_info *);
|
||||
|
||||
void ssh_userauth2(struct ssh *ssh, const char *, const char *,
|
||||
@@ -94,3 +94,6 @@ void maybe_add_key_to_agent(const char *, struct sshkey *,
|
||||
void load_hostkeys_command(struct hostkeys *, const char *,
|
||||
const char *, const struct ssh_conn_info *,
|
||||
const struct sshkey *, const char *);
|
||||
+
|
||||
+void ssh_conn_info_free(struct ssh_conn_info *);
|
||||
+struct ssh_conn_info *ssh_conn_info_dup(const struct ssh_conn_info *);
|
||||
diff --git a/sshconnect2.c b/sshconnect2.c
|
||||
index a296c9b8c..9efb3da8a 100644
|
||||
--- a/sshconnect2.c
|
||||
+++ b/sshconnect2.c
|
||||
@@ -89,7 +89,7 @@ extern Options options;
|
||||
*/
|
||||
|
||||
static char *xxx_host;
|
||||
-static struct sockaddr *xxx_hostaddr;
|
||||
+static struct sockaddr_storage xxx_hostaddr;
|
||||
static const struct ssh_conn_info *xxx_conn_info;
|
||||
static int key_type_allowed(struct sshkey *, const char *);
|
||||
|
||||
@@ -105,7 +105,7 @@ verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh)
|
||||
fatal("Server host key %s not in HostKeyAlgorithms",
|
||||
sshkey_ssh_name(hostkey));
|
||||
}
|
||||
- if (verify_host_key(xxx_host, xxx_hostaddr, hostkey,
|
||||
+ if (verify_host_key(xxx_host, (struct sockaddr *)&xxx_hostaddr, hostkey,
|
||||
xxx_conn_info) != 0)
|
||||
fatal("Host key verification failed.");
|
||||
return 0;
|
||||
@@ -222,16 +222,16 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port,
|
||||
}
|
||||
|
||||
void
|
||||
-ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
|
||||
- const struct ssh_conn_info *cinfo)
|
||||
+ssh_kex2(struct ssh *ssh, char *host, struct sockaddr_storage *hostaddr,
|
||||
+ u_short port, const struct ssh_conn_info *cinfo)
|
||||
{
|
||||
char *myproposal[PROPOSAL_MAX];
|
||||
char *s, *all_key, *hkalgs = NULL;
|
||||
int r, use_known_hosts_order = 0;
|
||||
|
||||
- xxx_host = host;
|
||||
- xxx_hostaddr = hostaddr;
|
||||
- xxx_conn_info = cinfo;
|
||||
+ xxx_host = xstrdup(host);
|
||||
+ xxx_hostaddr = *hostaddr;
|
||||
+ xxx_conn_info = ssh_conn_info_dup(cinfo);
|
||||
|
||||
if (options.rekey_limit || options.rekey_interval)
|
||||
ssh_packet_set_rekey_limits(ssh, options.rekey_limit,
|
||||
@@ -257,8 +257,10 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
|
||||
if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL)
|
||||
fatal_f("kex_names_cat");
|
||||
|
||||
- if (use_known_hosts_order)
|
||||
- hkalgs = order_hostkeyalgs(host, hostaddr, port, cinfo);
|
||||
+ if (use_known_hosts_order) {
|
||||
+ hkalgs = order_hostkeyalgs(host, (struct sockaddr *)hostaddr,
|
||||
+ port, cinfo);
|
||||
+ }
|
||||
|
||||
kex_proposal_populate_entries(ssh, myproposal, s, options.ciphers,
|
||||
options.macs, compression_alg_list(options.compression),
|
||||
@@ -42,6 +42,7 @@ SRC_URI = "http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-${PV}.tar
|
||||
file://CVE-2026-59996.patch \
|
||||
file://CVE-2026-59995.patch \
|
||||
file://CVE-2026-60001.patch \
|
||||
file://CVE-2026-60002.patch \
|
||||
"
|
||||
SRC_URI[sha256sum] = "910211c07255a8c5ad654391b40ee59800710dd8119dd5362de09385aa7a777c"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user