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. Fixes: 38addce8b600 ("gcc-plugins: Add latent_entropy plugin") Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Jason A. Donenfeld <Jason@xxxxxxxxx> --- I'm not super familiar with this plugin or its conventions, so pointers would be most welcome if something here looks amiss. The decision to buffer 2k at a time is pretty arbitrary too; I haven't measured usage. scripts/gcc-plugins/latent_entropy_plugin.c | 34 +++++++++------------ 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/scripts/gcc-plugins/latent_entropy_plugin.c b/scripts/gcc-plugins/latent_entropy_plugin.c index 589454bce930..f238ba6726b8 100644 --- a/scripts/gcc-plugins/latent_entropy_plugin.c +++ b/scripts/gcc-plugins/latent_entropy_plugin.c @@ -82,29 +82,27 @@ __visible int plugin_is_GPL_compatible; static GTY(()) tree latent_entropy_decl; static struct plugin_info latent_entropy_plugin_info = { - .version = "201606141920vanilla", + .version = "202203311920vanilla", .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 rnd_buf[256]; +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 (urandom_fd < 0) { + urandom_fd = open("/dev/urandom", O_RDONLY); + if (urandom_fd < 0) + abort(); } - - return ret; + if (rnd_idx >= ARRAY_SIZE(rnd_buf)) { + if (read(urandom_fd, rnd_buf, sizeof(rnd_buf)) != sizeof(rnd_buf)) + abort(); + rnd_idx = 0; + } + return rnd_buf[rnd_idx++]; } static tree tree_get_random_const(tree type) @@ -537,8 +535,6 @@ static void latent_entropy_start_unit(void *gcc_data __unused, tree type, id; int quals; - seed = get_random_seed(false); - if (in_lto_p) return; -- 2.35.1