From c13c97dbf846cf0e6a5581ac414ef96a215b0dc6 Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 19 May 2023 10:14:35 +0100 Subject: [PATCH 1/4] random: getentropy on macOS does not need unistd.h Remove it. Make this change, so in a future commit, we can combine #ifdefs, and avoid duplicate includes once we switch to using getrandom directly. Also remove the comment about macOS 10.12. We already require macOS > 10.15, so it is redundant. --- configure.ac | 4 ++-- src/random.cpp | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 97b970161c..17cc31162c 100644 --- a/configure.ac +++ b/configure.ac @@ -1179,8 +1179,8 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include [ AC_MSG_RESULT([no])] ) -AC_MSG_CHECKING([for getentropy via random.h]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +AC_MSG_CHECKING([for getentropy via sys/random.h]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ getentropy(nullptr, 32) ]])], [ AC_MSG_RESULT([yes]); AC_DEFINE([HAVE_GETENTROPY_RAND], [1], [Define this symbol if the BSD getentropy system call is available with sys/random.h]) ], diff --git a/src/random.cpp b/src/random.cpp index f4c51574cc..144a5c5318 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -33,7 +33,6 @@ #include #endif #if defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX) -#include #include #endif #ifdef HAVE_SYSCTL_ARND @@ -314,8 +313,6 @@ void GetOSRand(unsigned char *ent32) // Silence a compiler warning about unused function. (void)GetDevURandom; #elif defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX) - /* getentropy() is available on macOS 10.12 and later. - */ if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) { RandFailure(); } From c2ba3f5b0c7d0eece7d16d1ffc125d8a6a9297af Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 19 May 2023 09:34:20 +0100 Subject: [PATCH 2/4] random: add [[maybe_unused]] to GetDevURandom Rather than multiple instances of (void)GetDevURandom to silence compiler warnings. --- src/random.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/random.cpp b/src/random.cpp index 144a5c5318..61f342269f 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -251,7 +251,7 @@ static void Strengthen(const unsigned char (&seed)[32], SteadyClock::duration du /** Fallback: get 32 bytes of system entropy from /dev/urandom. The most * compatible way to get cryptographic randomness on UNIX-ish platforms. */ -static void GetDevURandom(unsigned char *ent32) +[[maybe_unused]] static void GetDevURandom(unsigned char *ent32) { int f = open("/dev/urandom", O_RDONLY); if (f == -1) { @@ -310,14 +310,10 @@ void GetOSRand(unsigned char *ent32) The function call is always successful. */ arc4random_buf(ent32, NUM_OS_RANDOM_BYTES); - // Silence a compiler warning about unused function. - (void)GetDevURandom; #elif defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX) if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) { RandFailure(); } - // Silence a compiler warning about unused function. - (void)GetDevURandom; #elif defined(HAVE_SYSCTL_ARND) /* FreeBSD, NetBSD and similar. It is possible for the call to return less * bytes than requested, so need to read in a loop. @@ -331,8 +327,6 @@ void GetOSRand(unsigned char *ent32) } have += len; } while (have < NUM_OS_RANDOM_BYTES); - // Silence a compiler warning about unused function. - (void)GetDevURandom; #else /* Fall back to /dev/urandom if there is no specific method implemented to * get system entropy for this OS. From d5e06919db5e221bfef445c5a40c88de72dc5869 Mon Sep 17 00:00:00 2001 From: fanquake Date: Thu, 18 May 2023 11:25:44 +0100 Subject: [PATCH 3/4] random: switch to using getrandom() directly This requires a linux kernel of 3.17.0+, which seems entirely reasonable. 3.17 went EOL in 2015, and the last supported 3.x kernel (3.16) went EOL > 4 years ago, in 2020. For reference, the current oldest maintained kernel is 4.14 (released 2017, EOL Jan 2024). Support for `getrandom()` (and `getentropy()`) was added to glibc 2.25, https://sourceware.org/legacy-ml/libc-alpha/2017-02/msg00079.html, and we already require 2.27+. All that being said, I don't think you would encounter a current day system, running with kernel headers older than 3.17 (released 2014) but also having a glibc of 2.27+ (released 2018). --- configure.ac | 11 +++++------ doc/dependencies.md | 2 +- src/random.cpp | 22 +++++----------------- 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/configure.ac b/configure.ac index 17cc31162c..2eeec87c97 100644 --- a/configure.ac +++ b/configure.ac @@ -1170,12 +1170,11 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], ) dnl Check for different ways of gathering OS randomness -AC_MSG_CHECKING([for Linux getrandom syscall]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include - #include - #include ]], - [[ syscall(SYS_getrandom, nullptr, 32, 0); ]])], - [ AC_MSG_RESULT([yes]); AC_DEFINE([HAVE_SYS_GETRANDOM], [1], [Define this symbol if the Linux getrandom system call is available]) ], +AC_MSG_CHECKING([for Linux getrandom function]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include ]], + [[ getrandom(nullptr, 32, 0); ]])], + [ AC_MSG_RESULT([yes]); AC_DEFINE([HAVE_GETRANDOM], [1], [Define this symbol if the Linux getrandom function call is available]) ], [ AC_MSG_RESULT([no])] ) diff --git a/doc/dependencies.md b/doc/dependencies.md index 4344ed259e..804f796abe 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -20,7 +20,7 @@ You can find installation instructions in the `build-*.md` file for your platfor | [Boost](../depends/packages/boost.mk) | [link](https://www.boost.org/users/download/) | [1.81.0](https://github.com/bitcoin/bitcoin/pull/26557) | [1.64.0](https://github.com/bitcoin/bitcoin/pull/22320) | No | | [libevent](../depends/packages/libevent.mk) | [link](https://github.com/libevent/libevent/releases) | [2.1.12-stable](https://github.com/bitcoin/bitcoin/pull/21991) | [2.1.8](https://github.com/bitcoin/bitcoin/pull/24681) | No | | glibc | [link](https://www.gnu.org/software/libc/) | N/A | [2.27](https://github.com/bitcoin/bitcoin/pull/27029) | Yes | -| Linux Kernel | [link](https://www.kernel.org/) | N/A | 3.2.0 | Yes | +| Linux Kernel | [link](https://www.kernel.org/) | N/A | [3.17.0](https://github.com/bitcoin/bitcoin/pull/27699) | Yes | ## Optional diff --git a/src/random.cpp b/src/random.cpp index 61f342269f..54500e6cc6 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -28,13 +28,10 @@ #include #endif -#ifdef HAVE_SYS_GETRANDOM -#include -#include -#endif -#if defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX) +#if defined(HAVE_GETRANDOM) || (defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)) #include #endif + #ifdef HAVE_SYSCTL_ARND #include #endif @@ -284,23 +281,14 @@ void GetOSRand(unsigned char *ent32) RandFailure(); } CryptReleaseContext(hProvider, 0); -#elif defined(HAVE_SYS_GETRANDOM) +#elif defined(HAVE_GETRANDOM) /* Linux. From the getrandom(2) man page: * "If the urandom source has been initialized, reads of up to 256 bytes * will always return as many bytes as requested and will not be * interrupted by signals." */ - int rv = syscall(SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0); - if (rv != NUM_OS_RANDOM_BYTES) { - if (rv < 0 && errno == ENOSYS) { - /* Fallback for kernel <3.17: the return value will be -1 and errno - * ENOSYS if the syscall is not available, in that case fall back - * to /dev/urandom. - */ - GetDevURandom(ent32); - } else { - RandFailure(); - } + if (getrandom(ent32, NUM_OS_RANDOM_BYTES, 0) != NUM_OS_RANDOM_BYTES) { + RandFailure(); } #elif defined(__OpenBSD__) /* OpenBSD. From the arc4random(3) man page: From 5228223e1ff2af29e6e77668ce3288005c2adbbc Mon Sep 17 00:00:00 2001 From: fanquake Date: Thu, 18 May 2023 11:28:41 +0100 Subject: [PATCH 4/4] ci: remove MSAN getrandom syscall workaround The corresponding workaround will also be dropped in oss-fuzz: https://github.com/google/oss-fuzz/blob/25946a544856413d31d9cbb3a366a4aef5a8fd60/projects/bitcoin-core/build.sh#L49. --- ci/test/06_script_b.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/ci/test/06_script_b.sh b/ci/test/06_script_b.sh index 17e9dc1b5c..cf1cab900c 100755 --- a/ci/test/06_script_b.sh +++ b/ci/test/06_script_b.sh @@ -101,14 +101,6 @@ cd "${BASE_BUILD_DIR}/bitcoin-$HOST" bash -c "./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG" || ( (cat config.log) && false) -if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then - # MemorySanitizer (MSAN) does not support tracking memory initialization done by - # using the Linux getrandom syscall. Avoid using getrandom by undefining - # HAVE_SYS_GETRANDOM. See https://github.com/google/sanitizers/issues/852 for - # details. - grep -v HAVE_SYS_GETRANDOM src/config/bitcoin-config.h > src/config/bitcoin-config.h.tmp && mv src/config/bitcoin-config.h.tmp src/config/bitcoin-config.h -fi - if [[ "${RUN_TIDY}" == "true" ]]; then MAYBE_BEAR="bear --config src/.bear-tidy-config" MAYBE_TOKEN="--"