From 038ec85e825fc940c1387f64a88ae73b75f6822b Mon Sep 17 00:00:00 2001 From: simon Date: Sun, 14 Jul 2013 10:46:07 +0000 Subject: [PATCH] Fix another giant batch of resource leaks. (Mostly memory, but there's one missing fclose too.) git-svn-id: svn://svn.tartarus.org/sgt/putty@9919 cda61777-01e9-0310-a592-d414129be87e --- import.c | 24 +++++++++++++++++------- portfwd.c | 1 + proxy.c | 1 + pscp.c | 11 +++++++++-- psftp.c | 2 ++ raw.c | 1 + rlogin.c | 1 + ssh.c | 6 +++--- sshdss.c | 3 +++ sshpubk.c | 2 ++ sshrsa.c | 2 ++ telnet.c | 1 + unix/gtkfont.c | 4 +++- unix/gtkwin.c | 8 +++++++- unix/uxgen.c | 1 + unix/uxproxy.c | 1 + unix/uxser.c | 1 + unix/uxsftp.c | 3 +++ unix/uxstore.c | 11 +++++++---- x11fwd.c | 5 ++++- 20 files changed, 70 insertions(+), 19 deletions(-) diff --git a/import.c b/import.c index d009241b..d4b87bc7 100644 --- a/import.c +++ b/import.c @@ -370,8 +370,10 @@ static struct openssh_key *load_openssh_key(const Filename *filename, } strip_crlf(line); if (0 == strncmp(line, "-----END ", 9) && - 0 == strcmp(line+strlen(line)-16, "PRIVATE KEY-----")) + 0 == strcmp(line+strlen(line)-16, "PRIVATE KEY-----")) { + sfree(line); break; /* done */ + } if ((p = strchr(line, ':')) != NULL) { if (headers_done) { errmsg = "header found in body of key data"; @@ -1091,8 +1093,10 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename, goto error; } strip_crlf(line); - if (!strcmp(line, "---- END SSH2 ENCRYPTED PRIVATE KEY ----")) + if (!strcmp(line, "---- END SSH2 ENCRYPTED PRIVATE KEY ----")) { + sfree(line); break; /* done */ + } if ((p = strchr(line, ':')) != NULL) { if (headers_done) { errmsg = "header found in body of key data"; @@ -1181,10 +1185,14 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename, goto error; } + fclose(fp); if (errmsg_p) *errmsg_p = NULL; return ret; error: + if (fp) + fclose(fp); + if (line) { smemclr(line, strlen(line)); sfree(line); @@ -1207,20 +1215,22 @@ int sshcom_encrypted(const Filename *filename, char **comment) struct sshcom_key *key = load_sshcom_key(filename, NULL); int pos, len, answer; + answer = 0; + *comment = NULL; if (!key) - return 0; + goto done; /* * Check magic number. */ - if (GET_32BIT(key->keyblob) != 0x3f6ff9eb) - return 0; /* key is invalid */ + if (GET_32BIT(key->keyblob) != 0x3f6ff9eb) { + goto done; /* key is invalid */ + } /* * Find the cipher-type string. */ - answer = 0; pos = 8; if (key->keyblob_len < pos+4) goto done; /* key is far too short */ @@ -1235,7 +1245,7 @@ int sshcom_encrypted(const Filename *filename, char **comment) answer = 1; done: - *comment = dupstr(key->comment); + *comment = dupstr(key ? key->comment : ""); smemclr(key->keyblob, key->keyblob_size); sfree(key->keyblob); smemclr(key, sizeof(*key)); diff --git a/portfwd.c b/portfwd.c index 70b89100..97c1cb74 100644 --- a/portfwd.c +++ b/portfwd.c @@ -386,6 +386,7 @@ const char *pfd_newconnect(Socket *s, char *hostname, int port, pr->s = *s = new_connection(addr, dummy_realhost, port, 0, 1, 0, 0, (Plug) pr, conf); + sfree(dummy_realhost); if ((err = sk_socket_error(*s)) != NULL) { free_portfwd_private(pr); return err; diff --git a/proxy.c b/proxy.c index bb89a176..70da38c3 100644 --- a/proxy.c +++ b/proxy.c @@ -473,6 +473,7 @@ Socket new_connection(SockAddr addr, char *hostname, conf_get_int(conf, CONF_addressfamily)); if (sk_addr_error(proxy_addr) != NULL) { ret->error = "Proxy error: Unable to resolve proxy host name"; + sfree(pplug); return (Socket)ret; } sfree(proxy_canonical_name); diff --git a/pscp.c b/pscp.c index a6886d76..70e3e7a1 100644 --- a/pscp.c +++ b/pscp.c @@ -1118,6 +1118,9 @@ int scp_sink_setup(char *source, int preserve, int recursive) if (!wc_unescape(newsource, source)) { /* Yes, here we go; it's a wildcard. Bah. */ char *dupsource, *lastpart, *dirpart, *wildcard; + + sfree(newsource); + dupsource = dupstr(source); lastpart = stripslashes(dupsource, 0); wildcard = dupstr(lastpart); @@ -1722,8 +1725,10 @@ static void source(char *src) return; } if (preserve) { - if (scp_send_filetimes(mtime, atime)) + if (scp_send_filetimes(mtime, atime)) { + close_rfile(f); return; + } } if (verbose) { @@ -1731,8 +1736,10 @@ static void source(char *src) uint64_decimal(size, sizestr); tell_user(stderr, "Sending file %s, size=%s", last, sizestr); } - if (scp_send_filename(last, size, permissions)) + if (scp_send_filename(last, size, permissions)) { + close_rfile(f); return; + } stat_bytes = uint64_make(0,0); stat_starttime = time(NULL); diff --git a/psftp.c b/psftp.c index c7a8486b..322b9c68 100644 --- a/psftp.c +++ b/psftp.c @@ -1035,6 +1035,7 @@ int sftp_cmd_ls(struct sftp_command *cmd) char *tmpdir; int len, check; + sfree(unwcdir); wildcard = stripslashes(dir, 0); unwcdir = dupstr(dir); len = wildcard - dir; @@ -2233,6 +2234,7 @@ struct sftp_command *sftp_getcmd(FILE *fp, int mode, int modeflags) cmd->obey = sftp_cmd_quit; if ((mode == 0) || (modeflags & 1)) printf("quit\n"); + sfree(line); return cmd; /* eof */ } diff --git a/raw.c b/raw.c index 698d7e4f..1d9f854c 100644 --- a/raw.c +++ b/raw.c @@ -50,6 +50,7 @@ static void raw_log(Plug plug, int type, SockAddr addr, int port, msg = dupprintf("Failed to connect to %s: %s", addrbuf, error_msg); logevent(raw->frontend, msg); + sfree(msg); } static void raw_check_close(Raw raw) diff --git a/rlogin.c b/rlogin.c index faf3daf9..f582f0c0 100644 --- a/rlogin.c +++ b/rlogin.c @@ -58,6 +58,7 @@ static void rlogin_log(Plug plug, int type, SockAddr addr, int port, msg = dupprintf("Failed to connect to %s: %s", addrbuf, error_msg); logevent(rlogin->frontend, msg); + sfree(msg); } static int rlogin_closing(Plug plug, const char *error_msg, int error_code, diff --git a/ssh.c b/ssh.c index ce3a5278..db31d389 100644 --- a/ssh.c +++ b/ssh.c @@ -4869,14 +4869,11 @@ static void ssh1_msg_port_open(Ssh ssh, struct Packet *pktin) { /* Remote side is trying to open a channel to talk to a * forwarded port. Give them back a local channel number. */ - struct ssh_channel *c; struct ssh_rportfwd pf, *pfp; int remoteid; int hostsize, port; char *host; const char *e; - c = snew(struct ssh_channel); - c->ssh = ssh; remoteid = ssh_pkt_getuint32(pktin); ssh_pkt_getstring(pktin, &host, &hostsize); @@ -4895,6 +4892,9 @@ static void ssh1_msg_port_open(Ssh ssh, struct Packet *pktin) send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE, PKT_INT, remoteid, PKT_END); } else { + struct ssh_channel *c = snew(struct ssh_channel); + c->ssh = ssh; + logeventf(ssh, "Received remote port open request for %s:%d", pf.dhost, port); e = pfd_newconnect(&c->u.pfd.s, pf.dhost, port, diff --git a/sshdss.c b/sshdss.c index 0484c443..532c13f2 100644 --- a/sshdss.c +++ b/sshdss.c @@ -289,6 +289,8 @@ static int dss_verifysig(void *key, char *sig, int siglen, freebn(w); freebn(sha); + freebn(u1); + freebn(u2); freebn(gu1p); freebn(yu2p); freebn(gu1yu2p); @@ -404,6 +406,7 @@ static void *dss_createkey(unsigned char *pub_blob, int pub_len, ytest = modpow(dss->g, dss->x, dss->p); if (0 != bignum_cmp(ytest, dss->y)) { dss_freekey(dss); + freebn(ytest); return NULL; } freebn(ytest); diff --git a/sshpubk.c b/sshpubk.c index 72aaaa97..e5157a3c 100644 --- a/sshpubk.c +++ b/sshpubk.c @@ -1008,6 +1008,8 @@ int ssh2_userkey_encrypted(const Filename *filename, char **commentptr) if (commentptr) *commentptr = comment; + else + sfree(comment); fclose(fp); if (!strcmp(b, "aes256-cbc")) diff --git a/sshrsa.c b/sshrsa.c index 6403343b..7fb9694f 100644 --- a/sshrsa.c +++ b/sshrsa.c @@ -413,6 +413,7 @@ int rsa_verify(struct RSAKey *key) pm1 = copybn(key->p); decbn(pm1); ed = modmul(key->exponent, key->private_exponent, pm1); + freebn(pm1); cmp = bignum_cmp(ed, One); sfree(ed); if (cmp != 0) @@ -421,6 +422,7 @@ int rsa_verify(struct RSAKey *key) qm1 = copybn(key->q); decbn(qm1); ed = modmul(key->exponent, key->private_exponent, qm1); + freebn(qm1); cmp = bignum_cmp(ed, One); sfree(ed); if (cmp != 0) diff --git a/telnet.c b/telnet.c index 3536414c..6a56da77 100644 --- a/telnet.c +++ b/telnet.c @@ -662,6 +662,7 @@ static void telnet_log(Plug plug, int type, SockAddr addr, int port, msg = dupprintf("Failed to connect to %s: %s", addrbuf, error_msg); logevent(telnet->frontend, msg); + sfree(msg); } static int telnet_closing(Plug plug, const char *error_msg, int error_code, diff --git a/unix/gtkfont.c b/unix/gtkfont.c index 56ae0315..d241db0e 100644 --- a/unix/gtkfont.c +++ b/unix/gtkfont.c @@ -191,8 +191,10 @@ static char *x11_guess_derived_font_name(XFontStruct *xfs, int bold, int wide) p++; } - if (nstr < lenof(strings)) + if (nstr < lenof(strings)) { + sfree(dupname); return NULL; /* XLFD was malformed */ + } if (bold) strings[2] = "bold"; diff --git a/unix/gtkwin.c b/unix/gtkwin.c index 4a1df45d..e1640763 100644 --- a/unix/gtkwin.c +++ b/unix/gtkwin.c @@ -3009,7 +3009,7 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data) 4, 12, 5, 13, 6, 14, 7, 15 }; struct gui_data *inst = (struct gui_data *)data; - char *title = dupcat(appname, " Reconfiguration", NULL); + char *title; Conf *oldconf, *newconf; int i, j, need_size; @@ -3020,6 +3020,8 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data) else inst->reconfiguring = TRUE; + title = dupcat(appname, " Reconfiguration", NULL); + oldconf = inst->conf; newconf = conf_copy(inst->conf); @@ -3134,6 +3136,7 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data) string_width("Could not change fonts in terminal window:"), "OK", 'o', +1, 1, NULL); + sfree(msgboxtext); sfree(errmsg); } else { need_size = TRUE; @@ -3228,6 +3231,7 @@ void fork_and_exec_self(struct gui_data *inst, int fd_to_close, ...) pid = fork(); if (pid < 0) { perror("fork"); + sfree(args); return; } @@ -3261,6 +3265,7 @@ void fork_and_exec_self(struct gui_data *inst, int fd_to_close, ...) } else { int status; + sfree(args); waitpid(pid, &status, 0); } @@ -3339,6 +3344,7 @@ int read_dupsession_data(struct gui_data *inst, Conf *conf, char *arg) } size_used = conf_deserialise(conf, data, size); + sfree(data); if (use_pty_argv && size > size_used) { int n = 0; i = size_used; diff --git a/unix/uxgen.c b/unix/uxgen.c index 7bed295c..156d4efe 100644 --- a/unix/uxgen.c +++ b/unix/uxgen.c @@ -26,6 +26,7 @@ char *get_random_data(int len) ret = read(fd, buf+ngot, len-ngot); if (ret < 0) { close(fd); + sfree(buf); perror("puttygen: unable to read /dev/random"); return NULL; } diff --git a/unix/uxproxy.c b/unix/uxproxy.c index def8a40a..9dee690e 100644 --- a/unix/uxproxy.c +++ b/unix/uxproxy.c @@ -297,6 +297,7 @@ Socket platform_new_connection(SockAddr addr, char *hostname, if (pid < 0) { ret->error = dupprintf("fork: %s", strerror(errno)); + sfree(cmd); return (Socket)ret; } else if (pid == 0) { close(0); diff --git a/unix/uxser.c b/unix/uxser.c index 8f4955c4..e45f3ae1 100644 --- a/unix/uxser.c +++ b/unix/uxser.c @@ -308,6 +308,7 @@ static const char *serial_init(void *frontend_handle, void **backend_handle, { char *msg = dupprintf("Opening serial device %s", line); logevent(serial->frontend, msg); + sfree(msg); } serial->fd = open(line, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); diff --git a/unix/uxsftp.c b/unix/uxsftp.c index f68685a0..57f28416 100644 --- a/unix/uxsftp.c +++ b/unix/uxsftp.c @@ -565,6 +565,7 @@ char *ssh_sftp_get_cmdline(char *prompt, int no_fds_ok) ret = ssh_sftp_do_select(TRUE, no_fds_ok); if (ret < 0) { printf("connection died\n"); + sfree(buf); return NULL; /* woop woop */ } if (ret > 0) { @@ -575,10 +576,12 @@ char *ssh_sftp_get_cmdline(char *prompt, int no_fds_ok) ret = read(0, buf+buflen, 1); if (ret < 0) { perror("read"); + sfree(buf); return NULL; } if (ret == 0) { /* eof on stdin; no error, but no answer either */ + sfree(buf); return NULL; } diff --git a/unix/uxstore.c b/unix/uxstore.c index 9d101575..c5e40d46 100644 --- a/unix/uxstore.c +++ b/unix/uxstore.c @@ -299,8 +299,10 @@ void *open_settings_r(const char *sessionname) char *value = strchr(line, '='); struct skeyval *kv; - if (!value) + if (!value) { + sfree(line); continue; + } *value++ = '\0'; value[strcspn(value, "\r\n")] = '\0'; /* trim trailing NL */ @@ -589,9 +591,6 @@ void store_host_key(const char *hostname, int port, int headerlen; char *filename, *tmpfilename; - newtext = dupprintf("%s@%d:%s %s\n", keytype, port, hostname, key); - headerlen = 1 + strcspn(newtext, " "); /* count the space too */ - /* * Open both the old file and a new file. */ @@ -613,6 +612,9 @@ void store_host_key(const char *hostname, int port, filename = make_filename(INDEX_HOSTKEYS, NULL); rfp = fopen(filename, "r"); + newtext = dupprintf("%s@%d:%s %s\n", keytype, port, hostname, key); + headerlen = 1 + strcspn(newtext, " "); /* count the space too */ + /* * Copy all lines from the old file to the new one that _don't_ * involve the same host key identifier as the one we're adding. @@ -621,6 +623,7 @@ void store_host_key(const char *hostname, int port, while ( (line = fgetline(rfp)) ) { if (strncmp(line, newtext, headerlen)) fputs(line, wfp); + sfree(line); } fclose(rfp); } diff --git a/x11fwd.c b/x11fwd.c index 1e04f542..895d8a99 100644 --- a/x11fwd.c +++ b/x11fwd.c @@ -171,6 +171,7 @@ struct X11Display *x11_setup_display(char *display, int authtype, Conf *conf) sk_addr_free(disp->addr); sfree(disp->hostname); sfree(disp->unixsocketpath); + sfree(disp); return NULL; /* FIXME: report an error */ } } @@ -343,7 +344,7 @@ void x11_get_auth_from_authfile(struct X11Display *disp, int len[4]; int family, protocol; int ideal_match = FALSE; - char *ourhostname = get_hostname(); + char *ourhostname; /* * Normally we should look for precisely the details specified in @@ -372,6 +373,8 @@ void x11_get_auth_from_authfile(struct X11Display *disp, if (!authfp) return; + ourhostname = get_hostname(); + /* Records in .Xauthority contain four strings of up to 64K each */ buf = snewn(65537 * 4, char); -- 2.11.0