1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-02-03 21:52:24 +00:00

Fix freeing of retkey in openssh_new_read.

Now it's always freed in the cleanup epilogue (unless we're returning
it), rather than ad-hoc earlier in the code. That should make it more
reliably freed on error paths.
This commit is contained in:
Simon Tatham 2017-02-14 21:31:12 +00:00
parent 12a080874f
commit b03020cab9

View File

@ -1543,7 +1543,7 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
const char **errmsg_p) const char **errmsg_p)
{ {
struct openssh_new_key *key = load_openssh_new_key(filename, errmsg_p); struct openssh_new_key *key = load_openssh_new_key(filename, errmsg_p);
struct ssh2_userkey *retkey; struct ssh2_userkey *retkey = NULL;
int i; int i;
struct ssh2_userkey *retval = NULL; struct ssh2_userkey *retval = NULL;
const char *errmsg; const char *errmsg;
@ -1552,7 +1552,7 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
unsigned checkint0, checkint1; unsigned checkint0, checkint1;
const void *priv, *string; const void *priv, *string;
int privlen, stringlen, key_index; int privlen, stringlen, key_index;
const struct ssh_signkey *alg; const struct ssh_signkey *alg = NULL;
blob = NULL; blob = NULL;
@ -1678,10 +1678,10 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
(const unsigned char *)thiskey); (const unsigned char *)thiskey);
if (key_index == key->key_wanted) { if (key_index == key->key_wanted) {
retkey = snew(struct ssh2_userkey); retkey = snew(struct ssh2_userkey);
retkey->comment = NULL;
retkey->alg = alg; retkey->alg = alg;
retkey->data = alg->openssh_createkey(alg, &thiskey, &thiskeylen); retkey->data = alg->openssh_createkey(alg, &thiskey, &thiskeylen);
if (!retkey->data) { if (!retkey->data) {
sfree(retkey);
errmsg = "unable to create key data structure"; errmsg = "unable to create key data structure";
goto error; goto error;
} }
@ -1718,12 +1718,21 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
errmsg = NULL; /* no error */ errmsg = NULL; /* no error */
retval = retkey; retval = retkey;
retkey = NULL; /* prevent the free */
error: error:
if (blob) { if (blob) {
smemclr(blob, blobsize); smemclr(blob, blobsize);
sfree(blob); sfree(blob);
} }
if (retkey) {
sfree(retkey->comment);
if (retkey->data) {
assert(alg);
alg->freekey(retkey->data);
}
sfree(retkey);
}
smemclr(key->keyblob, key->keyblob_size); smemclr(key->keyblob, key->keyblob_size);
sfree(key->keyblob); sfree(key->keyblob);
smemclr(key, sizeof(*key)); smemclr(key, sizeof(*key));