summaryrefslogtreecommitdiffstats
path: root/usr.bin/ssh/ssh_api.c
diff options
context:
space:
mode:
authordtucker <dtucker@openbsd.org>2019-09-13 04:36:43 +0000
committerdtucker <dtucker@openbsd.org>2019-09-13 04:36:43 +0000
commit33d1bf81aaf6e577a697fced50645073ffb73005 (patch)
tree152740b87c1754392c7c6a6f1716bb561afb756b /usr.bin/ssh/ssh_api.c
parentwhitespace (diff)
downloadwireguard-openbsd-33d1bf81aaf6e577a697fced50645073ffb73005.tar.xz
wireguard-openbsd-33d1bf81aaf6e577a697fced50645073ffb73005.zip
Plug mem leaks on error paths, based in part on github pr#120 from
David Carlier. ok djm@.
Diffstat (limited to 'usr.bin/ssh/ssh_api.c')
-rw-r--r--usr.bin/ssh/ssh_api.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/usr.bin/ssh/ssh_api.c b/usr.bin/ssh/ssh_api.c
index 43aebbc3121..511c034acaa 100644
--- a/usr.bin/ssh/ssh_api.c
+++ b/usr.bin/ssh/ssh_api.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh_api.c,v 1.17 2019/09/06 05:23:55 djm Exp $ */
+/* $OpenBSD: ssh_api.c,v 1.18 2019/09/13 04:36:43 dtucker Exp $ */
/*
* Copyright (c) 2012 Markus Friedl. All rights reserved.
*
@@ -324,8 +324,8 @@ _ssh_read_banner(struct ssh *ssh, struct sshbuf *banner)
const char *mismatch = "Protocol mismatch.\r\n";
const u_char *s = sshbuf_ptr(input);
u_char c;
- char *cp, *remote_version;
- int r, remote_major, remote_minor, expect_nl;
+ char *cp = NULL, *remote_version = NULL;
+ int r = 0, remote_major, remote_minor, expect_nl;
size_t n, j;
for (j = n = 0;;) {
@@ -351,10 +351,8 @@ _ssh_read_banner(struct ssh *ssh, struct sshbuf *banner)
if (sshbuf_len(banner) >= 4 &&
memcmp(sshbuf_ptr(banner), "SSH-", 4) == 0)
break;
- if ((cp = sshbuf_dup_string(banner)) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- debug("%s: %s", __func__, cp);
- free(cp);
+ debug("%s: %.*s", __func__, (int)sshbuf_len(banner),
+ sshbuf_ptr(banner));
/* Accept lines before banner only on client */
if (ssh->kex->server || ++n > SSH_MAX_PRE_BANNER_LINES) {
bad:
@@ -367,19 +365,22 @@ _ssh_read_banner(struct ssh *ssh, struct sshbuf *banner)
if ((r = sshbuf_consume(input, j)) != 0)
return r;
- if ((cp = sshbuf_dup_string(banner)) == NULL)
- return SSH_ERR_ALLOC_FAIL;
/* XXX remote version must be the same size as banner for sscanf */
- if ((remote_version = calloc(1, sshbuf_len(banner))) == NULL)
- return SSH_ERR_ALLOC_FAIL;
+ if ((cp = sshbuf_dup_string(banner)) == NULL ||
+ (remote_version = calloc(1, sshbuf_len(banner))) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
/*
* Check that the versions match. In future this might accept
* several versions and set appropriate flags to handle them.
*/
if (sscanf(cp, "SSH-%d.%d-%[^\n]\n",
- &remote_major, &remote_minor, remote_version) != 3)
- return SSH_ERR_INVALID_FORMAT;
+ &remote_major, &remote_minor, remote_version) != 3) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
debug("Remote protocol version %d.%d, remote software version %.100s",
remote_major, remote_minor, remote_version);
@@ -389,10 +390,13 @@ _ssh_read_banner(struct ssh *ssh, struct sshbuf *banner)
remote_minor = 0;
}
if (remote_major != 2)
- return SSH_ERR_PROTOCOL_MISMATCH;
+ r = SSH_ERR_PROTOCOL_MISMATCH;
+
debug("Remote version string %.100s", cp);
+ out:
free(cp);
- return 0;
+ free(remote_version);
+ return r;
}
/* Send our own protocol version identification. */