fix some kex-related leaks

This commit is contained in:
Damien Miller
2012-03-05 18:04:51 +11:00
committed by Markus Friedl
parent 06cbafed01
commit 4a3c3a7baf
5 changed files with 57 additions and 3 deletions

View File

@@ -310,9 +310,42 @@ kex_new(struct ssh *ssh, char *proposal[PROPOSAL_MAX], Kex **kexp)
return r;
}
void
kex_free_newkeys(Newkeys *newkeys)
{
if (newkeys == NULL)
return;
if (newkeys->enc.key) {
bzero(newkeys->enc.key, newkeys->enc.key_len);
free(newkeys->enc.key);
newkeys->enc.key = NULL;
}
if (newkeys->enc.iv) {
bzero(newkeys->enc.iv, newkeys->enc.block_size);
free(newkeys->enc.iv);
newkeys->enc.iv = NULL;
}
free(newkeys->enc.name);
bzero(&newkeys->enc, sizeof(newkeys->enc));
free(newkeys->comp.name);
bzero(&newkeys->comp, sizeof(newkeys->comp));
mac_clear(&newkeys->mac);
if (newkeys->mac.key) {
bzero(newkeys->mac.key, newkeys->mac.key_len);
free(newkeys->mac.key);
newkeys->mac.key = NULL;
}
free(newkeys->mac.name);
bzero(&newkeys->mac, sizeof(newkeys->mac));
bzero(newkeys, sizeof(*newkeys));
free(newkeys);
}
void
kex_free(Kex *kex)
{
u_int mode;
if (kex->peer != NULL)
sshbuf_free(kex->peer);
if (kex->my != NULL)
@@ -321,6 +354,10 @@ kex_free(Kex *kex)
DH_free(kex->dh);
if (kex->ec_client_key)
EC_KEY_free(kex->ec_client_key);
for (mode = 0; mode < MODE_MAX; mode++) {
kex_free_newkeys(kex->newkeys[mode]);
kex->newkeys[mode] = NULL;
}
free(kex);
}
@@ -610,7 +647,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
r = 0;
out:
if (digest)
free (digest);
free(digest);
if (b)
sshbuf_free(b);
return r;
@@ -635,6 +672,7 @@ kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,
}
}
for (mode = 0; mode < MODE_MAX; mode++) {
kex_free_newkeys(ssh->current_keys[mode]);
ssh->current_keys[mode] = kex->newkeys[mode];
kex->newkeys[mode] = NULL;
ctos = (!kex->server && mode == MODE_OUT) ||

View File

@@ -137,6 +137,7 @@ int kex_names_valid(const char *);
int kex_new(struct ssh *, char *[PROPOSAL_MAX], Kex **);
int kex_setup(struct ssh *, char *[PROPOSAL_MAX]);
void kex_free_newkeys(Newkeys *);
void kex_free(Kex *);
int kex_buf2prop(struct sshbuf *, int *, char ***);

View File

@@ -530,6 +530,7 @@ ssh_packet_close(struct ssh *ssh)
{
struct session_state *state = ssh->state;
int r;
u_int mode;
if (!state->initialized)
return;
@@ -545,6 +546,8 @@ ssh_packet_close(struct ssh *ssh)
sshbuf_free(state->output);
sshbuf_free(state->outgoing_packet);
sshbuf_free(state->incoming_packet);
for (mode = 0; mode < MODE_MAX; mode++)
kex_free_newkeys(state->newkeys[mode]);
if (state->compression_buffer) {
sshbuf_free(state->compression_buffer);
if (ssh->state->compression_out_started) {

View File

@@ -96,9 +96,15 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params)
void
ssh_free(struct ssh *ssh)
{
u_int mode;
ssh_packet_close(ssh);
if (ssh->kex);
if (ssh->kex)
kex_free(ssh->kex);
for (mode = 0; mode < MODE_MAX; mode++) {
kex_free_newkeys(ssh->current_keys[mode]);
ssh->current_keys[mode] = NULL;
}
free(ssh);
}

View File

@@ -101,7 +101,7 @@ do_kex_with_key(char *kex, int key_type, int bits)
ASSERT_INT_EQ(ssh_add_hostkey(client, public), 0);
TEST_DONE();
TEST_START(kex);
TEST_START("kex");
run_kex(client, server);
TEST_DONE();
@@ -148,6 +148,12 @@ do_kex_with_key(char *kex, int key_type, int bits)
ASSERT_INT_EQ(kex_send_kexinit(client), 0);
run_kex(client, server2);
TEST_DONE();
TEST_START("cleanup");
ssh_free(client);
ssh_free(server);
ssh_free(server2);
TEST_DONE();
}
static void