1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-08 08:58:00 +00:00

userauth2: add a missing free_prompts().

If a userauth layer is destroyed while userpass input is still
ongoing, ssh2_userauth_free forgot to free the active prompts_t,
leaking memory.

But adding the missing free_prompts call to ssh2_userauth_free results
in a double-free, because another thing I forgot was to null out that
pointer field everywhere _else_ it's freed. Fixed that too.
This commit is contained in:
Simon Tatham 2021-09-16 09:27:25 +01:00
parent 99b4229abf
commit 7a02234353

View File

@ -193,6 +193,8 @@ static void ssh2_userauth_free(PacketProtocolLayer *ppl)
sfree(s->locally_allocated_username);
sfree(s->hostname);
sfree(s->fullhostname);
if (s->cur_prompt)
free_prompts(s->cur_prompt);
sfree(s->publickey_comment);
sfree(s->publickey_algorithm);
if (s->publickey_blob)
@ -455,6 +457,7 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
* Terminate.
*/
free_prompts(s->cur_prompt);
s->cur_prompt = NULL;
ssh_user_close(s->ppl.ssh, "No username provided");
return;
}
@ -462,6 +465,7 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
s->username = s->locally_allocated_username =
prompt_get_result(s->cur_prompt->prompts[0]);
free_prompts(s->cur_prompt);
s->cur_prompt = NULL;
} else {
if (seat_verbose(s->ppl.seat) || seat_interactive(s->ppl.seat))
ppl_printf("Using username \"%s\".\r\n", s->username);
@ -918,6 +922,7 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
if (!s->userpass_ret) {
/* Failed to get a passphrase. Terminate. */
free_prompts(s->cur_prompt);
s->cur_prompt = NULL;
ssh_bpp_queue_disconnect(
s->ppl.bpp, "Unable to authenticate",
SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
@ -928,6 +933,7 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
passphrase =
prompt_get_result(s->cur_prompt->prompts[0]);
free_prompts(s->cur_prompt);
s->cur_prompt = NULL;
} else {
passphrase = NULL; /* no passphrase needed */
}
@ -1397,6 +1403,7 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
* Failed to get responses. Terminate.
*/
free_prompts(s->cur_prompt);
s->cur_prompt = NULL;
ssh_bpp_queue_disconnect(
s->ppl.bpp, "Unable to authenticate",
SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
@ -1424,6 +1431,7 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
* when we return to the top of this while loop.
*/
free_prompts(s->cur_prompt);
s->cur_prompt = NULL;
/*
* Get the next packet in case it's another
@ -1476,6 +1484,7 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
* Failed to get responses. Terminate.
*/
free_prompts(s->cur_prompt);
s->cur_prompt = NULL;
ssh_bpp_queue_disconnect(
s->ppl.bpp, "Unable to authenticate",
SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
@ -1489,6 +1498,7 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
*/
s->password = prompt_get_result(s->cur_prompt->prompts[0]);
free_prompts(s->cur_prompt);
s->cur_prompt = NULL;
/*
* Send the password packet.
@ -1587,6 +1597,7 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
*/
/* burn the evidence */
free_prompts(s->cur_prompt);
s->cur_prompt = NULL;
smemclr(s->password, strlen(s->password));
sfree(s->password);
ssh_bpp_queue_disconnect(
@ -1638,6 +1649,7 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
put_stringz(s->pktout, prompt_get_result_ref(
s->cur_prompt->prompts[1]));
free_prompts(s->cur_prompt);
s->cur_prompt = NULL;
s->pktout->minlen = 256;
pq_push(s->ppl.out_pq, s->pktout);
ppl_logevent("Sent new password");