mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
util: make use of the new getrandom() syscall if it is available when needing entropy
Doesn't require an fd, and could be a bit faster, so let's make use of it, if it is available.
This commit is contained in:
parent
d0159fdc7a
commit
539618a0dd
@ -308,7 +308,7 @@ LIBS="$save_LIBS"
|
||||
|
||||
AC_CHECK_FUNCS([memfd_create])
|
||||
AC_CHECK_FUNCS([__secure_getenv secure_getenv])
|
||||
AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at, setns, LO_FLAGS_PARTSCAN],
|
||||
AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at, setns, getrandom, LO_FLAGS_PARTSCAN],
|
||||
[], [], [[
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
@ -316,6 +316,7 @@ AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at, setns, LO_FLAGS_PARTSCAN]
|
||||
#include <fcntl.h>
|
||||
#include <sched.h>
|
||||
#include <linux/loop.h>
|
||||
#include <linux/random.h>
|
||||
]])
|
||||
|
||||
AC_CHECK_DECLS([IFLA_MACVLAN_FLAGS,
|
||||
|
@ -140,6 +140,21 @@ static inline int memfd_create(const char *name, unsigned int flags) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __NR_getrandom
|
||||
# if defined __x86_64__
|
||||
# define __NR_getrandom 278
|
||||
# else
|
||||
# warning "__NR_getrandom unknown for your architecture"
|
||||
# define __NR_getrandom 0xffffffff
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_GETRANDOM
|
||||
static inline int getrandom(void *buffer, size_t count, unsigned flags) {
|
||||
return syscall(__NR_getrandom, buffer, count, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef BTRFS_IOCTL_MAGIC
|
||||
#define BTRFS_IOCTL_MAGIC 0x94
|
||||
#endif
|
||||
|
@ -2466,14 +2466,37 @@ char* dirname_malloc(const char *path) {
|
||||
}
|
||||
|
||||
int dev_urandom(void *p, size_t n) {
|
||||
_cleanup_close_ int fd;
|
||||
static int have_syscall = -1;
|
||||
int r, fd;
|
||||
ssize_t k;
|
||||
|
||||
/* Use the syscall unless we know we don't have it, or when
|
||||
* the requested size is too large for it. */
|
||||
if (have_syscall != 0 || (size_t) (int) n != n) {
|
||||
r = getrandom(p, n, 0);
|
||||
if (r == (int) n) {
|
||||
have_syscall = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (r < 0) {
|
||||
if (errno == ENOSYS)
|
||||
/* we lack the syscall, continue with reading from /dev/urandom */
|
||||
have_syscall = false;
|
||||
else
|
||||
return -errno;
|
||||
} else
|
||||
/* too short read? */
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||
if (fd < 0)
|
||||
return errno == ENOENT ? -ENOSYS : -errno;
|
||||
|
||||
k = loop_read(fd, p, n, true);
|
||||
safe_close(fd);
|
||||
|
||||
if (k < 0)
|
||||
return (int) k;
|
||||
if ((size_t) k != n)
|
||||
|
Loading…
Reference in New Issue
Block a user