"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/lib/randgen.c" between
dovecot-2.3.16.tar.gz and dovecot-2.3.17.tar.gz

About: Dovecot is an IMAP and POP3 server, written with security primarily in mind.

randgen.c  (dovecot-2.3.16):randgen.c  (dovecot-2.3.17)
skipping to change at line 64 skipping to change at line 64
# define USE_ARC4RANDOM # define USE_ARC4RANDOM
#else #else
static bool getrandom_present = FALSE; static bool getrandom_present = FALSE;
# define USE_RANDOM_DEV # define USE_RANDOM_DEV
#endif #endif
static int init_refcount = 0; static int init_refcount = 0;
static int urandom_fd = -1; static int urandom_fd = -1;
#if defined(USE_GETRANDOM) || defined(USE_RANDOM_DEV) #if defined(USE_GETRANDOM) || defined(USE_RANDOM_DEV)
/* Use a small buffer when reading randomness. This is mainly to make small
random reads more efficient, such as i_rand*(). When reading larger amount
of randomness this buffer is bypassed.
There doesn't seem to be a big difference in Linux system CPU usage when
buffer size is above 16 bytes. Double it just to be safe. Avoid it being
too large anyway so we don't unnecessarily waste CPU and memory. */
#define RANDOM_READ_BUFFER_SIZE 32
static unsigned char random_next[RANDOM_READ_BUFFER_SIZE];
static size_t random_next_pos = 0;
static size_t random_next_size = 0;
static void random_open_urandom(void) static void random_open_urandom(void)
{ {
urandom_fd = open(DEV_URANDOM_PATH, O_RDONLY); urandom_fd = open(DEV_URANDOM_PATH, O_RDONLY);
if (urandom_fd == -1) { if (urandom_fd == -1) {
if (errno == ENOENT) { if (errno == ENOENT) {
i_fatal("open("DEV_URANDOM_PATH") failed: doesn't exist," i_fatal("open("DEV_URANDOM_PATH") failed: doesn't exist,"
"currently we require it"); "currently we require it");
} else { } else {
i_fatal("open("DEV_URANDOM_PATH") failed: %m"); i_fatal("open("DEV_URANDOM_PATH") failed: %m");
} }
} }
fd_close_on_exec(urandom_fd, TRUE); fd_close_on_exec(urandom_fd, TRUE);
} }
static inline int random_read(char *buf, size_t size) static inline int random_read(unsigned char *buf, size_t size)
{ {
ssize_t ret = 0; ssize_t ret = 0;
# if defined(USE_GETRANDOM) # if defined(USE_GETRANDOM)
if (getrandom_present) { if (getrandom_present) {
ret = getrandom(buf, size, 0); ret = getrandom(buf, size, 0);
if (ret < 0 && errno == ENOSYS) { if (ret < 0 && errno == ENOSYS) {
getrandom_present = FALSE; getrandom_present = FALSE;
/* It gets complicated here... While the libc (and its /* It gets complicated here... While the libc (and its
headers) indicated that getrandom() was available when headers) indicated that getrandom() was available when
we were compiled, the kernel disagreed just now at we were compiled, the kernel disagreed just now at
skipping to change at line 135 skipping to change at line 147
} }
#endif #endif
#if defined(USE_ARC4RANDOM) #if defined(USE_ARC4RANDOM)
arc4random_buf(buf, size); arc4random_buf(buf, size);
#else #else
size_t pos; size_t pos;
ssize_t ret; ssize_t ret;
for (pos = 0; pos < size; ) { for (pos = 0; pos < size; ) {
ret = random_read(PTR_OFFSET(buf, pos), size - pos); if (size >= sizeof(random_next) && random_next_size == 0) {
if (ret > -1) /* Asking for lots of randomness. Read directly to the
pos += ret; destination buffer. */
ret = random_read(PTR_OFFSET(buf, pos), size - pos);
if (ret > -1)
pos += ret;
} else {
/* Asking for a little randomness. Read via a larger
buffer to reduce the number of syscalls. */
if (random_next_size > random_next_pos)
ret = random_next_size - random_next_pos;
else {
random_next_pos = 0;
ret = random_read(random_next,
sizeof(random_next));
random_next_size = ret < 0 ? 0 : ret;
}
if (ret > 0) {
size_t used = I_MIN(size - pos, (size_t)ret);
memcpy(PTR_OFFSET(buf, pos),
random_next + random_next_pos, used);
random_next_pos += used;
pos += used;
}
}
} }
#endif /* defined(USE_ARC4RANDOM) */ #endif /* defined(USE_ARC4RANDOM) */
} }
void random_init(void) void random_init(void)
{ {
/* static analyzer seems to require this */ /* static analyzer seems to require this */
unsigned int seed = 0; unsigned int seed = 0;
const char *env_seed; const char *env_seed;
 End of changes. 3 change blocks. 
4 lines changed or deleted 38 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)