summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2014-02-05 20:24:12 (GMT)
committer Aris Adamantiadis <aris@0xbadc0de.be>2014-03-04 08:55:28 (GMT)
commite99246246b4061f7e71463f8806b9dcad65affa0 (patch)
tree3275b977bbb6e88f34a554ec02d7bbe4c4ccbbd8
parentc96e862c0821d4bb0aa2df676c7a8b212cd885b2 (diff)
downloadlibssh-e99246246b4061f7e71463f8806b9dcad65affa0.zip
libssh-e99246246b4061f7e71463f8806b9dcad65affa0.tar.gz
libssh-e99246246b4061f7e71463f8806b9dcad65affa0.tar.bz2
security: fix for vulnerability CVE-2014-0017
When accepting a new connection, a forking server based on libssh forks and the child process handles the request. The RAND_bytes() function of openssl doesn't reset its state after the fork, but simply adds the current process id (getpid) to the PRNG state, which is not guaranteed to be unique. This can cause several children to end up with same PRNG state which is a security issue.
-rw-r--r--include/libssh/wrapper.h1
-rw-r--r--src/bind.c2
-rw-r--r--src/libcrypto.c9
-rw-r--r--src/libgcrypt.c3
4 files changed, 15 insertions, 0 deletions
diff --git a/include/libssh/wrapper.h b/include/libssh/wrapper.h
index 7374a88..e8ff32c 100644
--- a/include/libssh/wrapper.h
+++ b/include/libssh/wrapper.h
@@ -70,5 +70,6 @@ int crypt_set_algorithms_server(ssh_session session);
struct ssh_crypto_struct *crypto_new(void);
void crypto_free(struct ssh_crypto_struct *crypto);
+void ssh_reseed(void);
#endif /* WRAPPER_H_ */
diff --git a/src/bind.c b/src/bind.c
index 8d82d0d..03d3403 100644
--- a/src/bind.c
+++ b/src/bind.c
@@ -458,6 +458,8 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
return SSH_ERROR;
}
}
+ /* force PRNG to change state in case we fork after ssh_bind_accept */
+ ssh_reseed();
return SSH_OK;
}
diff --git a/src/libcrypto.c b/src/libcrypto.c
index bb1d96a..d8cc795 100644
--- a/src/libcrypto.c
+++ b/src/libcrypto.c
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <sys/time.h>
#include "libssh/priv.h"
#include "libssh/session.h"
@@ -38,6 +39,8 @@
#include <openssl/rsa.h>
#include <openssl/hmac.h>
#include <openssl/opensslv.h>
+#include <openssl/rand.h>
+
#ifdef HAVE_OPENSSL_AES_H
#define HAS_AES
#include <openssl/aes.h>
@@ -74,6 +77,12 @@ static int alloc_key(struct ssh_cipher_struct *cipher) {
return 0;
}
+void ssh_reseed(void){
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ RAND_add(&tv, sizeof(tv), 0.0);
+}
+
SHACTX sha1_init(void) {
SHACTX c = malloc(sizeof(*c));
if (c == NULL) {
diff --git a/src/libgcrypt.c b/src/libgcrypt.c
index 899bccd..4617901 100644
--- a/src/libgcrypt.c
+++ b/src/libgcrypt.c
@@ -45,6 +45,9 @@ static int alloc_key(struct ssh_cipher_struct *cipher) {
return 0;
}
+void ssh_reseed(void){
+ }
+
SHACTX sha1_init(void) {
SHACTX ctx = NULL;
gcry_md_open(&ctx, GCRY_MD_SHA1, 0);