From: Devansh Patel <[email protected]>

This patch applies the upstream OpenSSH 10.4p1 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://www.cve.org/CVERecord?id=CVE-2026-60002

Signed-off-by: Devansh Patel <[email protected]>
[YC: Patch referenced in https://ubuntu.com/security/CVE-2026-60002]
Signed-off-by: Yoann Congal <[email protected]>
---
 .../openssh/openssh/CVE-2026-60002.patch      | 225 ++++++++++++++++++
 .../openssh/openssh_10.3p1.bb                 |   1 +
 2 files changed, 226 insertions(+)
 create mode 100644 
meta/recipes-connectivity/openssh/openssh/CVE-2026-60002.patch

diff --git a/meta/recipes-connectivity/openssh/openssh/CVE-2026-60002.patch 
b/meta/recipes-connectivity/openssh/openssh/CVE-2026-60002.patch
new file mode 100644
index 00000000000..85937279a20
--- /dev/null
+++ b/meta/recipes-connectivity/openssh/openssh/CVE-2026-60002.patch
@@ -0,0 +1,225 @@
+From b571549bc93e95f0d3d563094f825544228501de Mon Sep 17 00:00:00 2001
+From: "[email protected]" <[email protected]>
+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
+
+OpenBSD-Commit-ID: faaa6ad72e7d69d41fa8b197b606265b7d9bc73f
+
+CVE: CVE-2026-60002
+Upstream-Status: Backport 
[https://github.com/openssh/openssh-portable/commit/e8bdfb151a356d0171fea4194dd205fbb252be23]
+
+Backport Changes:
+- Omitted the upstream OpenBSD revision-only hunks in ssh.c,
+  sshconnect.c, sshconnect.h, and sshconnect2.c and retained the Wrynose
+  OpenSSH 10.3p1 revisions because this stable backport carries only the
+  functional security changes.
+
+(cherry picked from commit e8bdfb151a356d0171fea4194dd205fbb252be23)
+Signed-off-by: Devansh Patel <[email protected]>
+---
+ 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 531f28eb2..efb8930f4 100644
+--- a/ssh.c
++++ b/ssh.c
+@@ -612,26 +612,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);
+-}
+-
+ /*
+  * Main program for the ssh client.
+  */
+@@ -1799,8 +1779,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 4384277a6..3d338ff23 100644
+--- a/sshconnect.c
++++ b/sshconnect.c
+@@ -70,6 +70,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,
+@@ -1585,8 +1628,8 @@ warn_nonpq_kex(void)
+  */
+ 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 4c19490da..8da0e04b9 100644
+--- a/sshconnect.h
++++ b/sshconnect.h
+@@ -76,7 +76,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 *,
+@@ -85,7 +85,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 *,
+@@ -101,3 +101,6 @@ void        load_hostkeys_command(struct hostkeys *, const 
char *,
+     const struct sshkey *, const char *);
+ 
+ int hostkey_accepted_by_hostkeyalgs(const struct sshkey *);
++
++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 478a9a52f..50ac6b89d 100644
+--- a/sshconnect2.c
++++ b/sshconnect2.c
+@@ -83,7 +83,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 *);
+ 
+@@ -99,7 +99,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;
+@@ -216,16 +216,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 *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,
+@@ -248,8 +248,10 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr 
*hostaddr, u_short port,
+               fatal_fr(r, "kex_assemble_namelist");
+       free(all_key);
+ 
+-      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,
+           options.kex_algorithms, options.ciphers, options.macs,
diff --git a/meta/recipes-connectivity/openssh/openssh_10.3p1.bb 
b/meta/recipes-connectivity/openssh/openssh_10.3p1.bb
index d8d73ee5dd0..8edb1440fe0 100644
--- a/meta/recipes-connectivity/openssh/openssh_10.3p1.bb
+++ b/meta/recipes-connectivity/openssh/openssh_10.3p1.bb
@@ -29,6 +29,7 @@ SRC_URI = 
"https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-${PV}.ta
            file://CVE-2026-59996.patch \
            file://CVE-2026-59995.patch \
            file://CVE-2026-60001.patch \
+           file://CVE-2026-60002.patch \
            "
 SRC_URI[sha256sum] = 
"56682a36bb92dcf4b4f016fd8ec8e74059b79a8de25c15d670d731e7d18e45f4"
 
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#241735): 
https://lists.openembedded.org/g/openembedded-core/message/241735
Mute This Topic: https://lists.openembedded.org/mt/120397952/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to