diff options
author | Jon Simons <jon@jonsimons.org> | 2014-01-15 13:50:15 -0800 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2014-01-16 09:27:41 +0100 |
commit | 6007c3c43f7256698ed7ed62d13a588ee355daee (patch) | |
tree | 15ae3d45d0b88c77011e6e08791504fbb33d6e9a | |
parent | 9d1ddd0547452f44ad9c5517c0e1e095e1a1f4e7 (diff) | |
download | libssh-6007c3c43f7256698ed7ed62d13a588ee355daee.tar.gz libssh-6007c3c43f7256698ed7ed62d13a588ee355daee.tar.xz libssh-6007c3c43f7256698ed7ed62d13a588ee355daee.zip |
bind: fix possible double-frees in ssh_bind_free
Make sure to explicitly set key pointers to NULL following the use
of 'ssh_key_free' throughout bind.c.
Before this change, a double free can happen via 'ssh_bind_free'
as in this example callpath:
// create an ssh_bind
ssh_bind b = ssh_bind_new();
// provide a path to a wrong key-type
ssh_bind_options_set(b, SSH_BIND_OPTIONS_DSAKEY, path_to_rsa_key);
// initialize set key-type
ssh_bind_listen(b);
-> error path "The DSA host key has the wrong type: %d",
ssh_key_free(sshbind->dsa)
-> ssh_key_clean(key) // OK
-> SAFE_FREE(key) // OK, but, sshbind->dsa is *not* set to NULL
// ssh_bind_listen failed, so clean up ssh_bind
ssh_bind_free(b);
-> ssh_key_free(sshbind->dsa) // double-free here
To fix, set pointers to NULL that have been free'd with 'ssh_key_free'.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
-rw-r--r-- | src/bind.c | 10 |
1 files changed, 10 insertions, 0 deletions
@@ -179,6 +179,7 @@ int ssh_bind_listen(ssh_bind sshbind) { ssh_set_error(sshbind, SSH_FATAL, "The ECDSA host key has the wrong type"); ssh_key_free(sshbind->ecdsa); + sshbind->ecdsa = NULL; return SSH_ERROR; } } @@ -201,6 +202,7 @@ int ssh_bind_listen(ssh_bind sshbind) { "The DSA host key has the wrong type: %d", ssh_key_type(sshbind->dsa)); ssh_key_free(sshbind->dsa); + sshbind->dsa = NULL; return SSH_ERROR; } } @@ -222,6 +224,7 @@ int ssh_bind_listen(ssh_bind sshbind) { ssh_set_error(sshbind, SSH_FATAL, "The RSA host key has the wrong type"); ssh_key_free(sshbind->rsa); + sshbind->rsa = NULL; return SSH_ERROR; } } @@ -235,7 +238,9 @@ int ssh_bind_listen(ssh_bind sshbind) { fd = bind_socket(sshbind, host, sshbind->bindport); if (fd == SSH_INVALID_SOCKET) { ssh_key_free(sshbind->dsa); + sshbind->dsa = NULL; ssh_key_free(sshbind->rsa); + sshbind->rsa = NULL; return -1; } sshbind->bindfd = fd; @@ -246,7 +251,9 @@ int ssh_bind_listen(ssh_bind sshbind) { fd, strerror(errno)); close(fd); ssh_key_free(sshbind->dsa); + sshbind->dsa = NULL; ssh_key_free(sshbind->rsa); + sshbind->rsa = NULL; return -1; } } else { @@ -348,8 +355,11 @@ void ssh_bind_free(ssh_bind sshbind){ SAFE_FREE(sshbind->ecdsakey); ssh_key_free(sshbind->dsa); + sshbind->dsa = NULL; ssh_key_free(sshbind->rsa); + sshbind->rsa = NULL; ssh_key_free(sshbind->ecdsa); + sshbind->ecdsa = NULL; for (i = 0; i < 10; i++) { if (sshbind->wanted_methods[i]) { |