2022-05-28 20:02:35

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 000/111] 5.17.12-rc1 review

This is the start of the stable review cycle for the 5.17.12 release.
There are 111 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.

Responses should be made by Sun, 29 May 2022 08:46:36 +0000.
Anything received after that time might be too late.

The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.17.12-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.17.y
and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <[email protected]>
Linux 5.17.12-rc1

Edward Matijevic <[email protected]>
ALSA: ctxfi: Add SB046x PCI ID

Lorenzo Pieralisi <[email protected]>
ACPI: sysfs: Fix BERT error region memory mapping

Jason A. Donenfeld <[email protected]>
random: check for signals after page of pool writes

Jens Axboe <[email protected]>
random: wire up fops->splice_{read,write}_iter()

Jens Axboe <[email protected]>
random: convert to using fops->write_iter()

Jens Axboe <[email protected]>
random: convert to using fops->read_iter()

Jason A. Donenfeld <[email protected]>
random: unify batched entropy implementations

Jason A. Donenfeld <[email protected]>
random: move randomize_page() into mm where it belongs

Jason A. Donenfeld <[email protected]>
random: move initialization functions out of hot pages

Jason A. Donenfeld <[email protected]>
random: make consistent use of buf and len

Jason A. Donenfeld <[email protected]>
random: use proper return types on get_random_{int,long}_wait()

Jason A. Donenfeld <[email protected]>
random: remove extern from functions in header

Jason A. Donenfeld <[email protected]>
random: use static branch for crng_ready()

Jason A. Donenfeld <[email protected]>
random: credit architectural init the exact amount

Jason A. Donenfeld <[email protected]>
random: handle latent entropy and command line from random_init()

Jason A. Donenfeld <[email protected]>
random: use proper jiffies comparison macro

Jason A. Donenfeld <[email protected]>
random: remove ratelimiting for in-kernel unseeded randomness

Jason A. Donenfeld <[email protected]>
random: move initialization out of reseeding hot path

Jason A. Donenfeld <[email protected]>
random: avoid initializing twice in credit race

Jason A. Donenfeld <[email protected]>
random: use symbolic constants for crng_init states

Jason A. Donenfeld <[email protected]>
siphash: use one source of truth for siphash permutations

Jason A. Donenfeld <[email protected]>
random: help compiler out with fast_mix() by using simpler arguments

Jason A. Donenfeld <[email protected]>
random: do not use input pool from hard IRQs

Jason A. Donenfeld <[email protected]>
random: order timer entropy functions below interrupt functions

Jason A. Donenfeld <[email protected]>
random: do not pretend to handle premature next security model

Jason A. Donenfeld <[email protected]>
random: use first 128 bits of input as fast init

Jason A. Donenfeld <[email protected]>
random: do not use batches when !crng_ready()

Jason A. Donenfeld <[email protected]>
random: insist on random_get_entropy() existing in order to simplify

Jason A. Donenfeld <[email protected]>
xtensa: use fallback for random_get_entropy() instead of zero

Jason A. Donenfeld <[email protected]>
sparc: use fallback for random_get_entropy() instead of zero

Jason A. Donenfeld <[email protected]>
um: use fallback for random_get_entropy() instead of zero

Jason A. Donenfeld <[email protected]>
x86/tsc: Use fallback for random_get_entropy() instead of zero

Jason A. Donenfeld <[email protected]>
nios2: use fallback for random_get_entropy() instead of zero

Jason A. Donenfeld <[email protected]>
arm: use fallback for random_get_entropy() instead of zero

Jason A. Donenfeld <[email protected]>
mips: use fallback for random_get_entropy() instead of just c0 random

Jason A. Donenfeld <[email protected]>
riscv: use fallback for random_get_entropy() instead of zero

Jason A. Donenfeld <[email protected]>
m68k: use fallback for random_get_entropy() instead of zero

Jason A. Donenfeld <[email protected]>
timekeeping: Add raw clock fallback for random_get_entropy()

Jason A. Donenfeld <[email protected]>
powerpc: define get_cycles macro for arch-override

Jason A. Donenfeld <[email protected]>
alpha: define get_cycles macro for arch-override

Jason A. Donenfeld <[email protected]>
parisc: define get_cycles macro for arch-override

Jason A. Donenfeld <[email protected]>
s390: define get_cycles macro for arch-override

Jason A. Donenfeld <[email protected]>
ia64: define get_cycles macro for arch-override

Jason A. Donenfeld <[email protected]>
init: call time_init() before rand_initialize()

Jason A. Donenfeld <[email protected]>
random: fix sysctl documentation nits

Jason A. Donenfeld <[email protected]>
random: document crng_fast_key_erasure() destination possibility

Jason A. Donenfeld <[email protected]>
random: make random_get_entropy() return an unsigned long

Jason A. Donenfeld <[email protected]>
random: allow partial reads if later user copies fail

Jason A. Donenfeld <[email protected]>
random: check for signals every PAGE_SIZE chunk of /dev/[u]random

Jann Horn <[email protected]>
random: check for signal_pending() outside of need_resched() check

Jason A. Donenfeld <[email protected]>
random: do not allow user to keep crng key around on stack

Jan Varho <[email protected]>
random: do not split fast init input in add_hwgenerator_randomness()

Jason A. Donenfeld <[email protected]>
random: mix build-time latent entropy into pool at init

Jason A. Donenfeld <[email protected]>
random: re-add removed comment about get_random_{u32,u64} reseeding

Jason A. Donenfeld <[email protected]>
random: treat bootloader trust toggle the same way as cpu trust toggle

Jason A. Donenfeld <[email protected]>
random: skip fast_init if hwrng provides large chunk of entropy

Jason A. Donenfeld <[email protected]>
random: check for signal and try earlier when generating entropy

Jason A. Donenfeld <[email protected]>
random: reseed more often immediately after booting

Jason A. Donenfeld <[email protected]>
random: make consistent usage of crng_ready()

Jason A. Donenfeld <[email protected]>
random: use SipHash as interrupt entropy accumulator

Jason A. Donenfeld <[email protected]>
random: replace custom notifier chain with standard one

Jason A. Donenfeld <[email protected]>
random: don't let 644 read-only sysctls be written to

Jason A. Donenfeld <[email protected]>
random: give sysctl_random_min_urandom_seed a more sensible value

Jason A. Donenfeld <[email protected]>
random: do crng pre-init loading in worker rather than irq

Jason A. Donenfeld <[email protected]>
random: unify cycles_t and jiffies usage and types

Jason A. Donenfeld <[email protected]>
random: cleanup UUID handling

Jason A. Donenfeld <[email protected]>
random: only wake up writers after zap if threshold was passed

Jason A. Donenfeld <[email protected]>
random: round-robin registers as ulong, not u32

Jason A. Donenfeld <[email protected]>
random: clear fast pool, crng, and batches in cpuhp bring up

Jason A. Donenfeld <[email protected]>
random: pull add_hwgenerator_randomness() declaration into random.h

Jason A. Donenfeld <[email protected]>
random: check for crng_init == 0 in add_device_randomness()

Jason A. Donenfeld <[email protected]>
random: unify early init crng load accounting

Jason A. Donenfeld <[email protected]>
random: do not take pool spinlock at boot

Jason A. Donenfeld <[email protected]>
random: defer fast pool mixing to worker

Jason A. Donenfeld <[email protected]>
random: rewrite header introductory comment

Jason A. Donenfeld <[email protected]>
random: group sysctl functions

Jason A. Donenfeld <[email protected]>
random: group userspace read/write functions

Jason A. Donenfeld <[email protected]>
random: group entropy collection functions

Jason A. Donenfeld <[email protected]>
random: group entropy extraction functions

Jason A. Donenfeld <[email protected]>
random: group crng functions

Jason A. Donenfeld <[email protected]>
random: group initialization wait functions

Jason A. Donenfeld <[email protected]>
random: remove whitespace and reorder includes

Jason A. Donenfeld <[email protected]>
random: remove useless header comment

Jason A. Donenfeld <[email protected]>
random: introduce drain_entropy() helper to declutter crng_reseed()

Jason A. Donenfeld <[email protected]>
random: deobfuscate irq u32/u64 contributions

Jason A. Donenfeld <[email protected]>
random: add proper SPDX header

Jason A. Donenfeld <[email protected]>
random: remove unused tracepoints

Jason A. Donenfeld <[email protected]>
random: remove ifdef'd out interrupt bench

Jason A. Donenfeld <[email protected]>
random: tie batched entropy generation to base_crng generation

Dominik Brodowski <[email protected]>
random: fix locking for crng_init in crng_reseed()

Jason A. Donenfeld <[email protected]>
random: zero buffer after reading entropy from userspace

Jason A. Donenfeld <[email protected]>
random: remove outdated INT_MAX >> 6 check in urandom_read()

Jason A. Donenfeld <[email protected]>
random: make more consistent use of integer types

Jason A. Donenfeld <[email protected]>
random: use hash function for crng_slow_load()

Jason A. Donenfeld <[email protected]>
random: use simpler fast key erasure flow on per-cpu keys

Jason A. Donenfeld <[email protected]>
random: absorb fast pool into input pool after fast load

Jason A. Donenfeld <[email protected]>
random: do not xor RDRAND when writing into /dev/random

Jason A. Donenfeld <[email protected]>
random: ensure early RDSEED goes through mixer on init

Jason A. Donenfeld <[email protected]>
random: inline leaves of rand_initialize()

Jason A. Donenfeld <[email protected]>
random: get rid of secondary crngs

Jason A. Donenfeld <[email protected]>
random: use RDSEED instead of RDRAND in entropy extraction

Dominik Brodowski <[email protected]>
random: fix locking in crng_fast_load()

Jason A. Donenfeld <[email protected]>
random: remove batched entropy locking

Eric Biggers <[email protected]>
random: remove use_input_pool parameter from crng_reseed()

Jason A. Donenfeld <[email protected]>
random: make credit_entropy_bits() always safe

Jason A. Donenfeld <[email protected]>
random: always wake up entropy writers after extraction

Jason A. Donenfeld <[email protected]>
random: use linear min-entropy accumulation crediting

Jason A. Donenfeld <[email protected]>
random: simplify entropy debiting

Jason A. Donenfeld <[email protected]>
random: use computational hash for entropy extraction

Paolo Bonzini <[email protected]>
KVM: x86/mmu: fix NULL pointer dereference on guest INVPCID

Basavaraj Natikar <[email protected]>
HID: amd_sfh: Add support for sensor discovery


-------------

Diffstat:

Documentation/admin-guide/kernel-parameters.txt | 6 +
Documentation/admin-guide/sysctl/kernel.rst | 22 +-
Makefile | 4 +-
arch/alpha/include/asm/timex.h | 1 +
arch/arm/include/asm/timex.h | 1 +
arch/ia64/include/asm/timex.h | 1 +
arch/m68k/include/asm/timex.h | 2 +-
arch/mips/include/asm/timex.h | 17 +-
arch/nios2/include/asm/timex.h | 3 +
arch/parisc/include/asm/timex.h | 3 +-
arch/powerpc/include/asm/timex.h | 1 +
arch/riscv/include/asm/timex.h | 2 +-
arch/s390/include/asm/timex.h | 1 +
arch/sparc/include/asm/timex_32.h | 4 +-
arch/um/include/asm/timex.h | 9 +-
arch/x86/include/asm/timex.h | 9 +
arch/x86/include/asm/tsc.h | 7 +-
arch/x86/kvm/mmu/mmu.c | 6 +-
arch/xtensa/include/asm/timex.h | 6 +-
drivers/acpi/sysfs.c | 25 +-
drivers/char/Kconfig | 3 +-
drivers/char/hw_random/core.c | 1 +
drivers/char/random.c | 2868 +++++++++--------------
drivers/hid/amd-sfh-hid/amd_sfh_client.c | 11 +
drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 7 +
drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 4 +
include/linux/cpuhotplug.h | 2 +
include/linux/hw_random.h | 2 -
include/linux/mm.h | 1 +
include/linux/prandom.h | 23 +-
include/linux/random.h | 100 +-
include/linux/siphash.h | 28 +
include/linux/timex.h | 10 +-
include/trace/events/random.h | 233 --
init/main.c | 13 +-
kernel/cpu.c | 11 +
kernel/time/timekeeping.c | 15 +
lib/Kconfig.debug | 3 +-
lib/random32.c | 14 +-
lib/siphash.c | 32 +-
lib/vsprintf.c | 10 +-
mm/util.c | 32 +
sound/pci/ctxfi/ctatc.c | 2 +
sound/pci/ctxfi/cthardware.h | 3 +-
44 files changed, 1365 insertions(+), 2193 deletions(-)




2022-05-28 20:03:56

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 111/111] ALSA: ctxfi: Add SB046x PCI ID

From: Edward Matijevic <[email protected]>

commit 1b073ebb174d0c7109b438e0a5eb4495137803ec upstream.

Adds the PCI ID for X-Fi cards sold under the Platnum and XtremeMusic names

Before: snd_ctxfi 0000:05:05.0: chip 20K1 model Unknown (1102:0021) is found
After: snd_ctxfi 0000:05:05.0: chip 20K1 model SB046x (1102:0021) is found

[ This is only about defining the model name string, and the rest is
handled just like before, as a default unknown device.
Edward confirmed that the stuff has been working fine -- tiwai ]

Signed-off-by: Edward Matijevic <[email protected]>
Cc: <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/pci/ctxfi/ctatc.c | 2 ++
sound/pci/ctxfi/cthardware.h | 3 ++-
2 files changed, 4 insertions(+), 1 deletion(-)

--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -36,6 +36,7 @@
| ((IEC958_AES3_CON_FS_48000) << 24))

static const struct snd_pci_quirk subsys_20k1_list[] = {
+ SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0021, "SB046x", CTSB046X),
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0022, "SB055x", CTSB055X),
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x002f, "SB055x", CTSB055X),
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0029, "SB073x", CTSB073X),
@@ -64,6 +65,7 @@ static const struct snd_pci_quirk subsys

static const char *ct_subsys_name[NUM_CTCARDS] = {
/* 20k1 models */
+ [CTSB046X] = "SB046x",
[CTSB055X] = "SB055x",
[CTSB073X] = "SB073x",
[CTUAA] = "UAA",
--- a/sound/pci/ctxfi/cthardware.h
+++ b/sound/pci/ctxfi/cthardware.h
@@ -26,8 +26,9 @@ enum CHIPTYP {

enum CTCARDS {
/* 20k1 models */
+ CTSB046X,
+ CT20K1_MODEL_FIRST = CTSB046X,
CTSB055X,
- CT20K1_MODEL_FIRST = CTSB055X,
CTSB073X,
CTUAA,
CT20K1_UNKNOWN,



2022-05-28 20:07:44

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 033/111] random: group entropy extraction functions

From: "Jason A. Donenfeld" <[email protected]>

commit a5ed7cb1a7732ef11959332d507889fbc39ebbb4 upstream.

This pulls all of the entropy extraction-focused functions into the
third labeled section.

No functional changes.

Cc: Theodore Ts'o <[email protected]>
Reviewed-by: Eric Biggers <[email protected]>
Reviewed-by: Dominik Brodowski <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 216 +++++++++++++++++++++++++-------------------------
1 file changed, 109 insertions(+), 107 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -895,23 +895,36 @@ size_t __must_check get_random_bytes_arc
}
EXPORT_SYMBOL(get_random_bytes_arch);

+
+/**********************************************************************
+ *
+ * Entropy accumulation and extraction routines.
+ *
+ * Callers may add entropy via:
+ *
+ * static void mix_pool_bytes(const void *in, size_t nbytes)
+ *
+ * After which, if added entropy should be credited:
+ *
+ * static void credit_entropy_bits(size_t nbits)
+ *
+ * Finally, extract entropy via these two, with the latter one
+ * setting the entropy count to zero and extracting only if there
+ * is POOL_MIN_BITS entropy credited prior:
+ *
+ * static void extract_entropy(void *buf, size_t nbytes)
+ * static bool drain_entropy(void *buf, size_t nbytes)
+ *
+ **********************************************************************/
+
enum {
POOL_BITS = BLAKE2S_HASH_SIZE * 8,
POOL_MIN_BITS = POOL_BITS /* No point in settling for less. */
};

-/*
- * Static global variables
- */
+/* For notifying userspace should write into /dev/random. */
static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);

-/**********************************************************************
- *
- * OS independent entropy store. Here are the functions which handle
- * storing entropy in an entropy pool.
- *
- **********************************************************************/
-
static struct {
struct blake2s_state hash;
spinlock_t lock;
@@ -924,28 +937,106 @@ static struct {
.lock = __SPIN_LOCK_UNLOCKED(input_pool.lock),
};

-static void extract_entropy(void *buf, size_t nbytes);
-static bool drain_entropy(void *buf, size_t nbytes);
-
-static void crng_reseed(void);
+static void _mix_pool_bytes(const void *in, size_t nbytes)
+{
+ blake2s_update(&input_pool.hash, in, nbytes);
+}

/*
* This function adds bytes into the entropy "pool". It does not
* update the entropy estimate. The caller should call
* credit_entropy_bits if this is appropriate.
*/
-static void _mix_pool_bytes(const void *in, size_t nbytes)
+static void mix_pool_bytes(const void *in, size_t nbytes)
{
- blake2s_update(&input_pool.hash, in, nbytes);
+ unsigned long flags;
+
+ spin_lock_irqsave(&input_pool.lock, flags);
+ _mix_pool_bytes(in, nbytes);
+ spin_unlock_irqrestore(&input_pool.lock, flags);
}

-static void mix_pool_bytes(const void *in, size_t nbytes)
+static void credit_entropy_bits(size_t nbits)
+{
+ unsigned int entropy_count, orig, add;
+
+ if (!nbits)
+ return;
+
+ add = min_t(size_t, nbits, POOL_BITS);
+
+ do {
+ orig = READ_ONCE(input_pool.entropy_count);
+ entropy_count = min_t(unsigned int, POOL_BITS, orig + add);
+ } while (cmpxchg(&input_pool.entropy_count, orig, entropy_count) != orig);
+
+ if (crng_init < 2 && entropy_count >= POOL_MIN_BITS)
+ crng_reseed();
+}
+
+/*
+ * This is an HKDF-like construction for using the hashed collected entropy
+ * as a PRF key, that's then expanded block-by-block.
+ */
+static void extract_entropy(void *buf, size_t nbytes)
{
unsigned long flags;
+ u8 seed[BLAKE2S_HASH_SIZE], next_key[BLAKE2S_HASH_SIZE];
+ struct {
+ unsigned long rdseed[32 / sizeof(long)];
+ size_t counter;
+ } block;
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(block.rdseed); ++i) {
+ if (!arch_get_random_seed_long(&block.rdseed[i]) &&
+ !arch_get_random_long(&block.rdseed[i]))
+ block.rdseed[i] = random_get_entropy();
+ }

spin_lock_irqsave(&input_pool.lock, flags);
- _mix_pool_bytes(in, nbytes);
+
+ /* seed = HASHPRF(last_key, entropy_input) */
+ blake2s_final(&input_pool.hash, seed);
+
+ /* next_key = HASHPRF(seed, RDSEED || 0) */
+ block.counter = 0;
+ blake2s(next_key, (u8 *)&block, seed, sizeof(next_key), sizeof(block), sizeof(seed));
+ blake2s_init_key(&input_pool.hash, BLAKE2S_HASH_SIZE, next_key, sizeof(next_key));
+
spin_unlock_irqrestore(&input_pool.lock, flags);
+ memzero_explicit(next_key, sizeof(next_key));
+
+ while (nbytes) {
+ i = min_t(size_t, nbytes, BLAKE2S_HASH_SIZE);
+ /* output = HASHPRF(seed, RDSEED || ++counter) */
+ ++block.counter;
+ blake2s(buf, (u8 *)&block, seed, i, sizeof(block), sizeof(seed));
+ nbytes -= i;
+ buf += i;
+ }
+
+ memzero_explicit(seed, sizeof(seed));
+ memzero_explicit(&block, sizeof(block));
+}
+
+/*
+ * First we make sure we have POOL_MIN_BITS of entropy in the pool, and then we
+ * set the entropy count to zero (but don't actually touch any data). Only then
+ * can we extract a new key with extract_entropy().
+ */
+static bool drain_entropy(void *buf, size_t nbytes)
+{
+ unsigned int entropy_count;
+ do {
+ entropy_count = READ_ONCE(input_pool.entropy_count);
+ if (entropy_count < POOL_MIN_BITS)
+ return false;
+ } while (cmpxchg(&input_pool.entropy_count, entropy_count, 0) != entropy_count);
+ extract_entropy(buf, nbytes);
+ wake_up_interruptible(&random_write_wait);
+ kill_fasync(&fasync, SIGIO, POLL_OUT);
+ return true;
}

struct fast_pool {
@@ -988,24 +1079,6 @@ static void fast_mix(u32 pool[4])
pool[2] = c; pool[3] = d;
}

-static void credit_entropy_bits(size_t nbits)
-{
- unsigned int entropy_count, orig, add;
-
- if (!nbits)
- return;
-
- add = min_t(size_t, nbits, POOL_BITS);
-
- do {
- orig = READ_ONCE(input_pool.entropy_count);
- entropy_count = min_t(unsigned int, POOL_BITS, orig + add);
- } while (cmpxchg(&input_pool.entropy_count, orig, entropy_count) != orig);
-
- if (crng_init < 2 && entropy_count >= POOL_MIN_BITS)
- crng_reseed();
-}
-
/*********************************************************************
*
* Entropy input management
@@ -1202,77 +1275,6 @@ void add_disk_randomness(struct gendisk
EXPORT_SYMBOL_GPL(add_disk_randomness);
#endif

-/*********************************************************************
- *
- * Entropy extraction routines
- *
- *********************************************************************/
-
-/*
- * This is an HKDF-like construction for using the hashed collected entropy
- * as a PRF key, that's then expanded block-by-block.
- */
-static void extract_entropy(void *buf, size_t nbytes)
-{
- unsigned long flags;
- u8 seed[BLAKE2S_HASH_SIZE], next_key[BLAKE2S_HASH_SIZE];
- struct {
- unsigned long rdseed[32 / sizeof(long)];
- size_t counter;
- } block;
- size_t i;
-
- for (i = 0; i < ARRAY_SIZE(block.rdseed); ++i) {
- if (!arch_get_random_seed_long(&block.rdseed[i]) &&
- !arch_get_random_long(&block.rdseed[i]))
- block.rdseed[i] = random_get_entropy();
- }
-
- spin_lock_irqsave(&input_pool.lock, flags);
-
- /* seed = HASHPRF(last_key, entropy_input) */
- blake2s_final(&input_pool.hash, seed);
-
- /* next_key = HASHPRF(seed, RDSEED || 0) */
- block.counter = 0;
- blake2s(next_key, (u8 *)&block, seed, sizeof(next_key), sizeof(block), sizeof(seed));
- blake2s_init_key(&input_pool.hash, BLAKE2S_HASH_SIZE, next_key, sizeof(next_key));
-
- spin_unlock_irqrestore(&input_pool.lock, flags);
- memzero_explicit(next_key, sizeof(next_key));
-
- while (nbytes) {
- i = min_t(size_t, nbytes, BLAKE2S_HASH_SIZE);
- /* output = HASHPRF(seed, RDSEED || ++counter) */
- ++block.counter;
- blake2s(buf, (u8 *)&block, seed, i, sizeof(block), sizeof(seed));
- nbytes -= i;
- buf += i;
- }
-
- memzero_explicit(seed, sizeof(seed));
- memzero_explicit(&block, sizeof(block));
-}
-
-/*
- * First we make sure we have POOL_MIN_BITS of entropy in the pool, and then we
- * set the entropy count to zero (but don't actually touch any data). Only then
- * can we extract a new key with extract_entropy().
- */
-static bool drain_entropy(void *buf, size_t nbytes)
-{
- unsigned int entropy_count;
- do {
- entropy_count = READ_ONCE(input_pool.entropy_count);
- if (entropy_count < POOL_MIN_BITS)
- return false;
- } while (cmpxchg(&input_pool.entropy_count, entropy_count, 0) != entropy_count);
- extract_entropy(buf, nbytes);
- wake_up_interruptible(&random_write_wait);
- kill_fasync(&fasync, SIGIO, POLL_OUT);
- return true;
-}
-
/*
* Each time the timer fires, we expect that we got an unpredictable
* jump in the cycle counter. Even if the timer is running on another



2022-05-28 20:10:30

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 076/111] riscv: use fallback for random_get_entropy() instead of zero

From: "Jason A. Donenfeld" <[email protected]>

commit 6d01238623faa9425f820353d2066baf6c9dc872 upstream.

In the event that random_get_entropy() can't access a cycle counter or
similar, falling back to returning 0 is really not the best we can do.
Instead, at least calling random_get_entropy_fallback() would be
preferable, because that always needs to return _something_, even
falling back to jiffies eventually. It's not as though
random_get_entropy_fallback() is super high precision or guaranteed to
be entropic, but basically anything that's not zero all the time is
better than returning zero all the time.

Cc: Thomas Gleixner <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Paul Walmsley <[email protected]>
Acked-by: Palmer Dabbelt <[email protected]>
Reviewed-by: Palmer Dabbelt <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/riscv/include/asm/timex.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/riscv/include/asm/timex.h
+++ b/arch/riscv/include/asm/timex.h
@@ -41,7 +41,7 @@ static inline u32 get_cycles_hi(void)
static inline unsigned long random_get_entropy(void)
{
if (unlikely(clint_time_val == NULL))
- return 0;
+ return random_get_entropy_fallback();
return get_cycles();
}
#define random_get_entropy() random_get_entropy()



2022-05-28 20:12:20

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 073/111] powerpc: define get_cycles macro for arch-override

From: "Jason A. Donenfeld" <[email protected]>

commit 408835832158df0357e18e96da7f2d1ed6b80e7f upstream.

PowerPC defines a get_cycles() function, but it does not do the usual
`#define get_cycles get_cycles` dance, making it impossible for generic
code to see if an arch-specific function was defined. While the
get_cycles() ifdef is not currently used, the following timekeeping
patch in this series will depend on the macro existing (or not existing)
when defining random_get_entropy().

Cc: Thomas Gleixner <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Paul Mackerras <[email protected]>
Acked-by: Michael Ellerman <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/powerpc/include/asm/timex.h | 1 +
1 file changed, 1 insertion(+)

--- a/arch/powerpc/include/asm/timex.h
+++ b/arch/powerpc/include/asm/timex.h
@@ -19,6 +19,7 @@ static inline cycles_t get_cycles(void)
{
return mftb();
}
+#define get_cycles get_cycles

#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_TIMEX_H */



2022-05-28 20:13:40

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 021/111] random: zero buffer after reading entropy from userspace

From: "Jason A. Donenfeld" <[email protected]>

commit 7b5164fb1279bf0251371848e40bae646b59b3a8 upstream.

This buffer may contain entropic data that shouldn't stick around longer
than needed, so zero out the temporary buffer at the end of write_pool().

Reviewed-by: Dominik Brodowski <[email protected]>
Reviewed-by: Jann Horn <[email protected]>
Reviewed-by: Eric Biggers <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1336,19 +1336,24 @@ static __poll_t random_poll(struct file
static int write_pool(const char __user *ubuf, size_t count)
{
size_t len;
+ int ret = 0;
u8 block[BLAKE2S_BLOCK_SIZE];

while (count) {
len = min(count, sizeof(block));
- if (copy_from_user(block, ubuf, len))
- return -EFAULT;
+ if (copy_from_user(block, ubuf, len)) {
+ ret = -EFAULT;
+ goto out;
+ }
count -= len;
ubuf += len;
mix_pool_bytes(block, len);
cond_resched();
}

- return 0;
+out:
+ memzero_explicit(block, sizeof(block));
+ return ret;
}

static ssize_t random_write(struct file *file, const char __user *buffer,



2022-05-28 20:13:53

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 042/111] random: pull add_hwgenerator_randomness() declaration into random.h

From: "Jason A. Donenfeld" <[email protected]>

commit b777c38239fec5a528e59f55b379e31b1a187524 upstream.

add_hwgenerator_randomness() is a function implemented and documented
inside of random.c. It is the way that hardware RNGs push data into it.
Therefore, it should be declared in random.h. Otherwise sparse complains
with:

random.c:1137:6: warning: symbol 'add_hwgenerator_randomness' was not declared. Should it be static?

The alternative would be to include hw_random.h into random.c, but that
wouldn't really be good for anything except slowing down compile time.

Cc: Matt Mackall <[email protected]>
Cc: Theodore Ts'o <[email protected]>
Acked-by: Herbert Xu <[email protected]>
Reviewed-by: Eric Biggers <[email protected]>
Reviewed-by: Dominik Brodowski <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/hw_random/core.c | 1 +
include/linux/hw_random.h | 2 --
include/linux/random.h | 2 ++
3 files changed, 3 insertions(+), 2 deletions(-)

--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -15,6 +15,7 @@
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/hw_random.h>
+#include <linux/random.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/sched/signal.h>
--- a/include/linux/hw_random.h
+++ b/include/linux/hw_random.h
@@ -60,7 +60,5 @@ extern int devm_hwrng_register(struct de
/** Unregister a Hardware Random Number Generator driver. */
extern void hwrng_unregister(struct hwrng *rng);
extern void devm_hwrng_unregister(struct device *dve, struct hwrng *rng);
-/** Feed random bits into the pool. */
-extern void add_hwgenerator_randomness(const void *buffer, size_t count, size_t entropy);

#endif /* LINUX_HWRANDOM_H_ */
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -32,6 +32,8 @@ static inline void add_latent_entropy(vo
extern void add_input_randomness(unsigned int type, unsigned int code,
unsigned int value) __latent_entropy;
extern void add_interrupt_randomness(int irq) __latent_entropy;
+extern void add_hwgenerator_randomness(const void *buffer, size_t count,
+ size_t entropy);

extern void get_random_bytes(void *buf, size_t nbytes);
extern int wait_for_random_bytes(void);



2022-05-28 20:15:27

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 105/111] random: unify batched entropy implementations

From: "Jason A. Donenfeld" <[email protected]>

commit 3092adcef3ffd2ef59634998297ca8358461ebce upstream.

There are currently two separate batched entropy implementations, for
u32 and u64, with nearly identical code, with the goal of avoiding
unaligned memory accesses and letting the buffers be used more
efficiently. Having to maintain these two functions independently is a
bit of a hassle though, considering that they always need to be kept in
sync.

This commit factors them out into a type-generic macro, so that the
expansion produces the same code as before, such that diffing the
assembly shows no differences. This will also make it easier in the
future to add u16 and u8 batches.

This was initially tested using an always_inline function and letting
gcc constant fold the type size in, but the code gen was less efficient,
and in general it was more verbose and harder to follow. So this patch
goes with the boring macro solution, similar to what's already done for
the _wait functions in random.h.

Cc: Dominik Brodowski <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 145 ++++++++++++++++++--------------------------------
1 file changed, 54 insertions(+), 91 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -509,99 +509,62 @@ out_zero_chacha:
* provided by this function is okay, the function wait_for_random_bytes()
* should be called and return 0 at least once at any point prior.
*/
-struct batched_entropy {
- union {
- /*
- * We make this 1.5x a ChaCha block, so that we get the
- * remaining 32 bytes from fast key erasure, plus one full
- * block from the detached ChaCha state. We can increase
- * the size of this later if needed so long as we keep the
- * formula of (integer_blocks + 0.5) * CHACHA_BLOCK_SIZE.
- */
- u64 entropy_u64[CHACHA_BLOCK_SIZE * 3 / (2 * sizeof(u64))];
- u32 entropy_u32[CHACHA_BLOCK_SIZE * 3 / (2 * sizeof(u32))];
- };
- local_lock_t lock;
- unsigned long generation;
- unsigned int position;
-};

+#define DEFINE_BATCHED_ENTROPY(type) \
+struct batch_ ##type { \
+ /* \
+ * We make this 1.5x a ChaCha block, so that we get the \
+ * remaining 32 bytes from fast key erasure, plus one full \
+ * block from the detached ChaCha state. We can increase \
+ * the size of this later if needed so long as we keep the \
+ * formula of (integer_blocks + 0.5) * CHACHA_BLOCK_SIZE. \
+ */ \
+ type entropy[CHACHA_BLOCK_SIZE * 3 / (2 * sizeof(type))]; \
+ local_lock_t lock; \
+ unsigned long generation; \
+ unsigned int position; \
+}; \
+ \
+static DEFINE_PER_CPU(struct batch_ ##type, batched_entropy_ ##type) = { \
+ .lock = INIT_LOCAL_LOCK(batched_entropy_ ##type.lock), \
+ .position = UINT_MAX \
+}; \
+ \
+type get_random_ ##type(void) \
+{ \
+ type ret; \
+ unsigned long flags; \
+ struct batch_ ##type *batch; \
+ unsigned long next_gen; \
+ \
+ warn_unseeded_randomness(); \
+ \
+ if (!crng_ready()) { \
+ _get_random_bytes(&ret, sizeof(ret)); \
+ return ret; \
+ } \
+ \
+ local_lock_irqsave(&batched_entropy_ ##type.lock, flags); \
+ batch = raw_cpu_ptr(&batched_entropy_##type); \
+ \
+ next_gen = READ_ONCE(base_crng.generation); \
+ if (batch->position >= ARRAY_SIZE(batch->entropy) || \
+ next_gen != batch->generation) { \
+ _get_random_bytes(batch->entropy, sizeof(batch->entropy)); \
+ batch->position = 0; \
+ batch->generation = next_gen; \
+ } \
+ \
+ ret = batch->entropy[batch->position]; \
+ batch->entropy[batch->position] = 0; \
+ ++batch->position; \
+ local_unlock_irqrestore(&batched_entropy_ ##type.lock, flags); \
+ return ret; \
+} \
+EXPORT_SYMBOL(get_random_ ##type);

-static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64) = {
- .lock = INIT_LOCAL_LOCK(batched_entropy_u64.lock),
- .position = UINT_MAX
-};
-
-u64 get_random_u64(void)
-{
- u64 ret;
- unsigned long flags;
- struct batched_entropy *batch;
- unsigned long next_gen;
-
- warn_unseeded_randomness();
-
- if (!crng_ready()) {
- _get_random_bytes(&ret, sizeof(ret));
- return ret;
- }
-
- local_lock_irqsave(&batched_entropy_u64.lock, flags);
- batch = raw_cpu_ptr(&batched_entropy_u64);
-
- next_gen = READ_ONCE(base_crng.generation);
- if (batch->position >= ARRAY_SIZE(batch->entropy_u64) ||
- next_gen != batch->generation) {
- _get_random_bytes(batch->entropy_u64, sizeof(batch->entropy_u64));
- batch->position = 0;
- batch->generation = next_gen;
- }
-
- ret = batch->entropy_u64[batch->position];
- batch->entropy_u64[batch->position] = 0;
- ++batch->position;
- local_unlock_irqrestore(&batched_entropy_u64.lock, flags);
- return ret;
-}
-EXPORT_SYMBOL(get_random_u64);
-
-static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32) = {
- .lock = INIT_LOCAL_LOCK(batched_entropy_u32.lock),
- .position = UINT_MAX
-};
-
-u32 get_random_u32(void)
-{
- u32 ret;
- unsigned long flags;
- struct batched_entropy *batch;
- unsigned long next_gen;
-
- warn_unseeded_randomness();
-
- if (!crng_ready()) {
- _get_random_bytes(&ret, sizeof(ret));
- return ret;
- }
-
- local_lock_irqsave(&batched_entropy_u32.lock, flags);
- batch = raw_cpu_ptr(&batched_entropy_u32);
-
- next_gen = READ_ONCE(base_crng.generation);
- if (batch->position >= ARRAY_SIZE(batch->entropy_u32) ||
- next_gen != batch->generation) {
- _get_random_bytes(batch->entropy_u32, sizeof(batch->entropy_u32));
- batch->position = 0;
- batch->generation = next_gen;
- }
-
- ret = batch->entropy_u32[batch->position];
- batch->entropy_u32[batch->position] = 0;
- ++batch->position;
- local_unlock_irqrestore(&batched_entropy_u32.lock, flags);
- return ret;
-}
-EXPORT_SYMBOL(get_random_u32);
+DEFINE_BATCHED_ENTROPY(u64)
+DEFINE_BATCHED_ENTROPY(u32)

#ifdef CONFIG_SMP
/*



2022-05-28 20:16:04

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 074/111] timekeeping: Add raw clock fallback for random_get_entropy()

From: "Jason A. Donenfeld" <[email protected]>

commit 1366992e16bddd5e2d9a561687f367f9f802e2e4 upstream.

The addition of random_get_entropy_fallback() provides access to
whichever time source has the highest frequency, which is useful for
gathering entropy on platforms without available cycle counters. It's
not necessarily as good as being able to quickly access a cycle counter
that the CPU has, but it's still something, even when it falls back to
being jiffies-based.

In the event that a given arch does not define get_cycles(), falling
back to the get_cycles() default implementation that returns 0 is really
not the best we can do. Instead, at least calling
random_get_entropy_fallback() would be preferable, because that always
needs to return _something_, even falling back to jiffies eventually.
It's not as though random_get_entropy_fallback() is super high precision
or guaranteed to be entropic, but basically anything that's not zero all
the time is better than returning zero all the time.

Finally, since random_get_entropy_fallback() is used during extremely
early boot when randomizing freelists in mm_init(), it can be called
before timekeeping has been initialized. In that case there really is
nothing we can do; jiffies hasn't even started ticking yet. So just give
up and return 0.

Suggested-by: Thomas Gleixner <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Reviewed-by: Thomas Gleixner <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Theodore Ts'o <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/linux/timex.h | 8 ++++++++
kernel/time/timekeeping.c | 15 +++++++++++++++
2 files changed, 23 insertions(+)

--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -62,6 +62,8 @@
#include <linux/types.h>
#include <linux/param.h>

+unsigned long random_get_entropy_fallback(void);
+
#include <asm/timex.h>

#ifndef random_get_entropy
@@ -74,8 +76,14 @@
*
* By default we use get_cycles() for this purpose, but individual
* architectures may override this in their asm/timex.h header file.
+ * If a given arch does not have get_cycles(), then we fallback to
+ * using random_get_entropy_fallback().
*/
+#ifdef get_cycles
#define random_get_entropy() ((unsigned long)get_cycles())
+#else
+#define random_get_entropy() random_get_entropy_fallback()
+#endif
#endif

/*
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -17,6 +17,7 @@
#include <linux/clocksource.h>
#include <linux/jiffies.h>
#include <linux/time.h>
+#include <linux/timex.h>
#include <linux/tick.h>
#include <linux/stop_machine.h>
#include <linux/pvclock_gtod.h>
@@ -2380,6 +2381,20 @@ static int timekeeping_validate_timex(co
return 0;
}

+/**
+ * random_get_entropy_fallback - Returns the raw clock source value,
+ * used by random.c for platforms with no valid random_get_entropy().
+ */
+unsigned long random_get_entropy_fallback(void)
+{
+ struct tk_read_base *tkr = &tk_core.timekeeper.tkr_mono;
+ struct clocksource *clock = READ_ONCE(tkr->clock);
+
+ if (unlikely(timekeeping_suspended || !clock))
+ return 0;
+ return clock->read(clock);
+}
+EXPORT_SYMBOL_GPL(random_get_entropy_fallback);

/**
* do_adjtimex() - Accessor function to NTP __do_adjtimex function



2022-05-28 20:16:45

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 102/111] random: make consistent use of buf and len

From: "Jason A. Donenfeld" <[email protected]>

commit a19402634c435a4eae226df53c141cdbb9922e7b upstream.

The current code was a mix of "nbytes", "count", "size", "buffer", "in",
and so forth. Instead, let's clean this up by naming input parameters
"buf" (or "ubuf") and "len", so that you always understand that you're
reading this variety of function argument.

Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 193 +++++++++++++++++++++++--------------------------
include/linux/random.h | 10 +-
2 files changed, 99 insertions(+), 104 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -208,7 +208,7 @@ static void _warn_unseeded_randomness(co
*
* There are a few exported interfaces for use by other drivers:
*
- * void get_random_bytes(void *buf, size_t nbytes)
+ * void get_random_bytes(void *buf, size_t len)
* u32 get_random_u32()
* u64 get_random_u64()
* unsigned int get_random_int()
@@ -249,7 +249,7 @@ static DEFINE_PER_CPU(struct crng, crngs
};

/* Used by crng_reseed() and crng_make_state() to extract a new seed from the input pool. */
-static void extract_entropy(void *buf, size_t nbytes);
+static void extract_entropy(void *buf, size_t len);

/* This extracts a new crng key from the input pool. */
static void crng_reseed(void)
@@ -403,24 +403,24 @@ static void crng_make_state(u32 chacha_s
local_unlock_irqrestore(&crngs.lock, flags);
}

-static void _get_random_bytes(void *buf, size_t nbytes)
+static void _get_random_bytes(void *buf, size_t len)
{
u32 chacha_state[CHACHA_STATE_WORDS];
u8 tmp[CHACHA_BLOCK_SIZE];
- size_t len;
+ size_t first_block_len;

- if (!nbytes)
+ if (!len)
return;

- len = min_t(size_t, 32, nbytes);
- crng_make_state(chacha_state, buf, len);
- nbytes -= len;
- buf += len;
+ first_block_len = min_t(size_t, 32, len);
+ crng_make_state(chacha_state, buf, first_block_len);
+ len -= first_block_len;
+ buf += first_block_len;

- while (nbytes) {
- if (nbytes < CHACHA_BLOCK_SIZE) {
+ while (len) {
+ if (len < CHACHA_BLOCK_SIZE) {
chacha20_block(chacha_state, tmp);
- memcpy(buf, tmp, nbytes);
+ memcpy(buf, tmp, len);
memzero_explicit(tmp, sizeof(tmp));
break;
}
@@ -428,7 +428,7 @@ static void _get_random_bytes(void *buf,
chacha20_block(chacha_state, buf);
if (unlikely(chacha_state[12] == 0))
++chacha_state[13];
- nbytes -= CHACHA_BLOCK_SIZE;
+ len -= CHACHA_BLOCK_SIZE;
buf += CHACHA_BLOCK_SIZE;
}

@@ -445,20 +445,20 @@ static void _get_random_bytes(void *buf,
* wait_for_random_bytes() should be called and return 0 at least once
* at any point prior.
*/
-void get_random_bytes(void *buf, size_t nbytes)
+void get_random_bytes(void *buf, size_t len)
{
warn_unseeded_randomness();
- _get_random_bytes(buf, nbytes);
+ _get_random_bytes(buf, len);
}
EXPORT_SYMBOL(get_random_bytes);

-static ssize_t get_random_bytes_user(void __user *buf, size_t nbytes)
+static ssize_t get_random_bytes_user(void __user *ubuf, size_t len)
{
- size_t len, left, ret = 0;
+ size_t block_len, left, ret = 0;
u32 chacha_state[CHACHA_STATE_WORDS];
u8 output[CHACHA_BLOCK_SIZE];

- if (!nbytes)
+ if (!len)
return 0;

/*
@@ -472,8 +472,8 @@ static ssize_t get_random_bytes_user(voi
* use chacha_state after, so we can simply return those bytes to
* the user directly.
*/
- if (nbytes <= CHACHA_KEY_SIZE) {
- ret = nbytes - copy_to_user(buf, &chacha_state[4], nbytes);
+ if (len <= CHACHA_KEY_SIZE) {
+ ret = len - copy_to_user(ubuf, &chacha_state[4], len);
goto out_zero_chacha;
}

@@ -482,17 +482,17 @@ static ssize_t get_random_bytes_user(voi
if (unlikely(chacha_state[12] == 0))
++chacha_state[13];

- len = min_t(size_t, nbytes, CHACHA_BLOCK_SIZE);
- left = copy_to_user(buf, output, len);
+ block_len = min_t(size_t, len, CHACHA_BLOCK_SIZE);
+ left = copy_to_user(ubuf, output, block_len);
if (left) {
- ret += len - left;
+ ret += block_len - left;
break;
}

- buf += len;
- ret += len;
- nbytes -= len;
- if (!nbytes)
+ ubuf += block_len;
+ ret += block_len;
+ len -= block_len;
+ if (!len)
break;

BUILD_BUG_ON(PAGE_SIZE % CHACHA_BLOCK_SIZE != 0);
@@ -666,24 +666,24 @@ unsigned long randomize_page(unsigned lo
* use. Use get_random_bytes() instead. It returns the number of
* bytes filled in.
*/
-size_t __must_check get_random_bytes_arch(void *buf, size_t nbytes)
+size_t __must_check get_random_bytes_arch(void *buf, size_t len)
{
- size_t left = nbytes;
+ size_t left = len;
u8 *p = buf;

while (left) {
unsigned long v;
- size_t chunk = min_t(size_t, left, sizeof(unsigned long));
+ size_t block_len = min_t(size_t, left, sizeof(unsigned long));

if (!arch_get_random_long(&v))
break;

- memcpy(p, &v, chunk);
- p += chunk;
- left -= chunk;
+ memcpy(p, &v, block_len);
+ p += block_len;
+ left -= block_len;
}

- return nbytes - left;
+ return len - left;
}
EXPORT_SYMBOL(get_random_bytes_arch);

@@ -694,15 +694,15 @@ EXPORT_SYMBOL(get_random_bytes_arch);
*
* Callers may add entropy via:
*
- * static void mix_pool_bytes(const void *in, size_t nbytes)
+ * static void mix_pool_bytes(const void *buf, size_t len)
*
* After which, if added entropy should be credited:
*
- * static void credit_init_bits(size_t nbits)
+ * static void credit_init_bits(size_t bits)
*
* Finally, extract entropy via:
*
- * static void extract_entropy(void *buf, size_t nbytes)
+ * static void extract_entropy(void *buf, size_t len)
*
**********************************************************************/

@@ -724,9 +724,9 @@ static struct {
.lock = __SPIN_LOCK_UNLOCKED(input_pool.lock),
};

-static void _mix_pool_bytes(const void *in, size_t nbytes)
+static void _mix_pool_bytes(const void *buf, size_t len)
{
- blake2s_update(&input_pool.hash, in, nbytes);
+ blake2s_update(&input_pool.hash, buf, len);
}

/*
@@ -734,12 +734,12 @@ static void _mix_pool_bytes(const void *
* update the initialization bit counter; the caller should call
* credit_init_bits if this is appropriate.
*/
-static void mix_pool_bytes(const void *in, size_t nbytes)
+static void mix_pool_bytes(const void *buf, size_t len)
{
unsigned long flags;

spin_lock_irqsave(&input_pool.lock, flags);
- _mix_pool_bytes(in, nbytes);
+ _mix_pool_bytes(buf, len);
spin_unlock_irqrestore(&input_pool.lock, flags);
}

@@ -747,7 +747,7 @@ static void mix_pool_bytes(const void *i
* This is an HKDF-like construction for using the hashed collected entropy
* as a PRF key, that's then expanded block-by-block.
*/
-static void extract_entropy(void *buf, size_t nbytes)
+static void extract_entropy(void *buf, size_t len)
{
unsigned long flags;
u8 seed[BLAKE2S_HASH_SIZE], next_key[BLAKE2S_HASH_SIZE];
@@ -776,12 +776,12 @@ static void extract_entropy(void *buf, s
spin_unlock_irqrestore(&input_pool.lock, flags);
memzero_explicit(next_key, sizeof(next_key));

- while (nbytes) {
- i = min_t(size_t, nbytes, BLAKE2S_HASH_SIZE);
+ while (len) {
+ i = min_t(size_t, len, BLAKE2S_HASH_SIZE);
/* output = HASHPRF(seed, RDSEED || ++counter) */
++block.counter;
blake2s(buf, (u8 *)&block, seed, i, sizeof(block), sizeof(seed));
- nbytes -= i;
+ len -= i;
buf += i;
}

@@ -789,16 +789,16 @@ static void extract_entropy(void *buf, s
memzero_explicit(&block, sizeof(block));
}

-static void credit_init_bits(size_t nbits)
+static void credit_init_bits(size_t bits)
{
static struct execute_work set_ready;
unsigned int new, orig, add;
unsigned long flags;

- if (crng_ready() || !nbits)
+ if (crng_ready() || !bits)
return;

- add = min_t(size_t, nbits, POOL_BITS);
+ add = min_t(size_t, bits, POOL_BITS);

do {
orig = READ_ONCE(input_pool.init_bits);
@@ -834,13 +834,11 @@ static void credit_init_bits(size_t nbit
* The following exported functions are used for pushing entropy into
* the above entropy accumulation routines:
*
- * void add_device_randomness(const void *buf, size_t size);
- * void add_hwgenerator_randomness(const void *buffer, size_t count,
- * size_t entropy);
- * void add_bootloader_randomness(const void *buf, size_t size);
+ * void add_device_randomness(const void *buf, size_t len);
+ * void add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy);
+ * void add_bootloader_randomness(const void *buf, size_t len);
* void add_interrupt_randomness(int irq);
- * void add_input_randomness(unsigned int type, unsigned int code,
- * unsigned int value);
+ * void add_input_randomness(unsigned int type, unsigned int code, unsigned int value);
* void add_disk_randomness(struct gendisk *disk);
*
* add_device_randomness() adds data to the input pool that
@@ -904,7 +902,7 @@ int __init random_init(const char *comma
{
ktime_t now = ktime_get_real();
unsigned int i, arch_bytes;
- unsigned long rv;
+ unsigned long entropy;

#if defined(LATENT_ENTROPY_PLUGIN)
static const u8 compiletime_seed[BLAKE2S_BLOCK_SIZE] __initconst __latent_entropy;
@@ -912,13 +910,13 @@ int __init random_init(const char *comma
#endif

for (i = 0, arch_bytes = BLAKE2S_BLOCK_SIZE;
- i < BLAKE2S_BLOCK_SIZE; i += sizeof(rv)) {
- if (!arch_get_random_seed_long_early(&rv) &&
- !arch_get_random_long_early(&rv)) {
- rv = random_get_entropy();
- arch_bytes -= sizeof(rv);
+ i < BLAKE2S_BLOCK_SIZE; i += sizeof(entropy)) {
+ if (!arch_get_random_seed_long_early(&entropy) &&
+ !arch_get_random_long_early(&entropy)) {
+ entropy = random_get_entropy();
+ arch_bytes -= sizeof(entropy);
}
- _mix_pool_bytes(&rv, sizeof(rv));
+ _mix_pool_bytes(&entropy, sizeof(entropy));
}
_mix_pool_bytes(&now, sizeof(now));
_mix_pool_bytes(utsname(), sizeof(*(utsname())));
@@ -941,14 +939,14 @@ int __init random_init(const char *comma
* the entropy pool having similar initial state across largely
* identical devices.
*/
-void add_device_randomness(const void *buf, size_t size)
+void add_device_randomness(const void *buf, size_t len)
{
unsigned long entropy = random_get_entropy();
unsigned long flags;

spin_lock_irqsave(&input_pool.lock, flags);
_mix_pool_bytes(&entropy, sizeof(entropy));
- _mix_pool_bytes(buf, size);
+ _mix_pool_bytes(buf, len);
spin_unlock_irqrestore(&input_pool.lock, flags);
}
EXPORT_SYMBOL(add_device_randomness);
@@ -958,10 +956,9 @@ EXPORT_SYMBOL(add_device_randomness);
* Those devices may produce endless random bits and will be throttled
* when our pool is full.
*/
-void add_hwgenerator_randomness(const void *buffer, size_t count,
- size_t entropy)
+void add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy)
{
- mix_pool_bytes(buffer, count);
+ mix_pool_bytes(buf, len);
credit_init_bits(entropy);

/*
@@ -977,11 +974,11 @@ EXPORT_SYMBOL_GPL(add_hwgenerator_random
* Handle random seed passed by bootloader, and credit it if
* CONFIG_RANDOM_TRUST_BOOTLOADER is set.
*/
-void add_bootloader_randomness(const void *buf, size_t size)
+void add_bootloader_randomness(const void *buf, size_t len)
{
- mix_pool_bytes(buf, size);
+ mix_pool_bytes(buf, len);
if (trust_bootloader)
- credit_init_bits(size * 8);
+ credit_init_bits(len * 8);
}
EXPORT_SYMBOL_GPL(add_bootloader_randomness);

@@ -1181,8 +1178,7 @@ static void add_timer_randomness(struct
credit_init_bits(bits);
}

-void add_input_randomness(unsigned int type, unsigned int code,
- unsigned int value)
+void add_input_randomness(unsigned int type, unsigned int code, unsigned int value)
{
static unsigned char last_value;
static struct timer_rand_state input_timer_state = { INITIAL_JIFFIES };
@@ -1301,8 +1297,7 @@ static void try_to_generate_entropy(void
*
**********************************************************************/

-SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, unsigned int,
- flags)
+SYSCALL_DEFINE3(getrandom, char __user *, ubuf, size_t, len, unsigned int, flags)
{
if (flags & ~(GRND_NONBLOCK | GRND_RANDOM | GRND_INSECURE))
return -EINVAL;
@@ -1314,8 +1309,8 @@ SYSCALL_DEFINE3(getrandom, char __user *
if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM))
return -EINVAL;

- if (count > INT_MAX)
- count = INT_MAX;
+ if (len > INT_MAX)
+ len = INT_MAX;

if (!crng_ready() && !(flags & GRND_INSECURE)) {
int ret;
@@ -1326,7 +1321,7 @@ SYSCALL_DEFINE3(getrandom, char __user *
if (unlikely(ret))
return ret;
}
- return get_random_bytes_user(buf, count);
+ return get_random_bytes_user(ubuf, len);
}

static __poll_t random_poll(struct file *file, poll_table *wait)
@@ -1335,21 +1330,21 @@ static __poll_t random_poll(struct file
return crng_ready() ? EPOLLIN | EPOLLRDNORM : EPOLLOUT | EPOLLWRNORM;
}

-static int write_pool(const char __user *ubuf, size_t count)
+static int write_pool(const char __user *ubuf, size_t len)
{
- size_t len;
+ size_t block_len;
int ret = 0;
u8 block[BLAKE2S_BLOCK_SIZE];

- while (count) {
- len = min(count, sizeof(block));
- if (copy_from_user(block, ubuf, len)) {
+ while (len) {
+ block_len = min(len, sizeof(block));
+ if (copy_from_user(block, ubuf, block_len)) {
ret = -EFAULT;
goto out;
}
- count -= len;
- ubuf += len;
- mix_pool_bytes(block, len);
+ len -= block_len;
+ ubuf += block_len;
+ mix_pool_bytes(block, block_len);
cond_resched();
}

@@ -1358,20 +1353,20 @@ out:
return ret;
}

-static ssize_t random_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
+static ssize_t random_write(struct file *file, const char __user *ubuf,
+ size_t len, loff_t *ppos)
{
int ret;

- ret = write_pool(buffer, count);
+ ret = write_pool(ubuf, len);
if (ret)
return ret;

- return (ssize_t)count;
+ return (ssize_t)len;
}

-static ssize_t urandom_read(struct file *file, char __user *buf, size_t nbytes,
- loff_t *ppos)
+static ssize_t urandom_read(struct file *file, char __user *ubuf,
+ size_t len, loff_t *ppos)
{
static int maxwarn = 10;

@@ -1381,22 +1376,22 @@ static ssize_t urandom_read(struct file
else if (ratelimit_disable || __ratelimit(&urandom_warning)) {
--maxwarn;
pr_notice("%s: uninitialized urandom read (%zd bytes read)\n",
- current->comm, nbytes);
+ current->comm, len);
}
}

- return get_random_bytes_user(buf, nbytes);
+ return get_random_bytes_user(ubuf, len);
}

-static ssize_t random_read(struct file *file, char __user *buf, size_t nbytes,
- loff_t *ppos)
+static ssize_t random_read(struct file *file, char __user *ubuf,
+ size_t len, loff_t *ppos)
{
int ret;

ret = wait_for_random_bytes();
if (ret != 0)
return ret;
- return get_random_bytes_user(buf, nbytes);
+ return get_random_bytes_user(ubuf, len);
}

static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
@@ -1521,7 +1516,7 @@ static u8 sysctl_bootid[UUID_SIZE];
* UUID. The difference is in whether table->data is NULL; if it is,
* then a new UUID is generated and returned to the user.
*/
-static int proc_do_uuid(struct ctl_table *table, int write, void *buffer,
+static int proc_do_uuid(struct ctl_table *table, int write, void *buf,
size_t *lenp, loff_t *ppos)
{
u8 tmp_uuid[UUID_SIZE], *uuid;
@@ -1548,14 +1543,14 @@ static int proc_do_uuid(struct ctl_table
}

snprintf(uuid_string, sizeof(uuid_string), "%pU", uuid);
- return proc_dostring(&fake_table, 0, buffer, lenp, ppos);
+ return proc_dostring(&fake_table, 0, buf, lenp, ppos);
}

/* The same as proc_dointvec, but writes don't change anything. */
-static int proc_do_rointvec(struct ctl_table *table, int write, void *buffer,
+static int proc_do_rointvec(struct ctl_table *table, int write, void *buf,
size_t *lenp, loff_t *ppos)
{
- return write ? 0 : proc_dointvec(table, 0, buffer, lenp, ppos);
+ return write ? 0 : proc_dointvec(table, 0, buf, lenp, ppos);
}

static struct ctl_table random_table[] = {
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -12,12 +12,12 @@

struct notifier_block;

-void add_device_randomness(const void *, size_t);
-void add_bootloader_randomness(const void *, size_t);
+void add_device_randomness(const void *buf, size_t len);
+void add_bootloader_randomness(const void *buf, size_t len);
void add_input_randomness(unsigned int type, unsigned int code,
unsigned int value) __latent_entropy;
void add_interrupt_randomness(int irq) __latent_entropy;
-void add_hwgenerator_randomness(const void *buffer, size_t count, size_t entropy);
+void add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy);

#if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__)
static inline void add_latent_entropy(void)
@@ -28,8 +28,8 @@ static inline void add_latent_entropy(vo
static inline void add_latent_entropy(void) { }
#endif

-void get_random_bytes(void *buf, size_t nbytes);
-size_t __must_check get_random_bytes_arch(void *buf, size_t nbytes);
+void get_random_bytes(void *buf, size_t len);
+size_t __must_check get_random_bytes_arch(void *buf, size_t len);
u32 get_random_u32(void);
u64 get_random_u64(void);
static inline unsigned int get_random_int(void)



2022-05-28 20:18:22

by Fox Chen

[permalink] [raw]
Subject: RE: [PATCH 5.17 000/111] 5.17.12-rc1 review

On Fri, 27 May 2022 10:48:32 +0200, Greg Kroah-Hartman <[email protected]> wrote:
> This is the start of the stable review cycle for the 5.17.12 release.
> There are 111 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Sun, 29 May 2022 08:46:36 +0000.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.17.12-rc1.gz
> or in the git tree and branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.17.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
>

5.17.12-rc1 Successfully Compiled and booted on my Raspberry PI 4b (8g) (bcm2711)

Tested-by: Fox Chen <[email protected]>


2022-05-28 20:21:49

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 067/111] random: fix sysctl documentation nits

From: "Jason A. Donenfeld" <[email protected]>

commit 069c4ea6871c18bd368f27756e0f91ffb524a788 upstream.

A semicolon was missing, and the almost-alphabetical-but-not ordering
was confusing, so regroup these by category instead.

Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
Documentation/admin-guide/sysctl/kernel.rst | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

--- a/Documentation/admin-guide/sysctl/kernel.rst
+++ b/Documentation/admin-guide/sysctl/kernel.rst
@@ -1025,6 +1025,9 @@ This is a directory, with the following
* ``boot_id``: a UUID generated the first time this is retrieved, and
unvarying after that;

+* ``uuid``: a UUID generated every time this is retrieved (this can
+ thus be used to generate UUIDs at will);
+
* ``entropy_avail``: the pool's entropy count, in bits;

* ``poolsize``: the entropy pool size, in bits;
@@ -1032,10 +1035,7 @@ This is a directory, with the following
* ``urandom_min_reseed_secs``: obsolete (used to determine the minimum
number of seconds between urandom pool reseeding). This file is
writable for compatibility purposes, but writing to it has no effect
- on any RNG behavior.
-
-* ``uuid``: a UUID generated every time this is retrieved (this can
- thus be used to generate UUIDs at will);
+ on any RNG behavior;

* ``write_wakeup_threshold``: when the entropy count drops below this
(as a number of bits), processes waiting to write to ``/dev/random``



2022-05-28 20:22:05

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 026/111] random: add proper SPDX header

From: "Jason A. Donenfeld" <[email protected]>

commit a07fdae346c35c6ba286af1c88e0effcfa330bf9 upstream.

Convert the current license into the SPDX notation of "(GPL-2.0 OR
BSD-3-Clause)". This infers GPL-2.0 from the text "ALTERNATIVELY, this
product may be distributed under the terms of the GNU General Public
License, in which case the provisions of the GPL are required INSTEAD OF
the above restrictions" and it infers BSD-3-Clause from the verbatim
BSD 3 clause license in the file.

Cc: Thomas Gleixner <[email protected]>
Cc: Theodore Ts'o <[email protected]>
Cc: Dominik Brodowski <[email protected]>
Reviewed-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 37 +------------------------------------
1 file changed, 1 insertion(+), 36 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1,44 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
- * random.c -- A strong random number generator
- *
* Copyright (C) 2017-2022 Jason A. Donenfeld <[email protected]>. All Rights Reserved.
- *
* Copyright Matt Mackall <[email protected]>, 2003, 2004, 2005
- *
* Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All
* rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * ALTERNATIVELY, this product may be distributed under the terms of
- * the GNU General Public License, in which case the provisions of the GPL are
- * required INSTEAD OF the above restrictions. (This clause is
- * necessary due to a potential bad interaction between the GPL and
- * the restrictions contained in a BSD-style copyright.)
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
*/

/*



2022-05-28 20:22:19

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 089/111] random: do not use input pool from hard IRQs

From: "Jason A. Donenfeld" <[email protected]>

commit e3e33fc2ea7fcefd0d761db9d6219f83b4248f5c upstream.

Years ago, a separate fast pool was added for interrupts, so that the
cost associated with taking the input pool spinlocks and mixing into it
would be avoided in places where latency is critical. However, one
oversight was that add_input_randomness() and add_disk_randomness()
still sometimes are called directly from the interrupt handler, rather
than being deferred to a thread. This means that some unlucky interrupts
will be caught doing a blake2s_compress() call and potentially spinning
on input_pool.lock, which can also be taken by unprivileged users by
writing into /dev/urandom.

In order to fix this, add_timer_randomness() now checks whether it is
being called from a hard IRQ and if so, just mixes into the per-cpu IRQ
fast pool using fast_mix(), which is much faster and can be done
lock-free. A nice consequence of this, as well, is that it means hard
IRQ context FPU support is likely no longer useful.

The entropy estimation algorithm used by add_timer_randomness() is also
somewhat different than the one used for add_interrupt_randomness(). The
former looks at deltas of deltas of deltas, while the latter just waits
for 64 interrupts for one bit or for one second since the last bit. In
order to bridge these, and since add_interrupt_randomness() runs after
an add_timer_randomness() that's called from hard IRQ, we add to the
fast pool credit the related amount, and then subtract one to account
for add_interrupt_randomness()'s contribution.

A downside of this, however, is that the num argument is potentially
attacker controlled, which puts a bit more pressure on the fast_mix()
sponge to do more than it's really intended to do. As a mitigating
factor, the first 96 bits of input aren't attacker controlled (a cycle
counter followed by zeros), which means it's essentially two rounds of
siphash rather than one, which is somewhat better. It's also not that
much different from add_interrupt_randomness()'s use of the irq stack
instruction pointer register.

Cc: Thomas Gleixner <[email protected]>
Cc: Filipe Manana <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Theodore Ts'o <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 51 +++++++++++++++++++++++++++++++++++---------------
1 file changed, 36 insertions(+), 15 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1084,6 +1084,7 @@ static void mix_interrupt_randomness(str
* we don't wind up "losing" some.
*/
unsigned long pool[2];
+ unsigned int count;

/* Check to see if we're running on the wrong CPU due to hotplug. */
local_irq_disable();
@@ -1097,12 +1098,13 @@ static void mix_interrupt_randomness(str
* consistent view, before we reenable irqs again.
*/
memcpy(pool, fast_pool->pool, sizeof(pool));
+ count = fast_pool->count;
fast_pool->count = 0;
fast_pool->last = jiffies;
local_irq_enable();

mix_pool_bytes(pool, sizeof(pool));
- credit_init_bits(1);
+ credit_init_bits(max(1u, (count & U16_MAX) / 64));

memzero_explicit(pool, sizeof(pool));
}
@@ -1142,22 +1144,30 @@ struct timer_rand_state {

/*
* This function adds entropy to the entropy "pool" by using timing
- * delays. It uses the timer_rand_state structure to make an estimate
- * of how many bits of entropy this call has added to the pool.
- *
- * The number "num" is also added to the pool - it should somehow describe
- * the type of event which just happened. This is currently 0-255 for
- * keyboard scan codes, and 256 upwards for interrupts.
+ * delays. It uses the timer_rand_state structure to make an estimate
+ * of how many bits of entropy this call has added to the pool. The
+ * value "num" is also added to the pool; it should somehow describe
+ * the type of event that just happened.
*/
static void add_timer_randomness(struct timer_rand_state *state, unsigned int num)
{
unsigned long entropy = random_get_entropy(), now = jiffies, flags;
long delta, delta2, delta3;
+ unsigned int bits;

- spin_lock_irqsave(&input_pool.lock, flags);
- _mix_pool_bytes(&entropy, sizeof(entropy));
- _mix_pool_bytes(&num, sizeof(num));
- spin_unlock_irqrestore(&input_pool.lock, flags);
+ /*
+ * If we're in a hard IRQ, add_interrupt_randomness() will be called
+ * sometime after, so mix into the fast pool.
+ */
+ if (in_hardirq()) {
+ fast_mix(this_cpu_ptr(&irq_randomness)->pool,
+ (unsigned long[2]){ entropy, num });
+ } else {
+ spin_lock_irqsave(&input_pool.lock, flags);
+ _mix_pool_bytes(&entropy, sizeof(entropy));
+ _mix_pool_bytes(&num, sizeof(num));
+ spin_unlock_irqrestore(&input_pool.lock, flags);
+ }

if (crng_ready())
return;
@@ -1188,11 +1198,22 @@ static void add_timer_randomness(struct
delta = delta3;

/*
- * delta is now minimum absolute delta.
- * Round down by 1 bit on general principles,
- * and limit entropy estimate to 12 bits.
+ * delta is now minimum absolute delta. Round down by 1 bit
+ * on general principles, and limit entropy estimate to 11 bits.
+ */
+ bits = min(fls(delta >> 1), 11);
+
+ /*
+ * As mentioned above, if we're in a hard IRQ, add_interrupt_randomness()
+ * will run after this, which uses a different crediting scheme of 1 bit
+ * per every 64 interrupts. In order to let that function do accounting
+ * close to the one in this function, we credit a full 64/64 bit per bit,
+ * and then subtract one to account for the extra one added.
*/
- credit_init_bits(min_t(unsigned int, fls(delta >> 1), 11));
+ if (in_hardirq())
+ this_cpu_ptr(&irq_randomness)->count += max(1u, bits * 64) - 1;
+ else
+ credit_init_bits(bits);
}

void add_input_randomness(unsigned int type, unsigned int code,



2022-05-28 20:26:49

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 029/111] random: remove useless header comment

From: "Jason A. Donenfeld" <[email protected]>

commit 6071a6c0fba2d747742cadcbb3ba26ed756ed73b upstream.

This really adds nothing at all useful.

Cc: Theodore Ts'o <[email protected]>
Reviewed-by: Dominik Brodowski <[email protected]>
Reviewed-by: Eric Biggers <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/linux/random.h | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)

--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -1,9 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * include/linux/random.h
- *
- * Include file for the random number generator.
- */
+
#ifndef _LINUX_RANDOM_H
#define _LINUX_RANDOM_H




2022-05-28 20:28:51

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 108/111] random: wire up fops->splice_{read,write}_iter()

From: Jens Axboe <[email protected]>

commit 79025e727a846be6fd215ae9cdb654368ac3f9a6 upstream.

Now that random/urandom is using {read,write}_iter, we can wire it up to
using the generic splice handlers.

Fixes: 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops")
Signed-off-by: Jens Axboe <[email protected]>
[Jason: added the splice_write path. Note that sendfile() and such still
does not work for read, though it does for write, because of a file
type restriction in splice_direct_to_actor(), which I'll address
separately.]
Cc: Al Viro <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 4 ++++
1 file changed, 4 insertions(+)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1384,6 +1384,8 @@ const struct file_operations random_fops
.compat_ioctl = compat_ptr_ioctl,
.fasync = random_fasync,
.llseek = noop_llseek,
+ .splice_read = generic_file_splice_read,
+ .splice_write = iter_file_splice_write,
};

const struct file_operations urandom_fops = {
@@ -1393,6 +1395,8 @@ const struct file_operations urandom_fop
.compat_ioctl = compat_ptr_ioctl,
.fasync = random_fasync,
.llseek = noop_llseek,
+ .splice_read = generic_file_splice_read,
+ .splice_write = iter_file_splice_write,
};





2022-05-28 20:29:59

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 068/111] init: call time_init() before rand_initialize()

From: "Jason A. Donenfeld" <[email protected]>

commit fe222a6ca2d53c38433cba5d3be62a39099e708e upstream.

Currently time_init() is called after rand_initialize(), but
rand_initialize() makes use of the timer on various platforms, and
sometimes this timer needs to be initialized by time_init() first. In
order for random_get_entropy() to not return zero during early boot when
it's potentially used as an entropy source, reverse the order of these
two calls. The block doing random initialization was right before
time_init() before, so changing the order shouldn't have any complicated
effects.

Cc: Andrew Morton <[email protected]>
Reviewed-by: Stafford Horne <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
init/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/init/main.c
+++ b/init/main.c
@@ -1035,11 +1035,13 @@ asmlinkage __visible void __init __no_sa
softirq_init();
timekeeping_init();
kfence_init();
+ time_init();

/*
* For best initial stack canary entropy, prepare it after:
* - setup_arch() for any UEFI RNG entropy and boot cmdline access
* - timekeeping_init() for ktime entropy used in rand_initialize()
+ * - time_init() for making random_get_entropy() work on some platforms
* - rand_initialize() to get any arch-specific entropy like RDRAND
* - add_latent_entropy() to get any latent entropy
* - adding command line entropy
@@ -1049,7 +1051,6 @@ asmlinkage __visible void __init __no_sa
add_device_randomness(command_line, strlen(command_line));
boot_init_stack_canary();

- time_init();
perf_event_init();
profile_init();
call_function_init();



2022-05-28 20:32:33

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH 5.17 000/111] 5.17.12-rc1 review

On Fri, May 27, 2022 at 10:48:32AM +0200, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.17.12 release.
> There are 111 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Sun, 29 May 2022 08:46:36 +0000.
> Anything received after that time might be too late.
>

Build results:
total: 155 pass: 155 fail: 0
Qemu test results:
total: 489 pass: 489 fail: 0

Tested-by: Guenter Roeck <[email protected]>

Guenter

2022-05-28 20:33:36

by Sudip Mukherjee

[permalink] [raw]
Subject: Re: [PATCH 5.17 000/111] 5.17.12-rc1 review

Hi Greg,

On Fri, May 27, 2022 at 10:48:32AM +0200, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.17.12 release.
> There are 111 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Sun, 29 May 2022 08:46:36 +0000.
> Anything received after that time might be too late.

Build test:
mips (gcc version 11.3.1 20220517): 60 configs -> no failure
arm (gcc version 11.3.1 20220517): 100 configs -> no new failure
arm64 (gcc version 11.3.1 20220517): 3 configs -> no failure
x86_64 (gcc version 11.3.1 20220517): 4 configs -> no failure

Boot test:
x86_64: Booted on my test laptop. No regression.
arm64: Booted on rpi4b (4GB model). No regression. [1]
mips: Booted on ci20 board. No regression. [2]

[1]. https://openqa.qa.codethink.co.uk/tests/1223
[2]. https://openqa.qa.codethink.co.uk/tests/1224

Tested-by: Sudip Mukherjee <[email protected]>

--
Regards
Sudip


2022-05-28 20:34:06

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 022/111] random: fix locking for crng_init in crng_reseed()

From: Dominik Brodowski <[email protected]>

commit 7191c628fe07b70d3f37de736d173d1b115396ed upstream.

crng_init is protected by primary_crng->lock. Therefore, we need
to hold this lock when increasing crng_init to 2. As we shouldn't
hold this lock for too long, only hold it for those parts which
require protection.

Signed-off-by: Dominik Brodowski <[email protected]>
Reviewed-by: Eric Biggers <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -502,6 +502,7 @@ static void crng_reseed(void)
int entropy_count;
unsigned long next_gen;
u8 key[CHACHA_KEY_SIZE];
+ bool finalize_init = false;

/*
* First we make sure we have POOL_MIN_BITS of entropy in the pool,
@@ -529,12 +530,14 @@ static void crng_reseed(void)
++next_gen;
WRITE_ONCE(base_crng.generation, next_gen);
WRITE_ONCE(base_crng.birth, jiffies);
- spin_unlock_irqrestore(&base_crng.lock, flags);
- memzero_explicit(key, sizeof(key));
-
if (crng_init < 2) {
invalidate_batched_entropy();
crng_init = 2;
+ finalize_init = true;
+ }
+ spin_unlock_irqrestore(&base_crng.lock, flags);
+ memzero_explicit(key, sizeof(key));
+ if (finalize_init) {
process_random_ready_list();
wake_up_interruptible(&crng_init_wait);
kill_fasync(&fasync, SIGIO, POLL_IN);



2022-05-28 20:34:48

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 041/111] random: check for crng_init == 0 in add_device_randomness()

From: "Jason A. Donenfeld" <[email protected]>

commit 1daf2f387652bf3a7044aea042f5023b3f6b189b upstream.

This has no real functional change, as crng_pre_init_inject() (and
before that, crng_slow_init()) always checks for == 0, not >= 2. So
correct the outer unlocked change to reflect that. Before this used
crng_ready(), which was not correct.

Cc: Theodore Ts'o <[email protected]>
Reviewed-by: Dominik Brodowski <[email protected]>
Reviewed-by: Eric Biggers <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1020,7 +1020,7 @@ void add_device_randomness(const void *b
unsigned long time = random_get_entropy() ^ jiffies;
unsigned long flags;

- if (!crng_ready() && size)
+ if (crng_init == 0 && size)
crng_pre_init_inject(buf, size, false, false);

spin_lock_irqsave(&input_pool.lock, flags);



2022-05-28 20:35:11

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 016/111] random: absorb fast pool into input pool after fast load

From: "Jason A. Donenfeld" <[email protected]>

commit c30c575db4858f0bbe5e315ff2e529c782f33a1f upstream.

During crng_init == 0, we never credit entropy in add_interrupt_
randomness(), but instead dump it directly into the primary_crng. That's
fine, except for the fact that we then wind up throwing away that
entropy later when we switch to extracting from the input pool and
xoring into (and later in this series overwriting) the primary_crng key.
The two other early init sites -- add_hwgenerator_randomness()'s use
crng_fast_load() and add_device_ randomness()'s use of crng_slow_load()
-- always additionally give their inputs to the input pool. But not
add_interrupt_randomness().

This commit fixes that shortcoming by calling mix_pool_bytes() after
crng_fast_load() in add_interrupt_randomness(). That's partially
verboten on PREEMPT_RT, where it implies taking spinlock_t from an IRQ
handler. But this also only happens during early boot and then never
again after that. Plus it's a trylock so it has the same considerations
as calling crng_fast_load(), which we're already using.

Cc: Theodore Ts'o <[email protected]>
Reviewed-by: Dominik Brodowski <[email protected]>
Reviewed-by: Eric Biggers <[email protected]>
Suggested-by: Eric Biggers <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 4 ++++
1 file changed, 4 insertions(+)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -850,6 +850,10 @@ void add_interrupt_randomness(int irq)
crng_fast_load((u8 *)fast_pool->pool, sizeof(fast_pool->pool)) > 0) {
fast_pool->count = 0;
fast_pool->last = now;
+ if (spin_trylock(&input_pool.lock)) {
+ _mix_pool_bytes(&fast_pool->pool, sizeof(fast_pool->pool));
+ spin_unlock(&input_pool.lock);
+ }
}
return;
}



2022-05-28 20:36:47

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 013/111] random: inline leaves of rand_initialize()

From: "Jason A. Donenfeld" <[email protected]>

commit 8566417221fcec51346ec164e920dacb979c6b5f upstream.

This is a preparatory commit for the following one. We simply inline the
various functions that rand_initialize() calls that have no other
callers. The compiler was doing this anyway before. Doing this will
allow us to reorganize this after. We can then move the trust_cpu and
parse_trust_cpu definitions a bit closer to where they're actually used,
which makes the code easier to read.

Cc: Theodore Ts'o <[email protected]>
Reviewed-by: Dominik Brodowski <[email protected]>
Reviewed-by: Eric Biggers <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 90 ++++++++++++++++++--------------------------------
1 file changed, 33 insertions(+), 57 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -476,42 +476,6 @@ static DECLARE_WAIT_QUEUE_HEAD(crng_init

static void invalidate_batched_entropy(void);

-static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
-static int __init parse_trust_cpu(char *arg)
-{
- return kstrtobool(arg, &trust_cpu);
-}
-early_param("random.trust_cpu", parse_trust_cpu);
-
-static bool __init crng_init_try_arch_early(void)
-{
- int i;
- bool arch_init = true;
- unsigned long rv;
-
- for (i = 4; i < 16; i++) {
- if (!arch_get_random_seed_long_early(&rv) &&
- !arch_get_random_long_early(&rv)) {
- rv = random_get_entropy();
- arch_init = false;
- }
- primary_crng.state[i] ^= rv;
- }
-
- return arch_init;
-}
-
-static void __init crng_initialize(void)
-{
- extract_entropy(&primary_crng.state[4], sizeof(u32) * 12);
- if (crng_init_try_arch_early() && trust_cpu && crng_init < 2) {
- invalidate_batched_entropy();
- crng_init = 2;
- pr_notice("crng init done (trusting CPU's manufacturer)\n");
- }
- primary_crng.init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
-}
-
/*
* crng_fast_load() can be called by code in the interrupt service
* path. So we can't afford to dilly-dally. Returns the number of
@@ -1220,17 +1184,28 @@ int __must_check get_random_bytes_arch(v
}
EXPORT_SYMBOL(get_random_bytes_arch);

+static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
+static int __init parse_trust_cpu(char *arg)
+{
+ return kstrtobool(arg, &trust_cpu);
+}
+early_param("random.trust_cpu", parse_trust_cpu);
+
/*
- * init_std_data - initialize pool with system data
- *
- * This function clears the pool's entropy count and mixes some system
- * data into the pool to prepare it for use. The pool is not cleared
- * as that can only decrease the entropy in the pool.
+ * Note that setup_arch() may call add_device_randomness()
+ * long before we get here. This allows seeding of the pools
+ * with some platform dependent data very early in the boot
+ * process. But it limits our options here. We must use
+ * statically allocated structures that already have all
+ * initializations complete at compile time. We should also
+ * take care not to overwrite the precious per platform data
+ * we were given.
*/
-static void __init init_std_data(void)
+int __init rand_initialize(void)
{
int i;
ktime_t now = ktime_get_real();
+ bool arch_init = true;
unsigned long rv;

mix_pool_bytes(&now, sizeof(now));
@@ -1241,22 +1216,23 @@ static void __init init_std_data(void)
mix_pool_bytes(&rv, sizeof(rv));
}
mix_pool_bytes(utsname(), sizeof(*(utsname())));
-}

-/*
- * Note that setup_arch() may call add_device_randomness()
- * long before we get here. This allows seeding of the pools
- * with some platform dependent data very early in the boot
- * process. But it limits our options here. We must use
- * statically allocated structures that already have all
- * initializations complete at compile time. We should also
- * take care not to overwrite the precious per platform data
- * we were given.
- */
-int __init rand_initialize(void)
-{
- init_std_data();
- crng_initialize();
+ extract_entropy(&primary_crng.state[4], sizeof(u32) * 12);
+ for (i = 4; i < 16; i++) {
+ if (!arch_get_random_seed_long_early(&rv) &&
+ !arch_get_random_long_early(&rv)) {
+ rv = random_get_entropy();
+ arch_init = false;
+ }
+ primary_crng.state[i] ^= rv;
+ }
+ if (arch_init && trust_cpu && crng_init < 2) {
+ invalidate_batched_entropy();
+ crng_init = 2;
+ pr_notice("crng init done (trusting CPU's manufacturer)\n");
+ }
+ primary_crng.init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
+
if (ratelimit_disable) {
urandom_warning.interval = 0;
unseeded_warning.interval = 0;



2022-05-28 20:37:29

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 045/111] random: only wake up writers after zap if threshold was passed

From: "Jason A. Donenfeld" <[email protected]>

commit a3f9e8910e1584d7725ef7d5ac870920d42d0bb4 upstream.

The only time that we need to wake up /dev/random writers on
RNDCLEARPOOL/RNDZAPPOOL is when we're changing from a value that is
greater than or equal to POOL_MIN_BITS to zero, because if we're
changing from below POOL_MIN_BITS to zero, the writers are already
unblocked.

Cc: Theodore Ts'o <[email protected]>
Reviewed-by: Dominik Brodowski <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1582,7 +1582,7 @@ static long random_ioctl(struct file *f,
*/
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (xchg(&input_pool.entropy_count, 0)) {
+ if (xchg(&input_pool.entropy_count, 0) >= POOL_MIN_BITS) {
wake_up_interruptible(&random_write_wait);
kill_fasync(&fasync, SIGIO, POLL_OUT);
}



2022-05-28 20:37:50

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 054/111] random: reseed more often immediately after booting

From: "Jason A. Donenfeld" <[email protected]>

commit 7a7ff644aeaf071d433caffb3b8ea57354b55bd3 upstream.

In order to chip away at the "premature first" problem, we augment our
existing entropy accounting with more frequent reseedings at boot.

The idea is that at boot, we're getting entropy from various places, and
we're not very sure which of early boot entropy is good and which isn't.
Even when we're crediting the entropy, we're still not totally certain
that it's any good. Since boot is the one time (aside from a compromise)
that we have zero entropy, it's important that we shepherd entropy into
the crng fairly often.

At the same time, we don't want a "premature next" problem, whereby an
attacker can brute force individual bits of added entropy. In lieu of
going full-on Fortuna (for now), we can pick a simpler strategy of just
reseeding more often during the first 5 minutes after boot. This is
still bounded by the 256-bit entropy credit requirement, so we'll skip a
reseeding if we haven't reached that, but in case entropy /is/ coming
in, this ensures that it makes its way into the crng rather rapidly
during these early stages.

Ordinarily we reseed if the previous reseeding is 300 seconds old. This
commit changes things so that for the first 600 seconds of boot time, we
reseed if the previous reseeding is uptime / 2 seconds old. That means
that we'll reseed at the very least double the uptime of the previous
reseeding.

Cc: Theodore Ts'o <[email protected]>
Reviewed-by: Eric Biggers <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -336,6 +336,28 @@ static void crng_fast_key_erasure(u8 key
}

/*
+ * Return whether the crng seed is considered to be sufficiently
+ * old that a reseeding might be attempted. This happens if the last
+ * reseeding was CRNG_RESEED_INTERVAL ago, or during early boot, at
+ * an interval proportional to the uptime.
+ */
+static bool crng_has_old_seed(void)
+{
+ static bool early_boot = true;
+ unsigned long interval = CRNG_RESEED_INTERVAL;
+
+ if (unlikely(READ_ONCE(early_boot))) {
+ time64_t uptime = ktime_get_seconds();
+ if (uptime >= CRNG_RESEED_INTERVAL / HZ * 2)
+ WRITE_ONCE(early_boot, false);
+ else
+ interval = max_t(unsigned int, 5 * HZ,
+ (unsigned int)uptime / 2 * HZ);
+ }
+ return time_after(jiffies, READ_ONCE(base_crng.birth) + interval);
+}
+
+/*
* This function returns a ChaCha state that you may use for generating
* random data. It also returns up to 32 bytes on its own of random data
* that may be used; random_data_len may not be greater than 32.
@@ -368,10 +390,10 @@ static void crng_make_state(u32 chacha_s
}

/*
- * If the base_crng is more than 5 minutes old, we reseed, which
- * in turn bumps the generation counter that we check below.
+ * If the base_crng is old enough, we try to reseed, which in turn
+ * bumps the generation counter that we check below.
*/
- if (unlikely(time_after(jiffies, READ_ONCE(base_crng.birth) + CRNG_RESEED_INTERVAL)))
+ if (unlikely(crng_has_old_seed()))
crng_reseed();

local_lock_irqsave(&crngs.lock, flags);



2022-05-28 20:39:32

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 049/111] random: give sysctl_random_min_urandom_seed a more sensible value

From: "Jason A. Donenfeld" <[email protected]>

commit d0efdf35a6a71d307a250199af6fce122a7c7e11 upstream.

This isn't used by anything or anywhere, but we can't delete it due to
compatibility. So at least give it the correct value of what it's
supposed to be instead of a garbage one.

Cc: Theodore Ts'o <[email protected]>
Reviewed-by: Dominik Brodowski <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1619,7 +1619,7 @@ const struct file_operations urandom_fop
* to avoid breaking old userspaces, but writing to it does not
* change any behavior of the RNG.
*
- * - urandom_min_reseed_secs - fixed to the meaningless value "60".
+ * - urandom_min_reseed_secs - fixed to the value CRNG_RESEED_INTERVAL.
* It is writable to avoid breaking old userspaces, but writing
* to it does not change any behavior of the RNG.
*
@@ -1629,7 +1629,7 @@ const struct file_operations urandom_fop

#include <linux/sysctl.h>

-static int sysctl_random_min_urandom_seed = 60;
+static int sysctl_random_min_urandom_seed = CRNG_RESEED_INTERVAL / HZ;
static int sysctl_random_write_wakeup_bits = POOL_MIN_BITS;
static int sysctl_poolsize = POOL_BITS;
static u8 sysctl_bootid[UUID_SIZE];



2022-05-28 20:39:50

by Justin Forbes

[permalink] [raw]
Subject: Re: [PATCH 5.17 000/111] 5.17.12-rc1 review

On Fri, May 27, 2022 at 10:48:32AM +0200, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.17.12 release.
> There are 111 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Sun, 29 May 2022 08:46:36 +0000.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.17.12-rc1.gz
> or in the git tree and branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.17.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h

Tested rc1 against the Fedora build system (aarch64, armv7, ppc64le,
s390x, x86_64), and boot tested x86_64. No regressions noted.

Tested-by: Justin M. Forbes <[email protected]>

2022-05-28 20:42:01

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 059/111] random: mix build-time latent entropy into pool at init

From: "Jason A. Donenfeld" <[email protected]>

commit 1754abb3e7583c570666fa1e1ee5b317e88c89a0 upstream.

Prior, the "input_pool_data" array needed no real initialization, and so
it was easy to mark it with __latent_entropy to populate it during
compile-time. In switching to using a hash function, this required us to
specifically initialize it to some specific state, which means we
dropped the __latent_entropy attribute. An unfortunate side effect was
this meant the pool was no longer seeded using compile-time random data.
In order to bring this back, we declare an array in rand_initialize()
with __latent_entropy and call mix_pool_bytes() on that at init, which
accomplishes the same thing as before. We make this __initconst, so that
it doesn't take up space at runtime after init.

Fixes: 6e8ec2552c7d ("random: use computational hash for entropy extraction")
Reviewed-by: Dominik Brodowski <[email protected]>
Reviewed-by: Theodore Ts'o <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 5 +++++
1 file changed, 5 insertions(+)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -970,6 +970,11 @@ int __init rand_initialize(void)
bool arch_init = true;
unsigned long rv;

+#if defined(LATENT_ENTROPY_PLUGIN)
+ static const u8 compiletime_seed[BLAKE2S_BLOCK_SIZE] __initconst __latent_entropy;
+ _mix_pool_bytes(compiletime_seed, sizeof(compiletime_seed));
+#endif
+
for (i = 0; i < BLAKE2S_BLOCK_SIZE; i += sizeof(rv)) {
if (!arch_get_random_seed_long_early(&rv) &&
!arch_get_random_long_early(&rv)) {



2022-05-28 20:42:21

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 018/111] random: use hash function for crng_slow_load()

From: "Jason A. Donenfeld" <[email protected]>

commit 66e4c2b9541503d721e936cc3898c9f25f4591ff upstream.

Since we have a hash function that's really fast, and the goal of
crng_slow_load() is reportedly to "touch all of the crng's state", we
can just hash the old state together with the new state and call it a
day. This way we dont need to reason about another LFSR or worry about
various attacks there. This code is only ever used at early boot and
then never again.

Cc: Theodore Ts'o <[email protected]>
Reviewed-by: Dominik Brodowski <[email protected]>
Reviewed-by: Eric Biggers <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 40 ++++++++++++++--------------------------
1 file changed, 14 insertions(+), 26 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -477,42 +477,30 @@ static size_t crng_fast_load(const u8 *c
* all), and (2) it doesn't have the performance constraints of
* crng_fast_load().
*
- * So we do something more comprehensive which is guaranteed to touch
- * all of the primary_crng's state, and which uses a LFSR with a
- * period of 255 as part of the mixing algorithm. Finally, we do
- * *not* advance crng_init_cnt since buffer we may get may be something
- * like a fixed DMI table (for example), which might very well be
- * unique to the machine, but is otherwise unvarying.
+ * So, we simply hash the contents in with the current key. Finally,
+ * we do *not* advance crng_init_cnt since buffer we may get may be
+ * something like a fixed DMI table (for example), which might very
+ * well be unique to the machine, but is otherwise unvarying.
*/
-static int crng_slow_load(const u8 *cp, size_t len)
+static void crng_slow_load(const u8 *cp, size_t len)
{
unsigned long flags;
- static u8 lfsr = 1;
- u8 tmp;
- unsigned int i, max = sizeof(base_crng.key);
- const u8 *src_buf = cp;
- u8 *dest_buf = base_crng.key;
+ struct blake2s_state hash;
+
+ blake2s_init(&hash, sizeof(base_crng.key));

if (!spin_trylock_irqsave(&base_crng.lock, flags))
- return 0;
+ return;
if (crng_init != 0) {
spin_unlock_irqrestore(&base_crng.lock, flags);
- return 0;
+ return;
}
- if (len > max)
- max = len;

- for (i = 0; i < max; i++) {
- tmp = lfsr;
- lfsr >>= 1;
- if (tmp & 1)
- lfsr ^= 0xE1;
- tmp = dest_buf[i % sizeof(base_crng.key)];
- dest_buf[i % sizeof(base_crng.key)] ^= src_buf[i % len] ^ lfsr;
- lfsr += (tmp << 3) | (tmp >> 5);
- }
+ blake2s_update(&hash, base_crng.key, sizeof(base_crng.key));
+ blake2s_update(&hash, cp, len);
+ blake2s_final(&hash, base_crng.key);
+
spin_unlock_irqrestore(&base_crng.lock, flags);
- return 1;
}

static void crng_reseed(void)



2022-05-28 20:43:37

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 015/111] random: do not xor RDRAND when writing into /dev/random

From: "Jason A. Donenfeld" <[email protected]>

commit 91c2afca290ed3034841c8c8532e69ed9e16cf34 upstream.

Continuing the reasoning of "random: ensure early RDSEED goes through
mixer on init", we don't want RDRAND interacting with anything without
going through the mixer function, as a backdoored CPU could presumably
cancel out data during an xor, which it'd have a harder time doing when
being forced through a cryptographic hash function. There's actually no
need at all to be calling RDRAND in write_pool(), because before we
extract from the pool, we always do so with 32 bytes of RDSEED hashed in
at that stage. Xoring at this stage is needless and introduces a minor
liability.

Cc: Theodore Ts'o <[email protected]>
Reviewed-by: Dominik Brodowski <[email protected]>
Reviewed-by: Eric Biggers <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 14 ++------------
1 file changed, 2 insertions(+), 12 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1305,25 +1305,15 @@ static __poll_t random_poll(struct file
static int write_pool(const char __user *buffer, size_t count)
{
size_t bytes;
- u32 t, buf[16];
+ u8 buf[BLAKE2S_BLOCK_SIZE];
const char __user *p = buffer;

while (count > 0) {
- int b, i = 0;
-
bytes = min(count, sizeof(buf));
- if (copy_from_user(&buf, p, bytes))
+ if (copy_from_user(buf, p, bytes))
return -EFAULT;
-
- for (b = bytes; b > 0; b -= sizeof(u32), i++) {
- if (!arch_get_random_int(&t))
- break;
- buf[i] ^= t;
- }
-
count -= bytes;
p += bytes;
-
mix_pool_bytes(buf, bytes);
cond_resched();
}



2022-05-28 20:45:22

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.17 020/111] random: remove outdated INT_MAX >> 6 check in urandom_read()

From: "Jason A. Donenfeld" <[email protected]>

commit 434537ae54ad37e93555de21b6ac8133d6d773a9 upstream.

In 79a8468747c5 ("random: check for increase of entropy_count because of
signed conversion"), a number of checks were added around what values
were passed to account(), because account() was doing fancy fixed point
fractional arithmetic, and a user had some ability to pass large values
directly into it. One of things in that commit was limiting those values
to INT_MAX >> 6. The first >> 3 was for bytes to bits, and the next >> 3
was for bits to 1/8 fractional bits.

However, for several years now, urandom reads no longer touch entropy
accounting, and so this check serves no purpose. The current flow is:

urandom_read_nowarn()-->get_random_bytes_user()-->chacha20_block()

Of course, we don't want that size_t to be truncated when adding it into
the ssize_t. But we arrive at urandom_read_nowarn() in the first place
either via ordinary fops, which limits reads to MAX_RW_COUNT, or via
getrandom() which limits reads to INT_MAX.

Cc: Theodore Ts'o <[email protected]>
Reviewed-by: Dominik Brodowski <[email protected]>
Reviewed-by: Jann Horn <[email protected]>
Reviewed-by: Eric Biggers <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1286,9 +1286,8 @@ void rand_initialize_disk(struct gendisk
static ssize_t urandom_read_nowarn(struct file *file, char __user *buf,
size_t nbytes, loff_t *ppos)
{
- int ret;
+ ssize_t ret;

- nbytes = min_t(size_t, nbytes, INT_MAX >> 6);
ret = get_random_bytes_user(buf, nbytes);
trace_urandom_read(nbytes, input_pool.entropy_count);
return ret;