1
1

auth: Cleanup memory leak when using SSH agent

In Cockpit we've seen this memory leak:

at 0x4C2A9C7: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x5B76B03: ssh_userauth_agent (auth.c:778)
by 0x40DD5A: cockpit_ssh_authenticate (cockpitsshtransport.c:327)

BUG: https://red.libssh.org/issues/208

Signed-off-by: Stef Walter <stefw@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Этот коммит содержится в:
Stef Walter 2015-11-10 12:18:30 +01:00 коммит произвёл Andreas Schneider
родитель aa5c7c3b0c
Коммит ffe8b98cc2
3 изменённых файлов: 25 добавлений и 7 удалений

Просмотреть файл

@ -361,5 +361,7 @@ int match_hostname(const char *host, const char *pattern, unsigned int len);
#define CLOSE_SOCKET(s) do { if ((s) != SSH_INVALID_SOCKET) { _XCLOSESOCKET(s); (s) = SSH_INVALID_SOCKET;} } while(0)
void ssh_agent_state_free(void *data);
#endif /* _LIBSSH_PRIV_H */
/* vim: set ts=4 sw=4 et cindent: */

Просмотреть файл

@ -745,6 +745,15 @@ struct ssh_agent_state_struct {
char *comment;
};
/* Internal function */
void ssh_agent_state_free(void *data) {
struct ssh_agent_state_struct *state = data;
if (state) {
ssh_string_free_char(state->comment);
ssh_key_free(state->pubkey);
free (state);
}
}
/**
* @brief Try to do public key authentication with ssh agent.
@ -805,9 +814,8 @@ int ssh_userauth_agent(ssh_session session,
state->state == SSH_AGENT_STATE_PUBKEY){
rc = ssh_userauth_try_publickey(session, username, state->pubkey);
if (rc == SSH_AUTH_ERROR) {
ssh_string_free_char(state->comment);
ssh_key_free(state->pubkey);
SAFE_FREE(session->agent_state);
ssh_agent_state_free (state);
session->agent_state = NULL;
return rc;
} else if (rc == SSH_AUTH_AGAIN) {
state->state = SSH_AGENT_STATE_PUBKEY;
@ -816,6 +824,7 @@ int ssh_userauth_agent(ssh_session session,
SSH_LOG(SSH_LOG_DEBUG,
"Public key of %s refused by server", state->comment);
ssh_string_free_char(state->comment);
state->comment = NULL;
ssh_key_free(state->pubkey);
state->pubkey = ssh_agent_get_next_ident(session, &state->comment);
state->state = SSH_AGENT_STATE_NONE;
@ -831,23 +840,27 @@ int ssh_userauth_agent(ssh_session session,
if (rc == SSH_AUTH_AGAIN)
return rc;
ssh_string_free_char(state->comment);
ssh_key_free(state->pubkey);
state->comment = NULL;
if (rc == SSH_AUTH_ERROR) {
SAFE_FREE(session->agent_state);
ssh_agent_state_free (session->agent_state);
session->agent_state = NULL;
return rc;
} else if (rc != SSH_AUTH_SUCCESS) {
SSH_LOG(SSH_LOG_INFO,
"Server accepted public key but refused the signature");
ssh_key_free(state->pubkey);
state->pubkey = ssh_agent_get_next_ident(session, &state->comment);
state->state = SSH_AGENT_STATE_NONE;
continue;
}
SAFE_FREE(session->agent_state);
ssh_agent_state_free (session->agent_state);
session->agent_state = NULL;
return SSH_AUTH_SUCCESS;
}
}
SAFE_FREE(session->agent_state);
ssh_agent_state_free (session->agent_state);
session->agent_state = NULL;
return rc;
}
#endif

Просмотреть файл

@ -261,6 +261,9 @@ void ssh_free(ssh_session session) {
ssh_list_free(session->opts.identity);
}
ssh_agent_state_free (session->agent_state);
session->agent_state = NULL;
SAFE_FREE(session->auth_auto_state);
SAFE_FREE(session->serverbanner);
SAFE_FREE(session->clientbanner);