Currently, when we generate a temporary file name, we use the seconds, microseconds, and the PID to generate a unique value. The resulting value, while changing frequently, is actually predictable and on some systems, it may be possible to cause a DoS by creating all potential temporary files when the temporary file is being created in TMPDIR. The solution to this is to use the system CSPRNG to generate the temporary file name. This is the approach taken by FreeBSD, NetBSD, and OpenBSD, and glibc also recently switched to this approach from an approach that resembled ours in many ways. Even if this is not practically exploitable on many systems, it seems prudent to be at least as careful about temporary file generation as libc is. In this round, I've switched to allow multiple values for the makefile variable to make our usage in autoconf easier. I have not submitted any changes to the autoconf code, since the defaults are fine for most situations, and even a fallback to /dev/urandom should be okay in most places. I also haven't included multiple values in config.mak.uname since there's little reason to do so: the BSDs all have had arc4random for a long time, Windows and NonStop have only one good option, and no other systems have a value set. A range-diff appears below for your convenience. Changes from v2: * Switch from a single option in the makefile variable to multiple options. * Change the name of the libbsd option to "libbsd" so it doesn't share a substring with other options due to the function we use. Changes from v1: * Remove the automatic testing using buckets because it didn't seem to add much. * Switch to a single makefile variable. * Add support for OpenSSL CSPRNG. * Add more defaults for various systems, including macOS and NonStop. * Add an arc4random-libbsd variant for improved testing of the arc4random code paths on Linux. The only difference is the inclusion of an additional header. * Print a more useful error message than before, indicating that the CSPRNG failed. brian m. carlson (2): wrapper: add a helper to generate numbers from a CSPRNG wrapper: use a CSPRNG to generate random file names Makefile | 34 ++++++++++++ compat/winansi.c | 6 +++ config.mak.uname | 8 +++ contrib/buildsystems/CMakeLists.txt | 2 +- git-compat-util.h | 19 +++++++ t/helper/test-csprng.c | 29 +++++++++++ t/helper/test-tool.c | 1 + t/helper/test-tool.h | 1 + wrapper.c | 81 +++++++++++++++++++++++++---- 9 files changed, 169 insertions(+), 12 deletions(-) create mode 100644 t/helper/test-csprng.c Diff-intervalle contre v2 : 1: edd623bd9a ! 1: 6644235af2 wrapper: add a helper to generate numbers from a CSPRNG @@ Commit message requested, or we fail. We don't return partial data because the caller will almost never find that to be a useful behavior. - Specify a makefile knob which users can use to specify their preferred - CSPRNG, and turn the multiple string options into a set of defines, - since we cannot match on strings in the preprocessor. + Specify a makefile knob which users can use to specify one or more + suitable CSPRNGs, and turn the multiple string options into a set of + defines, since we cannot match on strings in the preprocessor. We allow + multiple options to make the job of handling this in autoconf easier. - The order of suggested options is important here. On systems with - arc4random, which is most of the BSDs, we suggest that, since, except on - MirBSD and macOS, it uses ChaCha20, which is extremely fast, and sits - entirely in userspace, avoiding a system call. We then prefer getrandom - over getentropy, because the former has been available longer on Linux, - and then OpenSSL. Finally, if none of those are available, we use + The order of options is important here. On systems with arc4random, + which is most of the BSDs, we use that, since, except on MirBSD and + macOS, it uses ChaCha20, which is extremely fast, and sits entirely in + userspace, avoiding a system call. We then prefer getrandom over + getentropy, because the former has been available longer on Linux, and + then OpenSSL. Finally, if none of those are available, we use /dev/urandom, because most Unix-like operating systems provide that API. - We prefer to suggest options that don't involve device files when - possible because those work in some restricted environments where device - files may not be available. + We prefer options that don't involve device files when possible because + those work in some restricted environments where device files may not be + available. Set the configuration variables appropriately for Linux and the BSDs, including macOS, as well as Windows and NonStop. We specifically only @@ Makefile: all:: # the executable mode bit, but doesn't really do so. # +# Define CSPRNG_METHOD to "arc4random" if your system has arc4random and -+# arc4random_buf, "arc4random-libbsd" if your system has those functions from -+# libbsd, "getrandom" if your system has getrandom, "getentropy" if your -+# system has getentropy, "rtlgenrandom" for RtlGenRandom (Windows only), or -+# "openssl" if you'd want to use the OpenSSL CSPRNG. If unset or set to ++# arc4random_buf, "libbsd" if your system has those functions from libbsd, ++# "getrandom" if your system has getrandom, "getentropy" if your system has ++# getentropy, "rtlgenrandom" for RtlGenRandom (Windows only), or "openssl" if ++# you'd want to use the OpenSSL CSPRNG. You may set multiple options with ++# spaces, in which case a suitable option will be chosen. If unset or set to +# anything else, defaults to using "/dev/urandom". +# # Define NEEDS_MODE_TRANSLATION if your OS strays from the typical file type @@ Makefile: ifdef HAVE_GETDELIM BASIC_CFLAGS += -DHAVE_GETDELIM endif -+ifeq ($(strip $(CSPRNG_METHOD)),arc4random) ++ifneq ($(findstring arc4random,$(CSPRNG_METHOD)),) + BASIC_CFLAGS += -DHAVE_ARC4RANDOM +endif + -+ifeq ($(strip $(CSPRNG_METHOD)),arc4random-libbsd) ++ifneq ($(findstring libbsd,$(CSPRNG_METHOD)),) + BASIC_CFLAGS += -DHAVE_ARC4RANDOM_LIBBSD + EXTLIBS += -lbsd +endif + -+ifeq ($(strip $(CSPRNG_METHOD)),getrandom) ++ifneq ($(findstring getrandom,$(CSPRNG_METHOD)),) + BASIC_CFLAGS += -DHAVE_GETRANDOM +endif + -+ifeq ($(strip $(CSPRNG_METHOD)),getentropy) ++ifneq ($(findstring getentropy,$(CSPRNG_METHOD)),) + BASIC_CFLAGS += -DHAVE_GETENTROPY +endif + -+ifeq ($(strip $(CSPRNG_METHOD)),rtlgenrandom) ++ifneq ($(findstring rtlgenrandom,$(CSPRNG_METHOD)),) + BASIC_CFLAGS += -DHAVE_RTLGENRANDOM +endif + -+ifeq ($(strip $(CSPRNG_METHOD)),openssl) ++ifneq ($(findstring openssl,$(CSPRNG_METHOD)),) + BASIC_CFLAGS += -DHAVE_OPENSSL_CSPRNG +endif + 2: b4cd8700e3 = 2: c6d7d686f2 wrapper: use a CSPRNG to generate random file names