diff options
author | lloyd <[email protected]> | 2013-11-08 19:20:24 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2013-11-08 19:20:24 +0000 |
commit | 699bb445ebcc9ec911a365e03e20e1cbaad15087 (patch) | |
tree | 8e4a097a0dd17a83575ce8f89885d6955d11e372 /src | |
parent | 79400f7b5add9dd0218ff3a127356add4a1bebca (diff) |
Simplify device opening, and avoid leaking a file descriptor if it was
too large to fit in an fd_set.
Read at least 128 bits even if the poll is asking for less.
Diffstat (limited to 'src')
-rw-r--r-- | src/entropy/dev_random/dev_random.cpp | 32 |
1 files changed, 14 insertions, 18 deletions
diff --git a/src/entropy/dev_random/dev_random.cpp b/src/entropy/dev_random/dev_random.cpp index bfa0d76f3..37690b06b 100644 --- a/src/entropy/dev_random/dev_random.cpp +++ b/src/entropy/dev_random/dev_random.cpp @@ -6,6 +6,7 @@ */ #include <botan/internal/dev_random.h> +#include <botan/internal/rounding.h> #include <sys/types.h> #include <sys/select.h> @@ -16,9 +17,11 @@ namespace Botan { -namespace { - -int open_nonblocking(const char* pathname) +/** +Device_EntropySource constructor +Open a file descriptor to each (available) device in fsnames +*/ +Device_EntropySource::Device_EntropySource(const std::vector<std::string>& fsnames) { #ifndef O_NONBLOCK #define O_NONBLOCK 0 @@ -29,22 +32,15 @@ int open_nonblocking(const char* pathname) #endif const int flags = O_RDONLY | O_NONBLOCK | O_NOCTTY; - return ::open(pathname, flags); - } -} - -/** -Device_EntropySource constructor -Open a file descriptor to each (available) device in fsnames -*/ -Device_EntropySource::Device_EntropySource(const std::vector<std::string>& fsnames) - { - for(size_t i = 0; i != fsnames.size(); ++i) + for(auto fsname : fsnames) { - fd_type fd = open_nonblocking(fsnames[i].c_str()); + fd_type fd = ::open(fsname.c_str(), flags); + if(fd >= 0 && fd < FD_SETSIZE) devices.push_back(fd); + else if(fd >= 0) + ::close(fd); } } @@ -67,9 +63,7 @@ void Device_EntropySource::poll(Entropy_Accumulator& accum) const size_t ENTROPY_BITS_PER_BYTE = 8; const size_t MS_WAIT_TIME = 32; - const size_t READ_ATTEMPT = accum.desired_remaining_bits() / 4; - - secure_vector<byte>& io_buffer = accum.get_io_buffer(READ_ATTEMPT); + const size_t READ_ATTEMPT = std::min<size_t>(accum.desired_remaining_bits() / 8, 16); int max_fd = devices[0]; fd_set read_set; @@ -88,6 +82,8 @@ void Device_EntropySource::poll(Entropy_Accumulator& accum) if(::select(max_fd + 1, &read_set, 0, 0, &timeout) < 0) return; + secure_vector<byte>& io_buffer = accum.get_io_buffer(READ_ATTEMPT); + for(size_t i = 0; i != devices.size(); ++i) { if(FD_ISSET(devices[i], &read_set)) |