diff options
Diffstat (limited to '')
-rw-r--r-- | scripts/gcc-plugins/latent_entropy_plugin.c | 62 |
1 files changed, 30 insertions, 32 deletions
diff --git a/scripts/gcc-plugins/latent_entropy_plugin.c b/scripts/gcc-plugins/latent_entropy_plugin.c index cbe1d6c4b1a5..39e86be60dd2 100644 --- a/scripts/gcc-plugins/latent_entropy_plugin.c +++ b/scripts/gcc-plugins/latent_entropy_plugin.c @@ -1,7 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright 2012-2016 by the PaX Team <pageexec@freemail.hu> * Copyright 2016 by Emese Revfy <re.emese@gmail.com> - * Licensed under the GPL v2 * * Note: the choice of the license means that the compilation process is * NOT 'eligible' as defined by gcc's library exception to the GPL v3, @@ -82,29 +82,35 @@ __visible int plugin_is_GPL_compatible; static GTY(()) tree latent_entropy_decl; static struct plugin_info latent_entropy_plugin_info = { - .version = "201606141920vanilla", + .version = PLUGIN_VERSION, .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) @@ -125,11 +131,7 @@ static tree handle_latent_entropy_attribute(tree *node, tree name, bool *no_add_attrs) { tree type; -#if BUILDING_GCC_VERSION <= 4007 - VEC(constructor_elt, gc) *vals; -#else vec<constructor_elt, va_gc> *vals; -#endif switch (TREE_CODE(*node)) { default: @@ -181,11 +183,7 @@ static tree handle_latent_entropy_attribute(tree *node, tree name, if (fld) break; -#if BUILDING_GCC_VERSION <= 4007 - vals = VEC_alloc(constructor_elt, gc, nelt); -#else vec_alloc(vals, nelt); -#endif for (fld = lst; fld; fld = TREE_CHAIN(fld)) { tree random_const, fld_t = TREE_TYPE(fld); @@ -225,11 +223,7 @@ static tree handle_latent_entropy_attribute(tree *node, tree name, elt_size_int = TREE_INT_CST_LOW(elt_size); nelt = array_size_int / elt_size_int; -#if BUILDING_GCC_VERSION <= 4007 - vals = VEC_alloc(constructor_elt, gc, nelt); -#else vec_alloc(vals, nelt); -#endif for (i = 0; i < nelt; i++) { tree cst = size_int(i); @@ -536,7 +530,7 @@ static unsigned int latent_entropy_execute(void) while (bb != EXIT_BLOCK_PTR_FOR_FN(cfun)) { perturb_local_entropy(bb, local_entropy); bb = bb->next_bb; - }; + } /* 4. mix local entropy into the global entropy variable */ perturb_latent_entropy(local_entropy); @@ -549,8 +543,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; @@ -585,6 +577,12 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, const struct plugin_argument * const argv = plugin_info->argv; int i; + /* + * 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); + static const struct ggc_root_tab gt_ggc_r_gt_latent_entropy[] = { { .base = &latent_entropy_decl, |