mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-08 11:53:00 -04:00
Try /proc on Linux as entropy fallback; use sysctl as last resort
It turns out that the happy fun Linux kernel is deprecating sysctl, and using sysctl to fetch entropy will spew messages in the kernel logs. Let's not do that. Instead, let's call sysctl for our entropy only when all other means fail. Additionally, let's add another means, and try /proc/sys/kernel/random/uuid if /dev/urandom fails.
This commit is contained in:
parent
71afc52580
commit
20fda296c5
59
arc4random.c
59
arc4random.c
@ -201,6 +201,49 @@ arc4_seed_sysctl_linux(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#define TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID
|
||||
static int
|
||||
arc4_seed_proc_sys_kernel_random_uuid(void)
|
||||
{
|
||||
/* Occasionally, somebody will make /proc/sys accessible in a chroot,
|
||||
* but not /dev/urandom. Let's try /proc/sys/kernel/random/uuid.
|
||||
* Its format is stupid, so we need to decode it from hex.
|
||||
*/
|
||||
int fd;
|
||||
char buf[128];
|
||||
unsigned char entropy[64];
|
||||
int bytes, n, i, nybbles;
|
||||
for (bytes = 0; bytes<ADD_ENTROPY; ) {
|
||||
fd = open("/proc/sys/kernel/random/uuid", O_RDONLY, 0);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
n = read(fd, buf, sizeof(buf));
|
||||
close(fd);
|
||||
if (n<=0)
|
||||
return -1;
|
||||
memset(entropy, 0, sizeof(entropy));
|
||||
for (i=nybbles=0; i<n; ++i) {
|
||||
if (EVUTIL_ISXDIGIT(buf[i])) {
|
||||
int nyb = evutil_hex_char_to_int(buf[i]);
|
||||
if (nybbles & 1) {
|
||||
entropy[nybbles/2] |= nyb;
|
||||
} else {
|
||||
entropy[nybbles/2] |= nyb<<4;
|
||||
}
|
||||
++nybbles;
|
||||
}
|
||||
}
|
||||
if (nybbles < 2)
|
||||
return -1;
|
||||
arc4_addrandom(entropy, nybbles/2);
|
||||
bytes += nybbles/2;
|
||||
}
|
||||
memset(entropy, 0, sizeof(entropy));
|
||||
memset(buf, 0, sizeof(buf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if _EVENT_HAVE_DECL_CTL_KERN && _EVENT_HAVE_DECL_KERN_ARND
|
||||
#define TRY_SEED_SYSCTL_BSD
|
||||
static int
|
||||
@ -284,17 +327,23 @@ arc4_seed(void)
|
||||
if (0 == arc4_seed_win32())
|
||||
ok = 1;
|
||||
#endif
|
||||
#ifdef TRY_SEED_URANDOM
|
||||
if (0 == arc4_seed_urandom())
|
||||
ok = 1;
|
||||
#endif
|
||||
#define TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID
|
||||
if (0 == arc4_seed_proc_sys_kernel_random_uuid())
|
||||
ok = 1;
|
||||
#endif
|
||||
#ifdef TRY_SEED_SYSCTL_LINUX
|
||||
if (0 == arc4_seed_sysctl_linux())
|
||||
/* Apparently Linux is deprecating sysctl, and spewing warning
|
||||
* messages when you try to use it. */
|
||||
if (!ok && 0 == arc4_seed_sysctl_linux())
|
||||
ok = 1;
|
||||
#endif
|
||||
#ifdef TRY_SEED_SYSCTL_BSD
|
||||
if (0 == arc4_seed_sysctl_bsd())
|
||||
ok = 1;
|
||||
#endif
|
||||
#ifdef TRY_SEED_URANDOM
|
||||
if (0 == arc4_seed_urandom())
|
||||
ok = 1;
|
||||
#endif
|
||||
return ok ? 0 : -1;
|
||||
}
|
||||
|
24
evutil.c
24
evutil.c
@ -1946,3 +1946,27 @@ evutil_tv_to_msec(const struct timeval *tv)
|
||||
return (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000);
|
||||
}
|
||||
|
||||
int
|
||||
evutil_hex_char_to_int(char c)
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case '0': return 0;
|
||||
case '1': return 1;
|
||||
case '2': return 2;
|
||||
case '3': return 3;
|
||||
case '4': return 4;
|
||||
case '5': return 5;
|
||||
case '6': return 6;
|
||||
case '7': return 7;
|
||||
case '8': return 8;
|
||||
case '9': return 9;
|
||||
case 'A': case 'a': return 10;
|
||||
case 'B': case 'b': return 11;
|
||||
case 'C': case 'c': return 12;
|
||||
case 'D': case 'd': return 13;
|
||||
case 'E': case 'e': return 14;
|
||||
case 'F': case 'f': return 15;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -223,6 +223,8 @@ const char *evutil_format_sockaddr_port(const struct sockaddr *sa, char *out, si
|
||||
|
||||
long evutil_tv_to_msec(const struct timeval *tv);
|
||||
|
||||
int evutil_hex_char_to_int(char c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user