summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2018-07-31 03:07:24 +0000
committerDamien Miller <djm@mindrot.org>2018-07-31 13:13:26 +1000
commit1a66079c0669813306cc69e5776a4acd9fb49015 (patch)
tree892eb2fcddac9189cc1d8e7a9b821bde27ba1014
parent87f08be054b7eeadbb9cdeb3fb4872be79ccf218 (diff)
upstream: fix some memory leaks spotted by Coverity via Jakub Jelen
in bz#2366 feedback and ok dtucker@ OpenBSD-Commit-ID: 8402bbae67d578bedbadb0ce68ff7c5a136ef563
-rw-r--r--addrmatch.c25
-rw-r--r--compat.c51
-rw-r--r--compat.h14
-rw-r--r--mux.c3
-rw-r--r--sftp-client.c20
-rw-r--r--sshconnect2.c15
-rw-r--r--sshd.c10
7 files changed, 82 insertions, 56 deletions
diff --git a/addrmatch.c b/addrmatch.c
index 8658e105a..5a402d065 100644
--- a/addrmatch.c
+++ b/addrmatch.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: addrmatch.c,v 1.13 2016/09/21 16:55:42 djm Exp $ */ 1/* $OpenBSD: addrmatch.c,v 1.14 2018/07/31 03:07:24 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2004-2008 Damien Miller <djm@mindrot.org> 4 * Copyright (c) 2004-2008 Damien Miller <djm@mindrot.org>
@@ -205,25 +205,24 @@ addr_cmp(const struct xaddr *a, const struct xaddr *b)
205static int 205static int
206addr_pton(const char *p, struct xaddr *n) 206addr_pton(const char *p, struct xaddr *n)
207{ 207{
208 struct addrinfo hints, *ai; 208 struct addrinfo hints, *ai = NULL;
209 int ret = -1;
209 210
210 memset(&hints, '\0', sizeof(hints)); 211 memset(&hints, '\0', sizeof(hints));
211 hints.ai_flags = AI_NUMERICHOST; 212 hints.ai_flags = AI_NUMERICHOST;
212 213
213 if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0) 214 if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0)
214 return -1; 215 goto out;
215
216 if (ai == NULL || ai->ai_addr == NULL) 216 if (ai == NULL || ai->ai_addr == NULL)
217 return -1; 217 goto out;
218 218 if (n != NULL && addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen, n) == -1)
219 if (n != NULL && 219 goto out;
220 addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen, n) == -1) { 220 /* success */
221 ret = 0;
222 out:
223 if (ai != NULL)
221 freeaddrinfo(ai); 224 freeaddrinfo(ai);
222 return -1; 225 return ret;
223 }
224
225 freeaddrinfo(ai);
226 return 0;
227} 226}
228 227
229/* 228/*
diff --git a/compat.c b/compat.c
index d0afe9084..563e13331 100644
--- a/compat.c
+++ b/compat.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: compat.c,v 1.111 2018/07/09 21:03:30 markus Exp $ */ 1/* $OpenBSD: compat.c,v 1.112 2018/07/31 03:07:24 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
4 * 4 *
@@ -184,13 +184,17 @@ proto_spec(const char *spec)
184} 184}
185 185
186char * 186char *
187compat_cipher_proposal(char *cipher_prop) 187compat_cipher_proposal(char *cipher_prop, u_int compat)
188{ 188{
189 if (!(datafellows & SSH_BUG_BIGENDIANAES)) 189 char *cp;
190
191 if (!(compat & SSH_BUG_BIGENDIANAES))
190 return cipher_prop; 192 return cipher_prop;
191 debug2("%s: original cipher proposal: %s", __func__, cipher_prop); 193 debug2("%s: original cipher proposal: %s", __func__, cipher_prop);
192 if ((cipher_prop = match_filter_blacklist(cipher_prop, "aes*")) == NULL) 194 if ((cp = match_filter_blacklist(cipher_prop, "aes*")) == NULL)
193 fatal("match_filter_blacklist failed"); 195 fatal("match_filter_blacklist failed");
196 free(cipher_prop);
197 cipher_prop = cp;
194 debug2("%s: compat cipher proposal: %s", __func__, cipher_prop); 198 debug2("%s: compat cipher proposal: %s", __func__, cipher_prop);
195 if (*cipher_prop == '\0') 199 if (*cipher_prop == '\0')
196 fatal("No supported ciphers found"); 200 fatal("No supported ciphers found");
@@ -198,13 +202,17 @@ compat_cipher_proposal(char *cipher_prop)
198} 202}
199 203
200char * 204char *
201compat_pkalg_proposal(char *pkalg_prop) 205compat_pkalg_proposal(char *pkalg_prop, u_int compat)
202{ 206{
203 if (!(datafellows & SSH_BUG_RSASIGMD5)) 207 char *cp;
208
209 if (!(compat & SSH_BUG_RSASIGMD5))
204 return pkalg_prop; 210 return pkalg_prop;
205 debug2("%s: original public key proposal: %s", __func__, pkalg_prop); 211 debug2("%s: original public key proposal: %s", __func__, pkalg_prop);
206 if ((pkalg_prop = match_filter_blacklist(pkalg_prop, "ssh-rsa")) == NULL) 212 if ((cp = match_filter_blacklist(pkalg_prop, "ssh-rsa")) == NULL)
207 fatal("match_filter_blacklist failed"); 213 fatal("match_filter_blacklist failed");
214 free(pkalg_prop);
215 pkalg_prop = cp;
208 debug2("%s: compat public key proposal: %s", __func__, pkalg_prop); 216 debug2("%s: compat public key proposal: %s", __func__, pkalg_prop);
209 if (*pkalg_prop == '\0') 217 if (*pkalg_prop == '\0')
210 fatal("No supported PK algorithms found"); 218 fatal("No supported PK algorithms found");
@@ -212,24 +220,31 @@ compat_pkalg_proposal(char *pkalg_prop)
212} 220}
213 221
214char * 222char *
215compat_kex_proposal(char *p) 223compat_kex_proposal(char *kex_prop, u_int compat)
216{ 224{
217 if ((datafellows & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0) 225 char *cp;
218 return p; 226
219 debug2("%s: original KEX proposal: %s", __func__, p); 227 if ((compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0)
220 if ((datafellows & SSH_BUG_CURVE25519PAD) != 0) 228 return kex_prop;
221 if ((p = match_filter_blacklist(p, 229 debug2("%s: original KEX proposal: %s", __func__, kex_prop);
230 if ((compat & SSH_BUG_CURVE25519PAD) != 0) {
231 if ((cp = match_filter_blacklist(kex_prop,
222 "curve25519-sha256@libssh.org")) == NULL) 232 "curve25519-sha256@libssh.org")) == NULL)
223 fatal("match_filter_blacklist failed"); 233 fatal("match_filter_blacklist failed");
224 if ((datafellows & SSH_OLD_DHGEX) != 0) { 234 free(kex_prop);
225 if ((p = match_filter_blacklist(p, 235 kex_prop = cp;
236 }
237 if ((compat & SSH_OLD_DHGEX) != 0) {
238 if ((cp = match_filter_blacklist(kex_prop,
226 "diffie-hellman-group-exchange-sha256," 239 "diffie-hellman-group-exchange-sha256,"
227 "diffie-hellman-group-exchange-sha1")) == NULL) 240 "diffie-hellman-group-exchange-sha1")) == NULL)
228 fatal("match_filter_blacklist failed"); 241 fatal("match_filter_blacklist failed");
242 free(kex_prop);
243 kex_prop = cp;
229 } 244 }
230 debug2("%s: compat KEX proposal: %s", __func__, p); 245 debug2("%s: compat KEX proposal: %s", __func__, kex_prop);
231 if (*p == '\0') 246 if (*kex_prop == '\0')
232 fatal("No supported key exchange algorithms found"); 247 fatal("No supported key exchange algorithms found");
233 return p; 248 return kex_prop;
234} 249}
235 250
diff --git a/compat.h b/compat.h
index 28d2c8135..e2877737b 100644
--- a/compat.h
+++ b/compat.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: compat.h,v 1.52 2018/07/03 11:39:54 djm Exp $ */ 1/* $OpenBSD: compat.h,v 1.53 2018/07/31 03:07:24 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
@@ -65,9 +65,15 @@
65 65
66u_int compat_datafellows(const char *); 66u_int compat_datafellows(const char *);
67int proto_spec(const char *); 67int proto_spec(const char *);
68char *compat_cipher_proposal(char *); 68
69char *compat_pkalg_proposal(char *); 69/*
70char *compat_kex_proposal(char *); 70 * compat_*_proposal will update their respective proposals based on the
71 * active compat flags. The replacement is performed in-place - i.e. they
72 * will free their argument and return a new heap-allocated string.
73 */
74char *compat_cipher_proposal(char *, u_int compat);
75char *compat_pkalg_proposal(char *, u_int compat);
76char *compat_kex_proposal(char *, u_int compat);
71 77
72extern int datafellows; 78extern int datafellows;
73#endif 79#endif
diff --git a/mux.c b/mux.c
index 6394e3e18..e607acd08 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.74 2018/07/11 18:53:29 markus Exp $ */ 1/* $OpenBSD: mux.c,v 1.75 2018/07/31 03:07:24 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -1042,6 +1042,7 @@ process_mux_stdio_fwd(struct ssh *ssh, u_int rid,
1042 set_nonblock(new_fd[1]); 1042 set_nonblock(new_fd[1]);
1043 1043
1044 nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1]); 1044 nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1]);
1045 free(chost);
1045 1046
1046 nc->ctl_chan = c->self; /* link session -> control channel */ 1047 nc->ctl_chan = c->self; /* link session -> control channel */
1047 c->remote_id = nc->self; /* link control -> session channel */ 1048 c->remote_id = nc->self; /* link control -> session channel */
diff --git a/sftp-client.c b/sftp-client.c
index dc4d8c4e0..4986d6d8d 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp-client.c,v 1.129 2018/05/25 04:25:46 djm Exp $ */ 1/* $OpenBSD: sftp-client.c,v 1.130 2018/07/31 03:07:24 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -1461,7 +1461,7 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
1461{ 1461{
1462 int i, ret = 0; 1462 int i, ret = 0;
1463 SFTP_DIRENT **dir_entries; 1463 SFTP_DIRENT **dir_entries;
1464 char *filename, *new_src, *new_dst; 1464 char *filename, *new_src = NULL, *new_dst = NULL;
1465 mode_t mode = 0777; 1465 mode_t mode = 0777;
1466 1466
1467 if (depth >= MAX_DIR_DEPTH) { 1467 if (depth >= MAX_DIR_DEPTH) {
@@ -1499,8 +1499,10 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
1499 } 1499 }
1500 1500
1501 for (i = 0; dir_entries[i] != NULL && !interrupted; i++) { 1501 for (i = 0; dir_entries[i] != NULL && !interrupted; i++) {
1502 filename = dir_entries[i]->filename; 1502 free(new_dst);
1503 free(new_src);
1503 1504
1505 filename = dir_entries[i]->filename;
1504 new_dst = path_append(dst, filename); 1506 new_dst = path_append(dst, filename);
1505 new_src = path_append(src, filename); 1507 new_src = path_append(src, filename);
1506 1508
@@ -1523,9 +1525,9 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
1523 } else 1525 } else
1524 logit("%s: not a regular file\n", new_src); 1526 logit("%s: not a regular file\n", new_src);
1525 1527
1526 free(new_dst);
1527 free(new_src);
1528 } 1528 }
1529 free(new_dst);
1530 free(new_src);
1529 1531
1530 if (preserve_flag) { 1532 if (preserve_flag) {
1531 if (dirattrib->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { 1533 if (dirattrib->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
@@ -1793,7 +1795,7 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
1793 int ret = 0; 1795 int ret = 0;
1794 DIR *dirp; 1796 DIR *dirp;
1795 struct dirent *dp; 1797 struct dirent *dp;
1796 char *filename, *new_src, *new_dst; 1798 char *filename, *new_src = NULL, *new_dst = NULL;
1797 struct stat sb; 1799 struct stat sb;
1798 Attrib a, *dirattrib; 1800 Attrib a, *dirattrib;
1799 1801
@@ -1844,6 +1846,8 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
1844 while (((dp = readdir(dirp)) != NULL) && !interrupted) { 1846 while (((dp = readdir(dirp)) != NULL) && !interrupted) {
1845 if (dp->d_ino == 0) 1847 if (dp->d_ino == 0)
1846 continue; 1848 continue;
1849 free(new_dst);
1850 free(new_src);
1847 filename = dp->d_name; 1851 filename = dp->d_name;
1848 new_dst = path_append(dst, filename); 1852 new_dst = path_append(dst, filename);
1849 new_src = path_append(src, filename); 1853 new_src = path_append(src, filename);
@@ -1870,9 +1874,9 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
1870 } 1874 }
1871 } else 1875 } else
1872 logit("%s: not a regular file\n", filename); 1876 logit("%s: not a regular file\n", filename);
1873 free(new_dst);
1874 free(new_src);
1875 } 1877 }
1878 free(new_dst);
1879 free(new_src);
1876 1880
1877 do_setstat(conn, dst, &a); 1881 do_setstat(conn, dst, &a);
1878 1882
diff --git a/sshconnect2.c b/sshconnect2.c
index 5d2bde81d..93192d186 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.282 2018/07/18 11:34:04 dtucker Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.283 2018/07/31 03:07:24 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Damien Miller. All rights reserved. 4 * Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -167,11 +167,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
167 167
168 if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) 168 if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL)
169 fatal("%s: kex_names_cat", __func__); 169 fatal("%s: kex_names_cat", __func__);
170 myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s); 170 myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s, datafellows);
171 myproposal[PROPOSAL_ENC_ALGS_CTOS] = 171 myproposal[PROPOSAL_ENC_ALGS_CTOS] =
172 compat_cipher_proposal(options.ciphers); 172 compat_cipher_proposal(options.ciphers, datafellows);
173 myproposal[PROPOSAL_ENC_ALGS_STOC] = 173 myproposal[PROPOSAL_ENC_ALGS_STOC] =
174 compat_cipher_proposal(options.ciphers); 174 compat_cipher_proposal(options.ciphers, datafellows);
175 myproposal[PROPOSAL_COMP_ALGS_CTOS] = 175 myproposal[PROPOSAL_COMP_ALGS_CTOS] =
176 myproposal[PROPOSAL_COMP_ALGS_STOC] = options.compression ? 176 myproposal[PROPOSAL_COMP_ALGS_STOC] = options.compression ?
177 "zlib@openssh.com,zlib,none" : "none,zlib@openssh.com,zlib"; 177 "zlib@openssh.com,zlib,none" : "none,zlib@openssh.com,zlib";
@@ -184,14 +184,15 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
184 fatal("%s: kex_assemble_namelist", __func__); 184 fatal("%s: kex_assemble_namelist", __func__);
185 free(all_key); 185 free(all_key);
186 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = 186 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
187 compat_pkalg_proposal(options.hostkeyalgorithms); 187 compat_pkalg_proposal(options.hostkeyalgorithms,
188 datafellows);
188 } else { 189 } else {
189 /* Enforce default */ 190 /* Enforce default */
190 options.hostkeyalgorithms = xstrdup(KEX_DEFAULT_PK_ALG); 191 options.hostkeyalgorithms = xstrdup(KEX_DEFAULT_PK_ALG);
191 /* Prefer algorithms that we already have keys for */ 192 /* Prefer algorithms that we already have keys for */
192 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = 193 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
193 compat_pkalg_proposal( 194 compat_pkalg_proposal(
194 order_hostkeyalgs(host, hostaddr, port)); 195 order_hostkeyalgs(host, hostaddr, port), datafellows);
195 } 196 }
196 197
197 if (options.rekey_limit || options.rekey_interval) 198 if (options.rekey_limit || options.rekey_interval)
@@ -223,7 +224,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
223 224
224 /* remove ext-info from the KEX proposals for rekeying */ 225 /* remove ext-info from the KEX proposals for rekeying */
225 myproposal[PROPOSAL_KEX_ALGS] = 226 myproposal[PROPOSAL_KEX_ALGS] =
226 compat_kex_proposal(options.kex_algorithms); 227 compat_kex_proposal(options.kex_algorithms, datafellows);
227 if ((r = kex_prop2buf(kex->my, myproposal)) != 0) 228 if ((r = kex_prop2buf(kex->my, myproposal)) != 0)
228 fatal("kex_prop2buf: %s", ssh_err(r)); 229 fatal("kex_prop2buf: %s", ssh_err(r));
229 230
diff --git a/sshd.c b/sshd.c
index d7d6f2b26..d3bd8fdaa 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.512 2018/07/11 18:53:29 markus Exp $ */ 1/* $OpenBSD: sshd.c,v 1.513 2018/07/31 03:07:24 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2268,11 +2268,11 @@ do_ssh2_kex(void)
2268 int r; 2268 int r;
2269 2269
2270 myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( 2270 myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(
2271 options.kex_algorithms); 2271 options.kex_algorithms, datafellows);
2272 myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal( 2272 myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(
2273 options.ciphers); 2273 options.ciphers, datafellows);
2274 myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal( 2274 myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal(
2275 options.ciphers); 2275 options.ciphers, datafellows);
2276 myproposal[PROPOSAL_MAC_ALGS_CTOS] = 2276 myproposal[PROPOSAL_MAC_ALGS_CTOS] =
2277 myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; 2277 myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
2278 2278
@@ -2286,7 +2286,7 @@ do_ssh2_kex(void)
2286 options.rekey_interval); 2286 options.rekey_interval);
2287 2287
2288 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( 2288 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
2289 list_hostkey_types()); 2289 list_hostkey_types(), datafellows);
2290 2290
2291 /* start key exchange */ 2291 /* start key exchange */
2292 if ((r = kex_setup(active_state, myproposal)) != 0) 2292 if ((r = kex_setup(active_state, myproposal)) != 0)