From: Greg Kroah-Hartman Date: Mon, 18 Apr 2022 10:04:55 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v4.9.311~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0783bf5a3ea7d0a306828ec068f88c9c1d380f42;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: gcc-plugins-latent_entropy-use-dev-urandom.patch --- diff --git a/queue-4.9/gcc-plugins-latent_entropy-use-dev-urandom.patch b/queue-4.9/gcc-plugins-latent_entropy-use-dev-urandom.patch new file mode 100644 index 00000000000..e73705be01f --- /dev/null +++ b/queue-4.9/gcc-plugins-latent_entropy-use-dev-urandom.patch @@ -0,0 +1,121 @@ +From c40160f2998c897231f8454bf797558d30a20375 Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" +Date: Wed, 6 Apr 2022 00:28:15 +0200 +Subject: gcc-plugins: latent_entropy: use /dev/urandom + +From: Jason A. Donenfeld + +commit c40160f2998c897231f8454bf797558d30a20375 upstream. + +While the latent entropy plugin mostly doesn't derive entropy from +get_random_const() for measuring the call graph, when __latent_entropy is +applied to a constant, then it's initialized statically to output from +get_random_const(). In that case, this data is derived from a 64-bit +seed, which means a buffer of 512 bits doesn't really have that amount +of compile-time entropy. + +This patch fixes that shortcoming by just buffering chunks of +/dev/urandom output and doling it out as requested. + +At the same time, it's important that we don't break the use of +-frandom-seed, for people who want the runtime benefits of the latent +entropy plugin, while still having compile-time determinism. In that +case, we detect whether gcc's set_random_seed() has been called by +making a call to get_random_seed(noinit=true) in the plugin init +function, which is called after set_random_seed() is called but before +anything that calls get_random_seed(noinit=false), and seeing if it's +zero or not. If it's not zero, we're in deterministic mode, and so we +just generate numbers with a basic xorshift prng. + +Note that we don't detect if -frandom-seed is being used using the +documented local_tick variable, because it's assigned via: + local_tick = (unsigned) tv.tv_sec * 1000 + tv.tv_usec / 1000; +which may well overflow and become -1 on its own, and so isn't +reliable: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105171 + +[kees: The 256 byte rnd_buf size was chosen based on average (250), + median (64), and std deviation (575) bytes of used entropy for a + defconfig x86_64 build] + +Fixes: 38addce8b600 ("gcc-plugins: Add latent_entropy plugin") +Cc: stable@vger.kernel.org +Cc: PaX Team +Signed-off-by: Jason A. Donenfeld +Signed-off-by: Kees Cook +Link: https://lore.kernel.org/r/20220405222815.21155-1-Jason@zx2c4.com +Signed-off-by: Greg Kroah-Hartman +--- + scripts/gcc-plugins/latent_entropy_plugin.c | 44 +++++++++++++++++----------- + 1 file changed, 27 insertions(+), 17 deletions(-) + +--- a/scripts/gcc-plugins/latent_entropy_plugin.c ++++ b/scripts/gcc-plugins/latent_entropy_plugin.c +@@ -86,25 +86,31 @@ static struct plugin_info latent_entropy + .help = "disable\tturn off latent entropy instrumentation\n", + }; + +-static unsigned HOST_WIDE_INT seed; +-/* +- * get_random_seed() (this is a GCC function) generates the seed. +- * This is a simple random generator without any cryptographic security because +- * the entropy doesn't come from here. +- */ ++static unsigned HOST_WIDE_INT deterministic_seed; ++static unsigned HOST_WIDE_INT rnd_buf[32]; ++static size_t rnd_idx = ARRAY_SIZE(rnd_buf); ++static int urandom_fd = -1; ++ + static unsigned HOST_WIDE_INT get_random_const(void) + { +- unsigned int i; +- unsigned HOST_WIDE_INT ret = 0; +- +- for (i = 0; i < 8 * sizeof(ret); i++) { +- ret = (ret << 1) | (seed & 1); +- seed >>= 1; +- if (ret & 1) +- seed ^= 0xD800000000000000ULL; ++ if (deterministic_seed) { ++ unsigned HOST_WIDE_INT w = deterministic_seed; ++ w ^= w << 13; ++ w ^= w >> 7; ++ w ^= w << 17; ++ deterministic_seed = w; ++ return deterministic_seed; + } + +- return ret; ++ if (urandom_fd < 0) { ++ urandom_fd = open("/dev/urandom", O_RDONLY); ++ gcc_assert(urandom_fd >= 0); ++ } ++ if (rnd_idx >= ARRAY_SIZE(rnd_buf)) { ++ gcc_assert(read(urandom_fd, rnd_buf, sizeof(rnd_buf)) == sizeof(rnd_buf)); ++ rnd_idx = 0; ++ } ++ return rnd_buf[rnd_idx++]; + } + + static tree tree_get_random_const(tree type) +@@ -556,8 +562,6 @@ static void latent_entropy_start_unit(vo + tree type, id; + int quals; + +- seed = get_random_seed(false); +- + if (in_lto_p) + return; + +@@ -594,6 +598,12 @@ __visible int plugin_init(struct plugin_ + + struct register_pass_info latent_entropy_pass_info; + ++ /* ++ * Call get_random_seed() with noinit=true, so that this returns ++ * 0 in the case where no seed has been passed via -frandom-seed. ++ */ ++ deterministic_seed = get_random_seed(true); ++ + latent_entropy_pass_info.pass = make_latent_entropy_pass(); + latent_entropy_pass_info.reference_pass_name = "optimized"; + latent_entropy_pass_info.ref_pass_instance_number = 1; diff --git a/queue-4.9/series b/queue-4.9/series index e7b1a4a68fc..f6f2da80b63 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -215,3 +215,4 @@ alsa-pcm-test-for-silence-field-in-struct-pcm_format_data.patch arm-davinci-da850-evm-avoid-null-pointer-dereference.patch smp-fix-offline-cpu-check-in-flush_smp_call_function_queue.patch i2c-pasemi-wait-for-write-xfers-to-finish.patch +gcc-plugins-latent_entropy-use-dev-urandom.patch