1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2026-10-24 03:48:55 +03:00

CVE-2026-59849 auth: Fix state machine to aovid infinite loop

After going through the whole list of certificates, the iterator was
set to NULL and at the beginning of the next loop reset to the start
of the list again, which caused infinite loop.

Adding one more intermediate state solves the issue.

Found by AISLE in partnership with Red Hat

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Pavol Žáčik <pzacik@redhat.com>
This commit is contained in:
Jakub Jelen
2026-05-26 12:13:47 +02:00
parent bb96432364
commit bcfa191283

View File

@@ -1451,6 +1451,7 @@ enum ssh_auth_auto_state_e {
SSH_AUTH_AUTO_STATE_PUBKEY,
SSH_AUTH_AUTO_STATE_KEY_IMPORTED,
SSH_AUTH_AUTO_STATE_CERTIFICATE_FILE,
SSH_AUTH_AUTO_STATE_CERTIFICATE_OPTION_INIT,
SSH_AUTH_AUTO_STATE_CERTIFICATE_OPTION,
SSH_AUTH_AUTO_STATE_PUBKEY_ACCEPTED
};
@@ -1682,6 +1683,7 @@ int ssh_userauth_publickey_auto(ssh_session session,
}
if (state->state == SSH_AUTH_AUTO_STATE_KEY_IMPORTED ||
state->state == SSH_AUTH_AUTO_STATE_CERTIFICATE_FILE ||
state->state == SSH_AUTH_AUTO_STATE_CERTIFICATE_OPTION_INIT ||
state->state == SSH_AUTH_AUTO_STATE_CERTIFICATE_OPTION) {
ssh_key k = state->pubkey;
if (state->state != SSH_AUTH_AUTO_STATE_KEY_IMPORTED) {
@@ -1732,14 +1734,15 @@ int ssh_userauth_publickey_auto(ssh_session session,
continue;
}
/* if the file does not exists, try configuration options */
state->state = SSH_AUTH_AUTO_STATE_CERTIFICATE_OPTION;
state->state = SSH_AUTH_AUTO_STATE_CERTIFICATE_OPTION_INIT;
}
/* Try certificate files loaded through options */
if (state->state == SSH_AUTH_AUTO_STATE_CERTIFICATE_OPTION_INIT) {
state->cert_it = ssh_list_get_iterator(session->opts.certificate);
state->state = SSH_AUTH_AUTO_STATE_CERTIFICATE_OPTION;
}
if (state->state == SSH_AUTH_AUTO_STATE_CERTIFICATE_OPTION) {
SSH_KEY_FREE(state->cert);
if (state->cert_it == NULL) {
state->cert_it = ssh_list_get_iterator(session->opts.certificate);
}
while (state->cert_it != NULL) {
const char *cert_file = state->cert_it->data;
ssh_key cert = NULL;