[openssh-commits] [openssh] 02/07: upstream: fix ownership and lifetime of several bits of client
git+noreply at mindrot.org
git+noreply at mindrot.org
Mon Jul 6 19:03:47 AEST 2026
This is an automated email from the git hooks/post-receive script.
djm pushed a commit to branch V_10_4
in repository openssh.
commit e8bdfb151a356d0171fea4194dd205fbb252be23
Author: djm at openbsd.org <djm at openbsd.org>
AuthorDate: Mon Jul 6 07:49:58 2026 +0000
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
---
ssh.c | 26 +++-----------------------
sshconnect.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++---
sshconnect.h | 9 ++++++---
sshconnect2.c | 22 ++++++++++++----------
4 files changed, 67 insertions(+), 39 deletions(-)
diff --git a/ssh.c b/ssh.c
index 5a160c8c1..7c644c23c 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.633 2026/06/14 03:59:34 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.634 2026/07/06 07:49:58 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo at cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -613,26 +613,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.
*/
@@ -1803,8 +1783,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 2fc1f6026..0ddfc76b3 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.383 2026/06/14 03:59:34 djm Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.384 2026/07/06 07:49:58 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo at cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -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..2ac2c07e0 100644
--- a/sshconnect.h
+++ b/sshconnect.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.h,v 1.50 2026/02/13 01:04:47 jsg Exp $ */
+/* $OpenBSD: sshconnect.h,v 1.51 2026/07/06 07:49:58 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -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 ecb4ae524..d1555ee97 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.387 2026/06/28 23:31:28 djm Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.388 2026/07/06 07:49:58 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -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,
--
To stop receiving notification emails like this one, please contact
djm at mindrot.org.
More information about the openssh-commits
mailing list