[PATCH] D44866: GetRandom / OpenBSD, using getentropy to get high quality randomness
David CARLIER via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Mar 24 09:02:19 PDT 2018
devnexen created this revision.
devnexen added reviewers: kubamracek, vitalybuka.
devnexen created this object with visibility "All Users".
Herald added subscribers: Sanitizers, llvm-commits.
- getentropy presence since late 2014, safe to use.
- guarantees to delivers good random data up to 256 bytes.
- fall back to /dev/urandom as long the buffer is correct.
Repository:
rCRT Compiler Runtime
https://reviews.llvm.org/D44866
Files:
lib/sanitizer_common/sanitizer_linux.cc
Index: lib/sanitizer_common/sanitizer_linux.cc
===================================================================
--- lib/sanitizer_common/sanitizer_linux.cc
+++ lib/sanitizer_common/sanitizer_linux.cc
@@ -140,6 +140,9 @@
}
#endif
+// Note : FreeBSD had implemented both
+// Linux and OpenBSD apis, available from
+// future 12.x version most likely
#if SANITIZER_LINUX && defined(__NR_getrandom)
# if !defined(GRND_NONBLOCK)
# define GRND_NONBLOCK 1
@@ -149,6 +152,12 @@
# define SANITIZER_USE_GETRANDOM 0
#endif // SANITIZER_LINUX && defined(__NR_getrandom)
+#if SANITIZER_OPENBSD
+# define SANITIZER_USE_GETENTROPY 1
+#else
+# define SANITIZER_USE_GETENTROPY 0
+#endif // SANITIZER_USE_GETENTROPY
+
namespace __sanitizer {
#if SANITIZER_LINUX && defined(__x86_64__)
@@ -1906,25 +1915,33 @@
bool GetRandom(void *buffer, uptr length, bool blocking) {
if (!buffer || !length || length > 256)
return false;
+ uptr res;
#if SANITIZER_USE_GETRANDOM
static atomic_uint8_t skip_getrandom_syscall;
if (!atomic_load_relaxed(&skip_getrandom_syscall)) {
// Up to 256 bytes, getrandom will not be interrupted.
- uptr res = internal_syscall(SYSCALL(getrandom), buffer, length,
+ res = internal_syscall(SYSCALL(getrandom), buffer, length,
blocking ? 0 : GRND_NONBLOCK);
int rverrno = 0;
if (internal_iserror(res, &rverrno) && rverrno == ENOSYS)
atomic_store_relaxed(&skip_getrandom_syscall, 1);
else if (res == length)
return true;
}
-#endif // SANITIZER_USE_GETRANDOM
+#elif SANITIZER_USE_GETENTROPY
+ res = getentropy(buffer, length);
+ int rverrno = 0;
+ if (internal_iserror(res, &rverrno) && rverrno == EFAULT)
+ return false;
+ else if (res == 0)
+ return true;
+#endif // SANITIZER_USE_GETENTROPY
// Up to 256 bytes, a read off /dev/urandom will not be interrupted.
// blocking is moot here, O_NONBLOCK has no effect when opening /dev/urandom.
uptr fd = internal_open("/dev/urandom", O_RDONLY);
if (internal_iserror(fd))
return false;
- uptr res = internal_read(fd, buffer, length);
+ res = internal_read(fd, buffer, length);
if (internal_iserror(res))
return false;
internal_close(fd);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D44866.139713.patch
Type: text/x-patch
Size: 2235 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180324/e1886b11/attachment.bin>
More information about the llvm-commits
mailing list