Fix another giant batch of resource leaks. (Mostly memory, but there's
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sun, 14 Jul 2013 10:46:07 +0000 (10:46 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sun, 14 Jul 2013 10:46:07 +0000 (10:46 +0000)
one missing fclose too.)

git-svn-id: svn://svn.tartarus.org/sgt/putty@9919 cda61777-01e9-0310-a592-d414129be87e

20 files changed:
import.c
portfwd.c
proxy.c
pscp.c
psftp.c
raw.c
rlogin.c
ssh.c
sshdss.c
sshpubk.c
sshrsa.c
telnet.c
unix/gtkfont.c
unix/gtkwin.c
unix/uxgen.c
unix/uxproxy.c
unix/uxser.c
unix/uxsftp.c
unix/uxstore.c
x11fwd.c

index d009241..d4b87bc 100644 (file)
--- 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));
index 70b8910..97c1cb7 100644 (file)
--- 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 bb89a17..70da38c 100644 (file)
--- 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 a6886d7..70e3e7a 100644 (file)
--- 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 c7a8486..322b9c6 100644 (file)
--- 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 698d7e4..1d9f854 100644 (file)
--- 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)
index faf3daf..f582f0c 100644 (file)
--- 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 ce3a527..db31d38 100644 (file)
--- 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,
index 0484c44..532c13f 100644 (file)
--- 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);
index 72aaaa9..e5157a3 100644 (file)
--- 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"))
index 6403343..7fb9694 100644 (file)
--- 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)
index 3536414..6a56da7 100644 (file)
--- 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,
index 56ae031..d241db0 100644 (file)
@@ -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";
index 4a1df45..e164076 100644 (file)
@@ -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;
index 7bed295..156d4ef 100644 (file)
@@ -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;
        }
index def8a40..9dee690 100644 (file)
@@ -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);
index 8f4955c..e45f3ae 100644 (file)
@@ -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);
index f68685a..57f2841 100644 (file)
@@ -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;
            }
 
index 9d10157..c5e40d4 100644 (file)
@@ -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);
     }
index 1e04f54..895d8a9 100644 (file)
--- 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);