From 679539d7ab96f188640d159ea0b004275db67356 Mon Sep 17 00:00:00 2001 From: simon Date: Fri, 19 Dec 2003 12:44:46 +0000 Subject: [PATCH] Joe Yates's memory leak patches. git-svn-id: svn://svn.tartarus.org/sgt/putty@3650 cda61777-01e9-0310-a592-d414129be87e --- cmdline.c | 8 ++++++++ psftp.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ putty.h | 1 + scp.c | 6 ++++++ sftp.c | 8 ++++++++ sftp.h | 5 +++++ ssh.c | 38 +++++++++++++++++++++++++++++++++++++- sshcrcda.c | 7 ++++++- sshrsa.c | 1 + winnet.c | 2 ++ 10 files changed, 118 insertions(+), 8 deletions(-) diff --git a/cmdline.c b/cmdline.c index eb98f606..2a054845 100644 --- a/cmdline.c +++ b/cmdline.c @@ -51,6 +51,14 @@ static void cmdline_save_param(char *p, char *value, int pri) saves[pri].nsaved++; } +void cmdline_cleanup(void) +{ + int pri; + + for (pri = 0; pri < NPRIORITIES; pri++) + sfree(saves[pri].params); +} + #define SAVEABLE(pri) do { \ if (need_save) { cmdline_save_param(p, value, pri); return ret; } \ } while (0) diff --git a/psftp.c b/psftp.c index d395b6f1..28c3dd97 100644 --- a/psftp.c +++ b/psftp.c @@ -25,6 +25,7 @@ static int psftp_connect(char *userhost, char *user, int portnumber); static int do_sftp_init(void); +void do_sftp_cleanup(); /* ---------------------------------------------------------------------- * sftp client state. @@ -1404,8 +1405,8 @@ struct sftp_command *sftp_getcmd(FILE *fp, int mode, int modeflags) */ cmd->nwords = cmd->wordssize = 2; cmd->words = sresize(cmd->words, cmd->wordssize, char *); - cmd->words[0] = "!"; - cmd->words[1] = p+1; + cmd->words[0] = dupstr("!"); + cmd->words[1] = dupstr(p+1); } else { /* @@ -1448,10 +1449,11 @@ struct sftp_command *sftp_getcmd(FILE *fp, int mode, int modeflags) cmd->wordssize = cmd->nwords + 16; cmd->words = sresize(cmd->words, cmd->wordssize, char *); } - cmd->words[cmd->nwords++] = q; + cmd->words[cmd->nwords++] = dupstr(q); } } + sfree(line); /* * Now parse the first word and assign a function. */ @@ -1504,6 +1506,23 @@ static int do_sftp_init(void) return 0; } +void do_sftp_cleanup() +{ + char ch; + back->special(backhandle, TS_EOF); + sftp_recvdata(&ch, 1); + back->free(backhandle); + sftp_cleanup_request(); + if (pwd) { + sfree(pwd); + pwd = NULL; + } + if (homedir) { + sfree(homedir); + homedir = NULL; + } +} + void do_sftp(int mode, int modeflags, char *batchfile) { FILE *fp; @@ -1522,7 +1541,15 @@ void do_sftp(int mode, int modeflags, char *batchfile) cmd = sftp_getcmd(stdin, 0, 0); if (!cmd) break; - if (cmd->obey(cmd) < 0) + ret = cmd->obey(cmd); + if (cmd->words) { + int i; + for(i = 0; i < cmd->nwords; i++) + sfree(cmd->words[i]); + sfree(cmd->words); + } + sfree(cmd); + if (ret < 0) break; } } else { @@ -1908,6 +1935,8 @@ static int psftp_connect(char *userhost, char *user, int portnumber) } if (verbose && realhost != NULL) printf("Connected to %s\n", realhost); + if (realhost != NULL) + sfree(realhost); return 0; } @@ -1993,13 +2022,16 @@ int psftp_main(int argc, char *argv[]) * it now. */ if (userhost) { - if (psftp_connect(userhost, user, portnumber)) + int ret; + ret = psftp_connect(userhost, user, portnumber); + sfree(userhost); + if (ret) return 1; if (do_sftp_init()) return 1; } else { printf("psftp: no hostname specified; use \"open host.name\"" - " to connect\n"); + " to connect\n"); } do_sftp(mode, modeflags, batchfile); @@ -2010,6 +2042,12 @@ int psftp_main(int argc, char *argv[]) sftp_recvdata(&ch, 1); } random_save_seed(); + cmdline_cleanup(); + console_provide_logctx(NULL); + do_sftp_cleanup(); + backhandle = NULL; + back = NULL; + sk_cleanup(); return 0; } diff --git a/putty.h b/putty.h index 60aed037..de1b770b 100644 --- a/putty.h +++ b/putty.h @@ -814,6 +814,7 @@ void printer_finish_job(printer_job *); */ int cmdline_process_param(char *, char *, int, Config *); void cmdline_run_saved(Config *); +void cmdline_cleanup(void); extern char *cmdline_password; #define TOOLTYPE_FILETRANSFER 1 #define TOOLTYPE_NONNETWORK 2 diff --git a/scp.c b/scp.c index 79d3f9ae..5e98536f 100644 --- a/scp.c +++ b/scp.c @@ -2178,6 +2178,12 @@ int psftp_main(int argc, char *argv[]) if (gui_mode) gui_send_errcount(list, errs); + cmdline_cleanup(); + console_provide_logctx(NULL); + back->free(backhandle); + backhandle = NULL; + back = NULL; + sk_cleanup(); return (errs == 0 ? 0 : 1); } diff --git a/sftp.c b/sftp.c index 4d5172b5..66e96b44 100644 --- a/sftp.c +++ b/sftp.c @@ -334,6 +334,14 @@ static struct sftp_request *sftp_alloc_request(void) return r; } +void sftp_cleanup_request(void) +{ + if (sftp_requests == NULL) { + freetree234(sftp_requests); + sftp_requests = NULL; + } +} + void sftp_register(struct sftp_request *req) { req->registered = 1; diff --git a/sftp.h b/sftp.h index 54d91af2..031aea27 100644 --- a/sftp.h +++ b/sftp.h @@ -67,6 +67,11 @@ int sftp_senddata(char *data, int len); int sftp_recvdata(char *data, int len); +/* + * Free sftp_requests + */ +void sftp_cleanup_request(void); + struct fxp_attrs { unsigned long flags; uint64 size; diff --git a/ssh.c b/ssh.c index d83d0c10..1d887230 100644 --- a/ssh.c +++ b/ssh.c @@ -2535,6 +2535,22 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) ssh->crcda_ctx = crcda_make_context(); logevent("Installing CRC compensation attack detector"); + if (servkey.modulus) { + sfree(servkey.modulus); + servkey.modulus = NULL; + } + if (servkey.exponent) { + sfree(servkey.exponent); + servkey.exponent = NULL; + } + if (hostkey.modulus) { + sfree(hostkey.modulus); + hostkey.modulus = NULL; + } + if (hostkey.exponent) { + sfree(hostkey.exponent); + hostkey.exponent = NULL; + } crWaitUntil(ispkt); if (ssh->pktin.type != SSH1_SMSG_SUCCESS) { @@ -3037,6 +3053,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) } logevent("Sending password with camouflage packets"); ssh_pkt_defersend(ssh); + sfree(randomstr); } else if (!(ssh->remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) { /* @@ -4338,6 +4355,10 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt) if (ssh->sccomp->text_name) logeventf(ssh, "Initialised %s decompression", ssh->sccomp->text_name); + freebn(s->f); + freebn(s->g); + freebn(s->K); + freebn(s->p); /* * If this is the first key exchange phase, we must pass the @@ -6278,7 +6299,22 @@ static void ssh_free(void *handle) sfree(ssh->do_ssh1_login_state); sfree(ssh->do_ssh2_transport_state); sfree(ssh->do_ssh2_authconn_state); - + if (ssh->pktout.data) { + sfree(ssh->pktout.data); + ssh->pktout.data = NULL; + } + if (ssh->pktin.data) { + sfree(ssh->pktin.data); + ssh->pktin.data = NULL; + } + if (ssh->crcda_ctx) { + crcda_free_context(ssh->crcda_ctx); + ssh->crcda_ctx = NULL; + } + if (ssh->logctx) { + log_free(ssh->logctx); + ssh->logctx = NULL; + } if (ssh->s) ssh_do_close(ssh); sfree(ssh); diff --git a/sshcrcda.c b/sshcrcda.c index 7fb5767c..09e5f8d0 100644 --- a/sshcrcda.c +++ b/sshcrcda.c @@ -71,7 +71,12 @@ void *crcda_make_context(void) void crcda_free_context(void *handle) { - sfree(handle); + struct crcda_ctx *ctx = (struct crcda_ctx *)handle; + if (ctx) { + sfree(ctx->h); + ctx->h = NULL; + sfree(ctx); + } } static void crc_update(uint32 *a, void *b) diff --git a/sshrsa.c b/sshrsa.c index 58755089..a735517f 100644 --- a/sshrsa.c +++ b/sshrsa.c @@ -738,6 +738,7 @@ static int rsa2_verifysig(void *key, char *sig, int siglen, if (bignum_byte(out, i) != hash[j]) ret = 0; } + freebn(out); return ret; } diff --git a/winnet.c b/winnet.c index 81885c66..8be2cd17 100644 --- a/winnet.c +++ b/winnet.c @@ -237,6 +237,8 @@ void sk_cleanup(void) for (i = 0; (s = index234(sktree, i)) != NULL; i++) { p_closesocket(s->s); } + freetree234(sktree); + sktree = NULL; } p_WSACleanup(); -- 2.11.0