diff options
author | dtucker@openbsd.org <dtucker@openbsd.org> | 2019-09-13 04:36:43 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2019-09-13 14:53:45 +1000 |
commit | b36ee3fcb2f1601693b1b7fd60dd6bd96006ea75 (patch) | |
tree | a3306118a58e6d505af368300e93a18848ca428c | |
parent | 2aefdf1aef906cf7548a2e5927d35aacb55948d4 (diff) |
upstream: Plug mem leaks on error paths, based in part on github
pr#120 from David Carlier. ok djm@.
OpenBSD-Commit-ID: c57adeb1022a8148fc86e5a88837b3b156dbdb7e
-rw-r--r-- | auth-options.c | 3 | ||||
-rw-r--r-- | ssh_api.c | 34 |
2 files changed, 21 insertions, 16 deletions
diff --git a/auth-options.c b/auth-options.c index 6fb59dc7..9550f656 100644 --- a/auth-options.c +++ b/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.88 2019/09/06 04:53:27 djm Exp $ */ +/* $OpenBSD: auth-options.c,v 1.89 2019/09/13 04:36:43 dtucker Exp $ */ /* * Copyright (c) 2018 Damien Miller <djm@mindrot.org> * @@ -266,6 +266,7 @@ handle_permit(const char **optsp, int allow_bare_port, * listen_host wildcard. */ if (asprintf(&tmp, "*:%s", opt) == -1) { + free(opt); *errstrp = "memory allocation failed"; return -1; } @@ -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. * @@ -330,8 +330,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;;) { @@ -357,10 +357,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: @@ -373,19 +371,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); @@ -395,10 +396,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. */ |