Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'hardening-v5.18-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux

Pull hardening fixes from Kees Cook:

- latent_entropy: Use /dev/urandom instead of small GCC seed (Jason
Donenfeld)

- uapi/stddef.h: add missed include guards (Tadeusz Struk)

* tag 'hardening-v5.18-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
gcc-plugins: latent_entropy: use /dev/urandom
uapi/linux/stddef.h: Add include guards

+31 -17
+4
include/uapi/linux/stddef.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 + #ifndef _UAPI_LINUX_STDDEF_H 3 + #define _UAPI_LINUX_STDDEF_H 4 + 2 5 #include <linux/compiler_types.h> 3 6 4 7 #ifndef __always_inline ··· 44 41 struct { } __empty_ ## NAME; \ 45 42 TYPE NAME[]; \ 46 43 } 44 + #endif
+27 -17
scripts/gcc-plugins/latent_entropy_plugin.c
··· 86 86 .help = "disable\tturn off latent entropy instrumentation\n", 87 87 }; 88 88 89 - static unsigned HOST_WIDE_INT seed; 90 - /* 91 - * get_random_seed() (this is a GCC function) generates the seed. 92 - * This is a simple random generator without any cryptographic security because 93 - * the entropy doesn't come from here. 94 - */ 89 + static unsigned HOST_WIDE_INT deterministic_seed; 90 + static unsigned HOST_WIDE_INT rnd_buf[32]; 91 + static size_t rnd_idx = ARRAY_SIZE(rnd_buf); 92 + static int urandom_fd = -1; 93 + 95 94 static unsigned HOST_WIDE_INT get_random_const(void) 96 95 { 97 - unsigned int i; 98 - unsigned HOST_WIDE_INT ret = 0; 99 - 100 - for (i = 0; i < 8 * sizeof(ret); i++) { 101 - ret = (ret << 1) | (seed & 1); 102 - seed >>= 1; 103 - if (ret & 1) 104 - seed ^= 0xD800000000000000ULL; 96 + if (deterministic_seed) { 97 + unsigned HOST_WIDE_INT w = deterministic_seed; 98 + w ^= w << 13; 99 + w ^= w >> 7; 100 + w ^= w << 17; 101 + deterministic_seed = w; 102 + return deterministic_seed; 105 103 } 106 104 107 - return ret; 105 + if (urandom_fd < 0) { 106 + urandom_fd = open("/dev/urandom", O_RDONLY); 107 + gcc_assert(urandom_fd >= 0); 108 + } 109 + if (rnd_idx >= ARRAY_SIZE(rnd_buf)) { 110 + gcc_assert(read(urandom_fd, rnd_buf, sizeof(rnd_buf)) == sizeof(rnd_buf)); 111 + rnd_idx = 0; 112 + } 113 + return rnd_buf[rnd_idx++]; 108 114 } 109 115 110 116 static tree tree_get_random_const(tree type) ··· 543 537 tree type, id; 544 538 int quals; 545 539 546 - seed = get_random_seed(false); 547 - 548 540 if (in_lto_p) 549 541 return; 550 542 ··· 576 572 const int argc = plugin_info->argc; 577 573 const struct plugin_argument * const argv = plugin_info->argv; 578 574 int i; 575 + 576 + /* 577 + * Call get_random_seed() with noinit=true, so that this returns 578 + * 0 in the case where no seed has been passed via -frandom-seed. 579 + */ 580 + deterministic_seed = get_random_seed(true); 579 581 580 582 static const struct ggc_root_tab gt_ggc_r_gt_latent_entropy[] = { 581 583 {