2022-05-28 20:21:58

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 000/163] 5.10.119-rc1 review

This is the start of the stable review cycle for the 5.10.119 release.
There are 163 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:26 +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.10.119-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.10.y
and the diffstat can be found below.

thanks,

greg k-h

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

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

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

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

Dominik Brodowski <[email protected]>
random: only call crng_finalize_init() for primary_crng

Dominik Brodowski <[email protected]>
random: access primary_pool directly rather than through pointer

Dominik Brodowski <[email protected]>
random: continually use hwgenerator randomness

Jason A. Donenfeld <[email protected]>
random: simplify arithmetic function flow in account()

Jason A. Donenfeld <[email protected]>
random: selectively clang-format where it makes sense

Jason A. Donenfeld <[email protected]>
random: access input_pool_data directly rather than through pointer

Jason A. Donenfeld <[email protected]>
random: cleanup fractional entropy shift constants

Jason A. Donenfeld <[email protected]>
random: prepend remaining pool constants with POOL_

Jason A. Donenfeld <[email protected]>
random: de-duplicate INPUT_POOL constants

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

Jason A. Donenfeld <[email protected]>
random: rather than entropy_store abstraction, use global

Jason A. Donenfeld <[email protected]>
random: remove unused extract_entropy() reserved argument

Jason A. Donenfeld <[email protected]>
random: remove incomplete last_data logic

Jason A. Donenfeld <[email protected]>
random: cleanup integer types

Jason A. Donenfeld <[email protected]>
random: cleanup poolinfo abstraction

Schspa Shi <[email protected]>
random: fix typo in comments

Jann Horn <[email protected]>
random: don't reset crng_init_cnt on urandom_read()

Jason A. Donenfeld <[email protected]>
random: avoid superfluous call to RDRAND in CRNG extraction

Dominik Brodowski <[email protected]>
random: early initialization of ChaCha constants

Jason A. Donenfeld <[email protected]>
random: use IS_ENABLED(CONFIG_NUMA) instead of ifdefs

Dominik Brodowski <[email protected]>
random: harmonize "crng init done" messages

Jason A. Donenfeld <[email protected]>
random: mix bootloader randomness into pool

Jason A. Donenfeld <[email protected]>
random: do not re-init if crng_reseed completes before primary init

Jason A. Donenfeld <[email protected]>
random: do not sign extend bytes for rotation when mixing

Jason A. Donenfeld <[email protected]>
random: use BLAKE2s instead of SHA1 in extraction

Sebastian Andrzej Siewior <[email protected]>
random: remove unused irq_flags argument from add_interrupt_randomness()

Mark Brown <[email protected]>
random: document add_hwgenerator_randomness() with other input functions

Jason A. Donenfeld <[email protected]>
lib/crypto: blake2s: avoid indirect calls to compression function for Clang CFI

Jason A. Donenfeld <[email protected]>
lib/crypto: sha1: re-roll loops to reduce code size

Jason A. Donenfeld <[email protected]>
lib/crypto: blake2s: move hmac construction into wireguard

Jason A. Donenfeld <[email protected]>
lib/crypto: blake2s: include as built-in

Eric Biggers <[email protected]>
crypto: blake2s - include <linux/bug.h> instead of <asm/bug.h>

Eric Biggers <[email protected]>
crypto: blake2s - adjust include guard naming

Eric Biggers <[email protected]>
crypto: blake2s - add comment for blake2s_state fields

Eric Biggers <[email protected]>
crypto: blake2s - optimize blake2s initialization

Eric Biggers <[email protected]>
crypto: blake2s - share the "shash" API boilerplate code

Eric Biggers <[email protected]>
crypto: blake2s - move update and final logic to internal/blake2s.h

Eric Biggers <[email protected]>
crypto: blake2s - remove unneeded includes

Eric Biggers <[email protected]>
crypto: x86/blake2s - define shash_alg structs using macros

Eric Biggers <[email protected]>
crypto: blake2s - define shash_alg structs using macros

Herbert Xu <[email protected]>
crypto: lib/blake2s - Move selftest prototype into header file

Jason A. Donenfeld <[email protected]>
MAINTAINERS: add git tree for random.c

Jason A. Donenfeld <[email protected]>
MAINTAINERS: co-maintain random.c

Eric Biggers <[email protected]>
random: remove dead code left over from blocking pool

Ard Biesheuvel <[email protected]>
random: avoid arch_get_random_seed_long() when collecting IRQ randomness

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

Andy Shevchenko <[email protected]>
ACPI: sysfs: Make sparse happy about address space in use

Hans Verkuil <[email protected]>
media: vim2m: initialize the media device earlier

Sakari Ailus <[email protected]>
media: vim2m: Register video device after setting up internals

Willy Tarreau <[email protected]>
secure_seq: use the 64 bits of the siphash for port offset calculation

Eric Dumazet <[email protected]>
tcp: change source port randomizarion at connect() time

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

Vitaly Kuznetsov <[email protected]>
KVM: x86: Properly handle APF vs disabled LAPIC situation

Denis Efremov (Oracle) <[email protected]>
staging: rtl8723bs: prevent ->Ssid overflow in rtw_wx_set_scan()

Daniel Thompson <[email protected]>
lockdown: also lock down previous kgdb use


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

Diffstat:

Documentation/admin-guide/kernel-parameters.txt | 6 +
Documentation/admin-guide/sysctl/kernel.rst | 22 +-
MAINTAINERS | 2 +
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/crypto/Makefile | 4 +-
arch/x86/crypto/blake2s-glue.c | 166 +-
arch/x86/crypto/blake2s-shash.c | 77 +
arch/x86/include/asm/timex.h | 9 +
arch/x86/include/asm/tsc.h | 7 +-
arch/x86/kernel/cpu/mshyperv.c | 2 +-
arch/x86/kvm/lapic.c | 6 +
arch/x86/kvm/mmu/mmu.c | 6 +-
arch/x86/kvm/x86.c | 2 +-
arch/xtensa/include/asm/timex.h | 6 +-
crypto/Kconfig | 3 +-
crypto/blake2s_generic.c | 158 +-
crypto/drbg.c | 17 +-
drivers/acpi/sysfs.c | 23 +-
drivers/char/Kconfig | 3 +-
drivers/char/hw_random/core.c | 1 +
drivers/char/random.c | 3035 +++++++++--------------
drivers/hv/vmbus_drv.c | 2 +-
drivers/media/test-drivers/vim2m.c | 22 +-
drivers/net/Kconfig | 1 -
drivers/net/wireguard/noise.c | 45 +-
drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 6 +-
include/crypto/blake2s.h | 66 +-
include/crypto/chacha.h | 15 +-
include/crypto/drbg.h | 2 +-
include/crypto/internal/blake2s.h | 123 +-
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/security.h | 2 +
include/linux/siphash.h | 28 +
include/linux/timex.h | 10 +-
include/net/inet_hashtables.h | 2 +-
include/net/secure_seq.h | 4 +-
include/trace/events/random.h | 330 ---
init/main.c | 13 +-
kernel/cpu.c | 11 +
kernel/debug/debug_core.c | 24 +
kernel/debug/kdb/kdb_main.c | 62 +-
kernel/irq/handle.c | 2 +-
kernel/time/timekeeping.c | 15 +
lib/Kconfig.debug | 3 +-
lib/crypto/Kconfig | 23 +-
lib/crypto/Makefile | 9 +-
lib/crypto/blake2s-generic.c | 6 +-
lib/crypto/blake2s-selftest.c | 33 +-
lib/crypto/blake2s.c | 81 +-
lib/random32.c | 16 +-
lib/sha1.c | 95 +-
lib/siphash.c | 32 +-
lib/vsprintf.c | 10 +-
mm/util.c | 32 +
net/core/secure_seq.c | 4 +-
net/ipv4/inet_hashtables.c | 28 +-
net/ipv6/inet6_hashtables.c | 4 +-
security/security.c | 2 +
sound/pci/ctxfi/ctatc.c | 2 +
sound/pci/ctxfi/cthardware.h | 3 +-
76 files changed, 1865 insertions(+), 3035 deletions(-)




2022-05-28 20:22:35

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 090/163] random: rewrite header introductory comment

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

commit 5f75d9f3babea8ae0a2d06724656874f41d317f5 upstream.

Now that we've re-documented the various sections, we can remove the
outdated text here and replace it with a high-level overview.

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 | 179 +++++---------------------------------------------
1 file changed, 19 insertions(+), 160 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -2,168 +2,27 @@
/*
* 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.
- */
-
-/*
- * Exported interfaces ---- output
- * ===============================
- *
- * There are four exported interfaces; two for use within the kernel,
- * and two for use from userspace.
- *
- * Exported interfaces ---- userspace output
- * -----------------------------------------
- *
- * The userspace interfaces are two character devices /dev/random and
- * /dev/urandom. /dev/random is suitable for use when very high
- * quality randomness is desired (for example, for key generation or
- * one-time pads), as it will only return a maximum of the number of
- * bits of randomness (as estimated by the random number generator)
- * contained in the entropy pool.
- *
- * The /dev/urandom device does not have this limit, and will return
- * as many bytes as are requested. As more and more random bytes are
- * requested without giving time for the entropy pool to recharge,
- * this will result in random numbers that are merely cryptographically
- * strong. For many applications, however, this is acceptable.
- *
- * Exported interfaces ---- kernel output
- * --------------------------------------
- *
- * The primary kernel interfaces are:
- *
- * void get_random_bytes(void *buf, size_t nbytes);
- * u32 get_random_u32()
- * u64 get_random_u64()
- * unsigned int get_random_int()
- * unsigned long get_random_long()
- *
- * These interfaces will return the requested number of random bytes
- * into the given buffer or as a return value. This is equivalent to a
- * read from /dev/urandom. The get_random_{u32,u64,int,long}() family
- * of functions may be higher performance for one-off random integers,
- * because they do a bit of buffering.
- *
- * prandom_u32()
- * -------------
- *
- * For even weaker applications, see the pseudorandom generator
- * prandom_u32(), prandom_max(), and prandom_bytes(). If the random
- * numbers aren't security-critical at all, these are *far* cheaper.
- * Useful for self-tests, random error simulation, randomized backoffs,
- * and any other application where you trust that nobody is trying to
- * maliciously mess with you by guessing the "random" numbers.
- *
- * Exported interfaces ---- input
- * ==============================
- *
- * The current exported interfaces for gathering environmental noise
- * from the devices are:
- *
- * void add_device_randomness(const void *buf, size_t size);
- * void add_input_randomness(unsigned int type, unsigned int code,
- * unsigned int value);
- * void add_interrupt_randomness(int irq);
- * void add_disk_randomness(struct gendisk *disk);
- * void add_hwgenerator_randomness(const void *buffer, size_t count,
- * size_t entropy);
- * void add_bootloader_randomness(const void *buf, size_t size);
- *
- * add_device_randomness() is for adding data to the random pool that
- * is likely to differ between two devices (or possibly even per boot).
- * This would be things like MAC addresses or serial numbers, or the
- * read-out of the RTC. This does *not* add any actual entropy to the
- * pool, but it initializes the pool to different values for devices
- * that might otherwise be identical and have very little entropy
- * available to them (particularly common in the embedded world).
- *
- * add_input_randomness() uses the input layer interrupt timing, as well as
- * the event type information from the hardware.
- *
- * add_interrupt_randomness() uses the interrupt timing as random
- * inputs to the entropy pool. Using the cycle counters and the irq source
- * as inputs, it feeds the randomness roughly once a second.
- *
- * add_disk_randomness() uses what amounts to the seek time of block
- * layer request events, on a per-disk_devt basis, as input to the
- * entropy pool. Note that high-speed solid state drives with very low
- * seek times do not make for good sources of entropy, as their seek
- * times are usually fairly consistent.
- *
- * All of these routines try to estimate how many bits of randomness a
- * particular randomness source. They do this by keeping track of the
- * first and second order deltas of the event timings.
- *
- * add_hwgenerator_randomness() is for true hardware RNGs, and will credit
- * entropy as specified by the caller. If the entropy pool is full it will
- * block until more entropy is needed.
- *
- * add_bootloader_randomness() is the same as add_hwgenerator_randomness() or
- * add_device_randomness(), depending on whether or not the configuration
- * option CONFIG_RANDOM_TRUST_BOOTLOADER is set.
- *
- * Ensuring unpredictability at system startup
- * ============================================
- *
- * When any operating system starts up, it will go through a sequence
- * of actions that are fairly predictable by an adversary, especially
- * if the start-up does not involve interaction with a human operator.
- * This reduces the actual number of bits of unpredictability in the
- * entropy pool below the value in entropy_count. In order to
- * counteract this effect, it helps to carry information in the
- * entropy pool across shut-downs and start-ups. To do this, put the
- * following lines an appropriate script which is run during the boot
- * sequence:
- *
- * echo "Initializing random number generator..."
- * random_seed=/var/run/random-seed
- * # Carry a random seed from start-up to start-up
- * # Load and then save the whole entropy pool
- * if [ -f $random_seed ]; then
- * cat $random_seed >/dev/urandom
- * else
- * touch $random_seed
- * fi
- * chmod 600 $random_seed
- * dd if=/dev/urandom of=$random_seed count=1 bs=512
- *
- * and the following lines in an appropriate script which is run as
- * the system is shutdown:
- *
- * # Carry a random seed from shut-down to start-up
- * # Save the whole entropy pool
- * echo "Saving random seed..."
- * random_seed=/var/run/random-seed
- * touch $random_seed
- * chmod 600 $random_seed
- * dd if=/dev/urandom of=$random_seed count=1 bs=512
- *
- * For example, on most modern systems using the System V init
- * scripts, such code fragments would be found in
- * /etc/rc.d/init.d/random. On older Linux systems, the correct script
- * location might be in /etc/rcb.d/rc.local or /etc/rc.d/rc.0.
- *
- * Effectively, these commands cause the contents of the entropy pool
- * to be saved at shut-down time and reloaded into the entropy pool at
- * start-up. (The 'dd' in the addition to the bootup script is to
- * make sure that /etc/random-seed is different for every start-up,
- * even if the system crashes without executing rc.0.) Even with
- * complete knowledge of the start-up activities, predicting the state
- * of the entropy pool requires knowledge of the previous history of
- * the system.
- *
- * Configuring the /dev/random driver under Linux
- * ==============================================
+ * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All rights reserved.
*
- * The /dev/random driver under Linux uses minor numbers 8 and 9 of
- * the /dev/mem major number (#1). So if your system does not have
- * /dev/random and /dev/urandom created already, they can be created
- * by using the commands:
+ * This driver produces cryptographically secure pseudorandom data. It is divided
+ * into roughly six sections, each with a section header:
*
- * mknod /dev/random c 1 8
- * mknod /dev/urandom c 1 9
+ * - Initialization and readiness waiting.
+ * - Fast key erasure RNG, the "crng".
+ * - Entropy accumulation and extraction routines.
+ * - Entropy collection routines.
+ * - Userspace reader/writer interfaces.
+ * - Sysctl interface.
+ *
+ * The high level overview is that there is one input pool, into which
+ * various pieces of data are hashed. Some of that data is then "credited" as
+ * having a certain number of bits of entropy. When enough bits of entropy are
+ * available, the hash is finalized and handed as a key to a stream cipher that
+ * expands it indefinitely for various consumers. This key is periodically
+ * refreshed as the various entropy collectors, described below, add data to the
+ * input pool and credit it. There is currently no Fortuna-like scheduler
+ * involved, which can lead to malicious entropy sources causing a premature
+ * reseed, and the entropy estimates are, at best, conservative guesses.
*/

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt



2022-05-28 20:23:57

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 148/163] random: remove ratelimiting for in-kernel unseeded randomness

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

commit cc1e127bfa95b5fb2f9307e7168bf8b2b45b4c5e upstream.

The CONFIG_WARN_ALL_UNSEEDED_RANDOM debug option controls whether the
kernel warns about all unseeded randomness or just the first instance.
There's some complicated rate limiting and comparison to the previous
caller, such that even with CONFIG_WARN_ALL_UNSEEDED_RANDOM enabled,
developers still don't see all the messages or even an accurate count of
how many were missed. This is the result of basically parallel
mechanisms aimed at accomplishing more or less the same thing, added at
different points in random.c history, which sort of compete with the
first-instance-only limiting we have now.

It turns out, however, that nobody cares about the first unseeded
randomness instance of in-kernel users. The same first user has been
there for ages now, and nobody is doing anything about it. It isn't even
clear that anybody _can_ do anything about it. Most places that can do
something about it have switched over to using get_random_bytes_wait()
or wait_for_random_bytes(), which is the right thing to do, but there is
still much code that needs randomness sometimes during init, and as a
geeneral rule, if you're not using one of the _wait functions or the
readiness notifier callback, you're bound to be doing it wrong just
based on that fact alone.

So warning about this same first user that can't easily change is simply
not an effective mechanism for anything at all. Users can't do anything
about it, as the Kconfig text points out -- the problem isn't in
userspace code -- and kernel developers don't or more often can't react
to it.

Instead, show the warning for all instances when CONFIG_WARN_ALL_UNSEEDED_RANDOM
is set, so that developers can debug things need be, or if it isn't set,
don't show a warning at all.

At the same time, CONFIG_WARN_ALL_UNSEEDED_RANDOM now implies setting
random.ratelimit_disable=1 on by default, since if you care about one
you probably care about the other too. And we can clean up usage around
the related urandom_warning ratelimiter as well (whose behavior isn't
changing), so that it properly counts missed messages after the 10
message threshold is reached.

Cc: Theodore Ts'o <[email protected]>
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 | 61 ++++++++++++++------------------------------------
lib/Kconfig.debug | 3 --
2 files changed, 19 insertions(+), 45 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -86,11 +86,10 @@ static DEFINE_SPINLOCK(random_ready_chai
static RAW_NOTIFIER_HEAD(random_ready_chain);

/* Control how we warn userspace. */
-static struct ratelimit_state unseeded_warning =
- RATELIMIT_STATE_INIT("warn_unseeded_randomness", HZ, 3);
static struct ratelimit_state urandom_warning =
RATELIMIT_STATE_INIT("warn_urandom_randomness", HZ, 3);
-static int ratelimit_disable __read_mostly;
+static int ratelimit_disable __read_mostly =
+ IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM);
module_param_named(ratelimit_disable, ratelimit_disable, int, 0644);
MODULE_PARM_DESC(ratelimit_disable, "Disable random ratelimit suppression");

@@ -183,27 +182,15 @@ static void process_random_ready_list(vo
spin_unlock_irqrestore(&random_ready_chain_lock, flags);
}

-#define warn_unseeded_randomness(previous) \
- _warn_unseeded_randomness(__func__, (void *)_RET_IP_, (previous))
+#define warn_unseeded_randomness() \
+ _warn_unseeded_randomness(__func__, (void *)_RET_IP_)

-static void _warn_unseeded_randomness(const char *func_name, void *caller, void **previous)
+static void _warn_unseeded_randomness(const char *func_name, void *caller)
{
-#ifdef CONFIG_WARN_ALL_UNSEEDED_RANDOM
- const bool print_once = false;
-#else
- static bool print_once __read_mostly;
-#endif
-
- if (print_once || crng_ready() ||
- (previous && (caller == READ_ONCE(*previous))))
+ if (!IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) || crng_ready())
return;
- WRITE_ONCE(*previous, caller);
-#ifndef CONFIG_WARN_ALL_UNSEEDED_RANDOM
- print_once = true;
-#endif
- if (__ratelimit(&unseeded_warning))
- printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n",
- func_name, caller, crng_init);
+ printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n",
+ func_name, caller, crng_init);
}


@@ -456,9 +443,7 @@ static void _get_random_bytes(void *buf,
*/
void get_random_bytes(void *buf, size_t nbytes)
{
- static void *previous;
-
- warn_unseeded_randomness(&previous);
+ warn_unseeded_randomness();
_get_random_bytes(buf, nbytes);
}
EXPORT_SYMBOL(get_random_bytes);
@@ -554,10 +539,9 @@ u64 get_random_u64(void)
u64 ret;
unsigned long flags;
struct batched_entropy *batch;
- static void *previous;
unsigned long next_gen;

- warn_unseeded_randomness(&previous);
+ warn_unseeded_randomness();

if (!crng_ready()) {
_get_random_bytes(&ret, sizeof(ret));
@@ -593,10 +577,9 @@ u32 get_random_u32(void)
u32 ret;
unsigned long flags;
struct batched_entropy *batch;
- static void *previous;
unsigned long next_gen;

- warn_unseeded_randomness(&previous);
+ warn_unseeded_randomness();

if (!crng_ready()) {
_get_random_bytes(&ret, sizeof(ret));
@@ -823,16 +806,9 @@ static void credit_init_bits(size_t nbit
wake_up_interruptible(&crng_init_wait);
kill_fasync(&fasync, SIGIO, POLL_IN);
pr_notice("crng init done\n");
- if (unseeded_warning.missed) {
- pr_notice("%d get_random_xx warning(s) missed due to ratelimiting\n",
- unseeded_warning.missed);
- unseeded_warning.missed = 0;
- }
- if (urandom_warning.missed) {
+ if (urandom_warning.missed)
pr_notice("%d urandom warning(s) missed due to ratelimiting\n",
urandom_warning.missed);
- urandom_warning.missed = 0;
- }
} else if (orig < POOL_EARLY_BITS && new >= POOL_EARLY_BITS) {
spin_lock_irqsave(&base_crng.lock, flags);
/* Check if crng_init is CRNG_EMPTY, to avoid race with crng_reseed(). */
@@ -945,10 +921,6 @@ int __init rand_initialize(void)
else if (arch_init && trust_cpu)
credit_init_bits(BLAKE2S_BLOCK_SIZE * 8);

- if (ratelimit_disable) {
- urandom_warning.interval = 0;
- unseeded_warning.interval = 0;
- }
return 0;
}

@@ -1394,11 +1366,14 @@ static ssize_t urandom_read(struct file
{
static int maxwarn = 10;

- if (!crng_ready() && maxwarn > 0) {
- maxwarn--;
- if (__ratelimit(&urandom_warning))
+ if (!crng_ready()) {
+ if (!ratelimit_disable && maxwarn <= 0)
+ ++urandom_warning.missed;
+ else if (ratelimit_disable || __ratelimit(&urandom_warning)) {
+ --maxwarn;
pr_notice("%s: uninitialized urandom read (%zd bytes read)\n",
current->comm, nbytes);
+ }
}

return get_random_bytes_user(buf, nbytes);
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1426,8 +1426,7 @@ config WARN_ALL_UNSEEDED_RANDOM
so architecture maintainers really need to do what they can
to get the CRNG seeded sooner after the system is booted.
However, since users cannot do anything actionable to
- address this, by default the kernel will issue only a single
- warning for the first use of unseeded randomness.
+ address this, by default this option is disabled.

Say Y here if you want to receive warnings for all uses of
unseeded randomness. This will be of use primarily for



2022-05-28 20:26:20

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 145/163] random: use symbolic constants for crng_init states

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

commit e3d2c5e79a999aa4e7d6f0127e16d3da5a4ff70d upstream.

crng_init represents a state machine, with three states, and various
rules for transitions. For the longest time, we've been managing these
with "0", "1", and "2", and expecting people to figure it out. To make
the code more obvious, replace these with proper enum values
representing the transition, and then redocument what each of these
states mean.

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

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -70,16 +70,16 @@
*********************************************************************/

/*
- * crng_init = 0 --> Uninitialized
- * 1 --> Initialized
- * 2 --> Initialized from input_pool
- *
* crng_init is protected by base_crng->lock, and only increases
- * its value (from 0->1->2).
+ * its value (from empty->early->ready).
*/
-static int crng_init = 0;
-#define crng_ready() (likely(crng_init > 1))
-/* Various types of waiters for crng_init->2 transition. */
+static enum {
+ CRNG_EMPTY = 0, /* Little to no entropy collected */
+ CRNG_EARLY = 1, /* At least POOL_EARLY_BITS collected */
+ CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */
+} crng_init = CRNG_EMPTY;
+#define crng_ready() (likely(crng_init >= CRNG_READY))
+/* Various types of waiters for crng_init->CRNG_READY transition. */
static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
static struct fasync_struct *fasync;
static DEFINE_SPINLOCK(random_ready_chain_lock);
@@ -284,7 +284,7 @@ static void crng_reseed(void)
WRITE_ONCE(base_crng.generation, next_gen);
WRITE_ONCE(base_crng.birth, jiffies);
if (!crng_ready()) {
- crng_init = 2;
+ crng_init = CRNG_READY;
finalize_init = true;
}
spin_unlock_irqrestore(&base_crng.lock, flags);
@@ -378,7 +378,7 @@ static void crng_make_state(u32 chacha_s
* For the fast path, we check whether we're ready, unlocked first, and
* then re-check once locked later. In the case where we're really not
* ready, we do fast key erasure with the base_crng directly, extracting
- * when crng_init==0.
+ * when crng_init is CRNG_EMPTY.
*/
if (!crng_ready()) {
bool ready;
@@ -386,7 +386,7 @@ static void crng_make_state(u32 chacha_s
spin_lock_irqsave(&base_crng.lock, flags);
ready = crng_ready();
if (!ready) {
- if (crng_init == 0)
+ if (crng_init == CRNG_EMPTY)
extract_entropy(base_crng.key, sizeof(base_crng.key));
crng_fast_key_erasure(base_crng.key, chacha_state,
random_data, random_data_len);
@@ -740,8 +740,8 @@ EXPORT_SYMBOL(get_random_bytes_arch);

enum {
POOL_BITS = BLAKE2S_HASH_SIZE * 8,
- POOL_INIT_BITS = POOL_BITS, /* No point in settling for less. */
- POOL_FAST_INIT_BITS = POOL_INIT_BITS / 2
+ POOL_READY_BITS = POOL_BITS, /* When crng_init->CRNG_READY */
+ POOL_EARLY_BITS = POOL_READY_BITS / 2 /* When crng_init->CRNG_EARLY */
};

static struct {
@@ -836,13 +836,13 @@ static void credit_init_bits(size_t nbit
init_bits = min_t(unsigned int, POOL_BITS, orig + add);
} while (cmpxchg(&input_pool.init_bits, orig, init_bits) != orig);

- if (!crng_ready() && init_bits >= POOL_INIT_BITS)
+ if (!crng_ready() && init_bits >= POOL_READY_BITS)
crng_reseed();
- else if (unlikely(crng_init == 0 && init_bits >= POOL_FAST_INIT_BITS)) {
+ else if (unlikely(crng_init == CRNG_EMPTY && init_bits >= POOL_EARLY_BITS)) {
spin_lock_irqsave(&base_crng.lock, flags);
- if (crng_init == 0) {
+ if (crng_init == CRNG_EMPTY) {
extract_entropy(base_crng.key, sizeof(base_crng.key));
- crng_init = 1;
+ crng_init = CRNG_EARLY;
}
spin_unlock_irqrestore(&base_crng.lock, flags);
}
@@ -1517,7 +1517,7 @@ const struct file_operations urandom_fop
*
* - write_wakeup_threshold - the amount of entropy in the input pool
* below which write polls to /dev/random will unblock, requesting
- * more entropy, tied to the POOL_INIT_BITS constant. It is writable
+ * more entropy, tied to the POOL_READY_BITS constant. It is writable
* to avoid breaking old userspaces, but writing to it does not
* change any behavior of the RNG.
*
@@ -1532,7 +1532,7 @@ const struct file_operations urandom_fop
#include <linux/sysctl.h>

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




2022-05-28 20:27:22

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 079/163] 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:28:22

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 031/163] random: use BLAKE2s instead of SHA1 in extraction

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

commit 9f9eff85a008b095eafc5f4ecbaf5aca689271c1 upstream.

This commit addresses one of the lower hanging fruits of the RNG: its
usage of SHA1.

BLAKE2s is generally faster, and certainly more secure, than SHA1, which
has [1] been [2] really [3] very [4] broken [5]. Additionally, the
current construction in the RNG doesn't use the full SHA1 function, as
specified, and allows overwriting the IV with RDRAND output in an
undocumented way, even in the case when RDRAND isn't set to "trusted",
which means potential malicious IV choices. And its short length means
that keeping only half of it secret when feeding back into the mixer
gives us only 2^80 bits of forward secrecy. In other words, not only is
the choice of hash function dated, but the use of it isn't really great
either.

This commit aims to fix both of these issues while also keeping the
general structure and semantics as close to the original as possible.
Specifically:

a) Rather than overwriting the hash IV with RDRAND, we put it into
BLAKE2's documented "salt" and "personal" fields, which were
specifically created for this type of usage.
b) Since this function feeds the full hash result back into the
entropy collector, we only return from it half the length of the
hash, just as it was done before. This increases the
construction's forward secrecy from 2^80 to a much more
comfortable 2^128.
c) Rather than using the raw "sha1_transform" function alone, we
instead use the full proper BLAKE2s function, with finalization.

This also has the advantage of supplying 16 bytes at a time rather than
SHA1's 10 bytes, which, in addition to having a faster compression
function to begin with, means faster extraction in general. On an Intel
i7-11850H, this commit makes initial seeding around 131% faster.

BLAKE2s itself has the nice property of internally being based on the
ChaCha permutation, which the RNG is already using for expansion, so
there shouldn't be any issue with newness, funkiness, or surprising CPU
behavior, since it's based on something already in use.

[1] https://eprint.iacr.org/2005/010.pdf
[2] https://www.iacr.org/archive/crypto2005/36210017/36210017.pdf
[3] https://eprint.iacr.org/2015/967.pdf
[4] https://shattered.io/static/shattered.pdf
[5] https://www.usenix.org/system/files/sec20-leurent.pdf

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

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1,8 +1,7 @@
/*
* random.c -- A strong random number generator
*
- * Copyright (C) 2017 Jason A. Donenfeld <[email protected]>. All
- * Rights Reserved.
+ * Copyright (C) 2017-2022 Jason A. Donenfeld <[email protected]>. All Rights Reserved.
*
* Copyright Matt Mackall <[email protected]>, 2003, 2004, 2005
*
@@ -78,12 +77,12 @@
* an *estimate* of how many bits of randomness have been stored into
* the random number generator's internal state.
*
- * When random bytes are desired, they are obtained by taking the SHA
- * hash of the contents of the "entropy pool". The SHA hash avoids
+ * When random bytes are desired, they are obtained by taking the BLAKE2s
+ * hash of the contents of the "entropy pool". The BLAKE2s hash avoids
* exposing the internal state of the entropy pool. It is believed to
* be computationally infeasible to derive any useful information
- * about the input of SHA from its output. Even if it is possible to
- * analyze SHA in some clever way, as long as the amount of data
+ * about the input of BLAKE2s from its output. Even if it is possible to
+ * analyze BLAKE2s in some clever way, as long as the amount of data
* returned from the generator is less than the inherent entropy in
* the pool, the output data is totally unpredictable. For this
* reason, the routine decreases its internal estimate of how many
@@ -93,7 +92,7 @@
* If this estimate goes to zero, the routine can still generate
* random numbers; however, an attacker may (at least in theory) be
* able to infer the future output of the generator from prior
- * outputs. This requires successful cryptanalysis of SHA, which is
+ * outputs. This requires successful cryptanalysis of BLAKE2s, which is
* not believed to be feasible, but there is a remote possibility.
* Nonetheless, these numbers should be useful for the vast majority
* of purposes.
@@ -347,7 +346,7 @@
#include <linux/completion.h>
#include <linux/uuid.h>
#include <crypto/chacha.h>
-#include <crypto/sha.h>
+#include <crypto/blake2s.h>

#include <asm/processor.h>
#include <linux/uaccess.h>
@@ -367,10 +366,7 @@
#define INPUT_POOL_WORDS (1 << (INPUT_POOL_SHIFT-5))
#define OUTPUT_POOL_SHIFT 10
#define OUTPUT_POOL_WORDS (1 << (OUTPUT_POOL_SHIFT-5))
-#define EXTRACT_SIZE 10
-
-
-#define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long))
+#define EXTRACT_SIZE (BLAKE2S_HASH_SIZE / 2)

/*
* To allow fractional bits to be tracked, the entropy_count field is
@@ -406,7 +402,7 @@ static int random_write_wakeup_bits = 28
* Thanks to Colin Plumb for suggesting this.
*
* The mixing operation is much less sensitive than the output hash,
- * where we use SHA-1. All that we want of mixing operation is that
+ * where we use BLAKE2s. All that we want of mixing operation is that
* it be a good non-cryptographic hash; i.e. it not produce collisions
* when fed "random" data of the sort we expect to see. As long as
* the pool state differs for different inputs, we have preserved the
@@ -1399,56 +1395,49 @@ retry:
*/
static void extract_buf(struct entropy_store *r, __u8 *out)
{
- int i;
- union {
- __u32 w[5];
- unsigned long l[LONGS(20)];
- } hash;
- __u32 workspace[SHA1_WORKSPACE_WORDS];
+ struct blake2s_state state __aligned(__alignof__(unsigned long));
+ u8 hash[BLAKE2S_HASH_SIZE];
+ unsigned long *salt;
unsigned long flags;

+ blake2s_init(&state, sizeof(hash));
+
/*
* If we have an architectural hardware random number
- * generator, use it for SHA's initial vector
+ * generator, use it for BLAKE2's salt & personal fields.
*/
- sha1_init(hash.w);
- for (i = 0; i < LONGS(20); i++) {
+ for (salt = (unsigned long *)&state.h[4];
+ salt < (unsigned long *)&state.h[8]; ++salt) {
unsigned long v;
if (!arch_get_random_long(&v))
break;
- hash.l[i] = v;
+ *salt ^= v;
}

- /* Generate a hash across the pool, 16 words (512 bits) at a time */
+ /* Generate a hash across the pool */
spin_lock_irqsave(&r->lock, flags);
- for (i = 0; i < r->poolinfo->poolwords; i += 16)
- sha1_transform(hash.w, (__u8 *)(r->pool + i), workspace);
+ blake2s_update(&state, (const u8 *)r->pool,
+ r->poolinfo->poolwords * sizeof(*r->pool));
+ blake2s_final(&state, hash); /* final zeros out state */

/*
* We mix the hash back into the pool to prevent backtracking
* attacks (where the attacker knows the state of the pool
* plus the current outputs, and attempts to find previous
- * ouputs), unless the hash function can be inverted. By
- * mixing at least a SHA1 worth of hash data back, we make
+ * outputs), unless the hash function can be inverted. By
+ * mixing at least a hash worth of hash data back, we make
* brute-forcing the feedback as hard as brute-forcing the
* hash.
*/
- __mix_pool_bytes(r, hash.w, sizeof(hash.w));
+ __mix_pool_bytes(r, hash, sizeof(hash));
spin_unlock_irqrestore(&r->lock, flags);

- memzero_explicit(workspace, sizeof(workspace));
-
- /*
- * In case the hash function has some recognizable output
- * pattern, we fold it in half. Thus, we always feed back
- * twice as much data as we output.
+ /* Note that EXTRACT_SIZE is half of hash size here, because above
+ * we've dumped the full length back into mixer. By reducing the
+ * amount that we emit, we retain a level of forward secrecy.
*/
- hash.w[0] ^= hash.w[3];
- hash.w[1] ^= hash.w[4];
- hash.w[2] ^= rol32(hash.w[2], 16);
-
- memcpy(out, &hash, EXTRACT_SIZE);
- memzero_explicit(&hash, sizeof(hash));
+ memcpy(out, hash, EXTRACT_SIZE);
+ memzero_explicit(hash, sizeof(hash));
}

static ssize_t _extract_entropy(struct entropy_store *r, void *buf,



2022-05-28 20:29:39

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 094/163] 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:31:40

by Naresh Kamboju

[permalink] [raw]
Subject: Re: [PATCH 5.10 000/163] 5.10.119-rc1 review

On Fri, 27 May 2022 at 14:21, Greg Kroah-Hartman
<[email protected]> wrote:
>
> This is the start of the stable review cycle for the 5.10.119 release.
> There are 163 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:26 +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.10.119-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.10.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h

Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.

Tested-by: Linux Kernel Functional Testing <[email protected]>

## Build
* kernel: 5.10.119-rc1
* git: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
* git branch: linux-5.10.y
* git commit: d318333bd3dbc483b4d566521dc6486ef9f6ba04
* git describe: v5.10.118-164-gd318333bd3db
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.10.y/build/v5.10.118-164-gd318333bd3db/

## Test Regressions (compared to v5.10.118)
No test regressions found.

## Metric Regressions (compared to v5.10.118)
No metric regressions found.

## Test Fixes (compared to v5.10.118)
No test fixes found.

## Metric Fixes (compared to v5.10.118)
No metric fixes found.

## Test result summary
total: 94216, pass: 80324, fail: 458, skip: 12631, xfail: 803

## Build Summary
* arc: 10 total, 10 passed, 0 failed
* arm: 291 total, 291 passed, 0 failed
* arm64: 41 total, 41 passed, 0 failed
* dragonboard-410c: 1 total, 1 passed, 0 failed
* hi6220-hikey: 1 total, 1 passed, 0 failed
* i386: 40 total, 40 passed, 0 failed
* juno-r2: 1 total, 1 passed, 0 failed
* mips: 37 total, 37 passed, 0 failed
* parisc: 12 total, 12 passed, 0 failed
* powerpc: 51 total, 51 passed, 0 failed
* riscv: 27 total, 27 passed, 0 failed
* s390: 21 total, 21 passed, 0 failed
* sh: 24 total, 24 passed, 0 failed
* sparc: 12 total, 12 passed, 0 failed
* x15: 1 total, 1 passed, 0 failed
* x86: 1 total, 1 passed, 0 failed
* x86_64: 41 total, 41 passed, 0 failed

## Test suites summary
* fwts
* kselftest-android
* kselftest-arm64
* kselftest-bpf
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-drivers
* kselftest-efivarfs
* kselftest-filesystems
* kselftest-firmware
* kselftest-fpu
* kselftest-futex
* kselftest-gpio
* kselftest-intel_pstate
* kselftest-ipc
* kselftest-ir
* kselftest-kcmp
* kselftest-kexec
* kselftest-kvm
* kselftest-lib
* kselftest-livepatch
* kselftest-membarrier
* kselftest-memfd
* kselftest-memory-hotplug
* kselftest-mincore
* kselftest-mount
* kselftest-mqueue
* kselftest-net
* kselftest-netfilter
* kselftest-nsfs
* kselftest-openat2
* kselftest-pid_namespace
* kselftest-pidfd
* kselftest-proc
* kselftest-pstore
* kselftest-ptrace
* kselftest-rseq
* kselftest-rtc
* kselftest-seccomp
* kselftest-sigaltstack
* kselftest-size
* kselftest-splice
* kselftest-static_keys
* kselftest-sync
* kselftest-sysctl
* kselftest-tc-testing
* kselftest-timens
* kselftest-timers
* kselftest-tmpfs
* kselftest-tpm2
* kselftest-user
* kselftest-vm
* kselftest-x86
* kselftest-zram
* kunit
* kvm-unit-tests
* libgpiod
* libhugetlbfs
* linux-log-parser
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-containers-tests
* ltp-controllers-tests
* ltp-cpuhotplug-tests
* ltp-crypto-tests
* ltp-cve-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-nptl-tests
* ltp-open-posix-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-syscalls-tests
* ltp-tracing-tests
* network-basic-tests
* packetdrill
* perf
* perf/Zstd-perf.data-compression
* rcutorture
* ssuite
* v4l2-compliance
* vdso

--
Linaro LKFT
https://lkft.linaro.org

2022-05-28 20:36:58

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 060/163] random: make credit_entropy_bits() always safe

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

commit a49c010e61e1938be851f5e49ac219d49b704103 upstream.

This is called from various hwgenerator drivers, so rather than having
one "safe" version for userspace and one "unsafe" version for the
kernel, just make everything safe; the checks are cheap and sensible to
have anyway.

Reported-by: Sultan Alsawaf <[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 | 29 +++++++++--------------------
1 file changed, 9 insertions(+), 20 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -447,18 +447,15 @@ static void process_random_ready_list(vo
spin_unlock_irqrestore(&random_ready_list_lock, flags);
}

-/*
- * Credit (or debit) the entropy store with n bits of entropy.
- * Use credit_entropy_bits_safe() if the value comes from userspace
- * or otherwise should be checked for extreme values.
- */
static void credit_entropy_bits(int nbits)
{
int entropy_count, orig;

- if (!nbits)
+ if (nbits <= 0)
return;

+ nbits = min(nbits, POOL_BITS);
+
do {
orig = READ_ONCE(input_pool.entropy_count);
entropy_count = min(POOL_BITS, orig + nbits);
@@ -470,18 +467,6 @@ static void credit_entropy_bits(int nbit
crng_reseed(&primary_crng, true);
}

-static int credit_entropy_bits_safe(int nbits)
-{
- if (nbits < 0)
- return -EINVAL;
-
- /* Cap the value to avoid overflows */
- nbits = min(nbits, POOL_BITS);
-
- credit_entropy_bits(nbits);
- return 0;
-}
-
/*********************************************************************
*
* CRNG using CHACHA20
@@ -1526,7 +1511,10 @@ static long random_ioctl(struct file *f,
return -EPERM;
if (get_user(ent_count, p))
return -EFAULT;
- return credit_entropy_bits_safe(ent_count);
+ if (ent_count < 0)
+ return -EINVAL;
+ credit_entropy_bits(ent_count);
+ return 0;
case RNDADDENTROPY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -1539,7 +1527,8 @@ static long random_ioctl(struct file *f,
retval = write_pool((const char __user *)p, size);
if (retval < 0)
return retval;
- return credit_entropy_bits_safe(ent_count);
+ credit_entropy_bits(ent_count);
+ return 0;
case RNDZAPENTCNT:
case RNDCLEARPOOL:
/*



2022-05-28 20:37:36

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 122/163] ia64: define get_cycles macro for arch-override

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

commit 57c0900b91d8891ab43f0e6b464d059fda51d102 upstream.

Itanium 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]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/ia64/include/asm/timex.h | 1 +
1 file changed, 1 insertion(+)

--- a/arch/ia64/include/asm/timex.h
+++ b/arch/ia64/include/asm/timex.h
@@ -39,6 +39,7 @@ get_cycles (void)
ret = ia64_getreg(_IA64_REG_AR_ITC);
return ret;
}
+#define get_cycles get_cycles

extern void ia64_cpu_local_tick (void);
extern unsigned long long ia64_native_sched_clock (void);



2022-05-28 20:38:14

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 019/163] crypto: blake2s - move update and final logic to internal/blake2s.h

From: Eric Biggers <[email protected]>

commit 057edc9c8bb2d5ff5b058b521792c392428a0714 upstream.

Move most of blake2s_update() and blake2s_final() into new inline
functions __blake2s_update() and __blake2s_final() in
include/crypto/internal/blake2s.h so that this logic can be shared by
the shash helper functions. This will avoid duplicating this logic
between the library and shash implementations.

Signed-off-by: Eric Biggers <[email protected]>
Acked-by: Ard Biesheuvel <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/crypto/internal/blake2s.h | 41 ++++++++++++++++++++++++++++++++
lib/crypto/blake2s.c | 48 ++++++--------------------------------
2 files changed, 49 insertions(+), 40 deletions(-)

--- a/include/crypto/internal/blake2s.h
+++ b/include/crypto/internal/blake2s.h
@@ -4,6 +4,7 @@
#define BLAKE2S_INTERNAL_H

#include <crypto/blake2s.h>
+#include <linux/string.h>

struct blake2s_tfm_ctx {
u8 key[BLAKE2S_KEY_SIZE];
@@ -23,4 +24,44 @@ static inline void blake2s_set_lastblock
state->f[0] = -1;
}

+typedef void (*blake2s_compress_t)(struct blake2s_state *state,
+ const u8 *block, size_t nblocks, u32 inc);
+
+static inline void __blake2s_update(struct blake2s_state *state,
+ const u8 *in, size_t inlen,
+ blake2s_compress_t compress)
+{
+ const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;
+
+ if (unlikely(!inlen))
+ return;
+ if (inlen > fill) {
+ memcpy(state->buf + state->buflen, in, fill);
+ (*compress)(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
+ state->buflen = 0;
+ in += fill;
+ inlen -= fill;
+ }
+ if (inlen > BLAKE2S_BLOCK_SIZE) {
+ const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE);
+ /* Hash one less (full) block than strictly possible */
+ (*compress)(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
+ in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
+ inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
+ }
+ memcpy(state->buf + state->buflen, in, inlen);
+ state->buflen += inlen;
+}
+
+static inline void __blake2s_final(struct blake2s_state *state, u8 *out,
+ blake2s_compress_t compress)
+{
+ blake2s_set_lastblock(state);
+ memset(state->buf + state->buflen, 0,
+ BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
+ (*compress)(state, state->buf, 1, state->buflen);
+ cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
+ memcpy(out, state->h, state->outlen);
+}
+
#endif /* BLAKE2S_INTERNAL_H */
--- a/lib/crypto/blake2s.c
+++ b/lib/crypto/blake2s.c
@@ -15,55 +15,23 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/bug.h>
-#include <asm/unaligned.h>
+
+#if IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S)
+# define blake2s_compress blake2s_compress_arch
+#else
+# define blake2s_compress blake2s_compress_generic
+#endif

void blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen)
{
- const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;
-
- if (unlikely(!inlen))
- return;
- if (inlen > fill) {
- memcpy(state->buf + state->buflen, in, fill);
- if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S))
- blake2s_compress_arch(state, state->buf, 1,
- BLAKE2S_BLOCK_SIZE);
- else
- blake2s_compress_generic(state, state->buf, 1,
- BLAKE2S_BLOCK_SIZE);
- state->buflen = 0;
- in += fill;
- inlen -= fill;
- }
- if (inlen > BLAKE2S_BLOCK_SIZE) {
- const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE);
- /* Hash one less (full) block than strictly possible */
- if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S))
- blake2s_compress_arch(state, in, nblocks - 1,
- BLAKE2S_BLOCK_SIZE);
- else
- blake2s_compress_generic(state, in, nblocks - 1,
- BLAKE2S_BLOCK_SIZE);
- in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
- inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
- }
- memcpy(state->buf + state->buflen, in, inlen);
- state->buflen += inlen;
+ __blake2s_update(state, in, inlen, blake2s_compress);
}
EXPORT_SYMBOL(blake2s_update);

void blake2s_final(struct blake2s_state *state, u8 *out)
{
WARN_ON(IS_ENABLED(DEBUG) && !out);
- blake2s_set_lastblock(state);
- memset(state->buf + state->buflen, 0,
- BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
- if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S))
- blake2s_compress_arch(state, state->buf, 1, state->buflen);
- else
- blake2s_compress_generic(state, state->buf, 1, state->buflen);
- cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
- memcpy(out, state->h, state->outlen);
+ __blake2s_final(state, out, blake2s_compress);
memzero_explicit(state, sizeof(*state));
}
EXPORT_SYMBOL(blake2s_final);



2022-05-28 20:39:15

by Jason A. Donenfeld

[permalink] [raw]
Subject: Re: [PATCH 5.10 000/163] 5.10.119-rc1 review

On 5/28/22, Guenter Roeck <[email protected]> wrote:
> On Fri, May 27, 2022 at 11:10:35PM +0200, Jason A. Donenfeld wrote:
>> Hi Guenter,
>>
>> On Fri, May 27, 2022 at 09:59:14AM -0700, Guenter Roeck wrote:
>> > Given that we (ChromeOS) have been hit by rng related
>> > issues before (specifically boot stalls on some hardware), I am quite
>> > concerned about the possible impact of this series for stable releases.
>>
>> The urandom try_to_generate_entropy() change from 5.18 wasn't backported.
>>
>
> Was it not backported on purpose or is it missing ?
>

On purpose, on account of the concern that you expressed. Hence I
mentioned it in response to your message.

Jason

2022-05-28 20:39:41

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 063/163] random: fix locking in crng_fast_load()

From: Dominik Brodowski <[email protected]>

commit 7c2fe2b32bf76441ff5b7a425b384e5f75aa530a upstream.

crng_init is protected by primary_crng->lock, so keep holding that lock
when incrementing crng_init from 0 to 1 in crng_fast_load(). The call to
pr_notice() can wait until the lock is released; this code path cannot
be reached twice, as crng_fast_load() aborts early if crng_init > 0.

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 | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -647,12 +647,13 @@ static size_t crng_fast_load(const u8 *c
p[crng_init_cnt % CHACHA_KEY_SIZE] ^= *cp;
cp++; crng_init_cnt++; len--; ret++;
}
- spin_unlock_irqrestore(&primary_crng.lock, flags);
if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) {
invalidate_batched_entropy();
crng_init = 1;
- pr_notice("fast init done\n");
}
+ spin_unlock_irqrestore(&primary_crng.lock, flags);
+ if (crng_init == 1)
+ pr_notice("fast init done\n");
return ret;
}




2022-05-28 20:39:45

by Sudip Mukherjee

[permalink] [raw]
Subject: Re: [PATCH 5.10 000/163] 5.10.119-rc1 review

Hi Greg,

On Fri, May 27, 2022 at 10:48:00AM +0200, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.10.119 release.
> There are 163 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:26 +0000.
> Anything received after that time might be too late.

Build test:
mips (gcc version 11.3.1 20220517): 63 configs -> no failure
arm (gcc version 11.3.1 20220517): 105 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.
x86_64: Booted on qemu. No regression. [1]
arm64: Booted on rpi4b (4GB model). No regression. [2]

[1]. https://openqa.qa.codethink.co.uk/tests/1218
[2]. https://openqa.qa.codethink.co.uk/tests/1220


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

--
Regards
Sudip


2022-05-28 20:40:05

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 150/163] random: handle latent entropy and command line from random_init()

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

commit 2f14062bb14b0fcfcc21e6dc7d5b5c0d25966164 upstream.

Currently, start_kernel() adds latent entropy and the command line to
the entropy bool *after* the RNG has been initialized, deferring when
it's actually used by things like stack canaries until the next time
the pool is seeded. This surely is not intended.

Rather than splitting up which entropy gets added where and when between
start_kernel() and random_init(), just do everything in random_init(),
which should eliminate these kinds of bugs in the future.

While we're at it, rename the awkwardly titled "rand_initialize()" to
the more standard "random_init()" nomenclature.

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 | 13 ++++++++-----
include/linux/random.h | 16 +++++++---------
init/main.c | 10 +++-------
3 files changed, 18 insertions(+), 21 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -888,12 +888,13 @@ early_param("random.trust_bootloader", p

/*
* The first collection of entropy occurs at system boot while interrupts
- * are still turned off. Here we push in RDSEED, a timestamp, and utsname().
- * Depending on the above configuration knob, RDSEED may be considered
- * sufficient for initialization. Note that much earlier setup may already
- * have pushed entropy into the input pool by the time we get here.
+ * are still turned off. Here we push in latent entropy, RDSEED, a timestamp,
+ * utsname(), and the command line. Depending on the above configuration knob,
+ * RDSEED may be considered sufficient for initialization. Note that much
+ * earlier setup may already have pushed entropy into the input pool by the
+ * time we get here.
*/
-int __init rand_initialize(void)
+int __init random_init(const char *command_line)
{
size_t i;
ktime_t now = ktime_get_real();
@@ -915,6 +916,8 @@ int __init rand_initialize(void)
}
_mix_pool_bytes(&now, sizeof(now));
_mix_pool_bytes(utsname(), sizeof(*(utsname())));
+ _mix_pool_bytes(command_line, strlen(command_line));
+ add_latent_entropy();

if (crng_ready())
crng_reseed();
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -14,26 +14,24 @@ struct notifier_block;

extern void add_device_randomness(const void *, size_t);
extern void add_bootloader_randomness(const void *, size_t);
+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);

#if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__)
static inline void add_latent_entropy(void)
{
- add_device_randomness((const void *)&latent_entropy,
- sizeof(latent_entropy));
+ add_device_randomness((const void *)&latent_entropy, sizeof(latent_entropy));
}
#else
static inline void add_latent_entropy(void) {}
#endif

-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);
-extern int __init rand_initialize(void);
+extern int __init random_init(const char *command_line);
extern bool rng_is_initialized(void);
extern int register_random_ready_notifier(struct notifier_block *nb);
extern int unregister_random_ready_notifier(struct notifier_block *nb);
--- a/init/main.c
+++ b/init/main.c
@@ -957,15 +957,11 @@ asmlinkage __visible void __init __no_sa
/*
* 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()
+ * - timekeeping_init() for ktime entropy used in random_init()
* - 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
+ * - random_init() to initialize the RNG from from early entropy sources
*/
- rand_initialize();
- add_latent_entropy();
- add_device_randomness(command_line, strlen(command_line));
+ random_init(command_line);
boot_init_stack_canary();

perf_event_init();



2022-05-28 20:40:21

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 125/163] alpha: define get_cycles macro for arch-override

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

commit 1097710bc9660e1e588cf2186a35db3d95c4d258 upstream.

Alpha 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: Richard Henderson <[email protected]>
Cc: Ivan Kokshaysky <[email protected]>
Acked-by: Matt Turner <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/alpha/include/asm/timex.h | 1 +
1 file changed, 1 insertion(+)

--- a/arch/alpha/include/asm/timex.h
+++ b/arch/alpha/include/asm/timex.h
@@ -28,5 +28,6 @@ static inline cycles_t get_cycles (void)
__asm__ __volatile__ ("rpcc %0" : "=r"(ret));
return ret;
}
+#define get_cycles get_cycles

#endif



2022-05-28 20:40:44

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 041/163] random: cleanup poolinfo abstraction

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

commit 91ec0fe138f107232cb36bc6112211db37cb5306 upstream.

Now that we're only using one polynomial, we can cleanup its
representation into constants, instead of passing around pointers
dynamically to select different polynomials. This improves the codegen
and makes the code a bit more straightforward.

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 | 67 ++++++++++++++++++++++----------------------------
1 file changed, 30 insertions(+), 37 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -430,14 +430,20 @@ static int random_write_wakeup_bits = 28
* polynomial which improves the resulting TGFSR polynomial to be
* irreducible, which we have made here.
*/
-static const struct poolinfo {
- int poolbitshift, poolwords, poolbytes, poolfracbits;
-#define S(x) ilog2(x)+5, (x), (x)*4, (x) << (ENTROPY_SHIFT+5)
- int tap1, tap2, tap3, tap4, tap5;
-} poolinfo_table[] = {
- /* was: x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 */
+enum poolinfo {
+ POOL_WORDS = 128,
+ POOL_WORDMASK = POOL_WORDS - 1,
+ POOL_BYTES = POOL_WORDS * sizeof(u32),
+ POOL_BITS = POOL_BYTES * 8,
+ POOL_BITSHIFT = ilog2(POOL_WORDS) + 5,
+ POOL_FRACBITS = POOL_WORDS << (ENTROPY_SHIFT + 5),
+
/* x^128 + x^104 + x^76 + x^51 +x^25 + x + 1 */
- { S(128), 104, 76, 51, 25, 1 },
+ POOL_TAP1 = 104,
+ POOL_TAP2 = 76,
+ POOL_TAP3 = 51,
+ POOL_TAP4 = 25,
+ POOL_TAP5 = 1
};

/*
@@ -503,7 +509,6 @@ MODULE_PARM_DESC(ratelimit_disable, "Dis
struct entropy_store;
struct entropy_store {
/* read-only data: */
- const struct poolinfo *poolinfo;
__u32 *pool;
const char *name;

@@ -525,7 +530,6 @@ static void crng_reseed(struct crng_stat
static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy;

static struct entropy_store input_pool = {
- .poolinfo = &poolinfo_table[0],
.name = "input",
.lock = __SPIN_LOCK_UNLOCKED(input_pool.lock),
.pool = input_pool_data
@@ -548,33 +552,26 @@ static __u32 const twist_table[8] = {
static void _mix_pool_bytes(struct entropy_store *r, const void *in,
int nbytes)
{
- unsigned long i, tap1, tap2, tap3, tap4, tap5;
+ unsigned long i;
int input_rotate;
- int wordmask = r->poolinfo->poolwords - 1;
const unsigned char *bytes = in;
__u32 w;

- tap1 = r->poolinfo->tap1;
- tap2 = r->poolinfo->tap2;
- tap3 = r->poolinfo->tap3;
- tap4 = r->poolinfo->tap4;
- tap5 = r->poolinfo->tap5;
-
input_rotate = r->input_rotate;
i = r->add_ptr;

/* mix one byte at a time to simplify size handling and churn faster */
while (nbytes--) {
w = rol32(*bytes++, input_rotate);
- i = (i - 1) & wordmask;
+ i = (i - 1) & POOL_WORDMASK;

/* XOR in the various taps */
w ^= r->pool[i];
- w ^= r->pool[(i + tap1) & wordmask];
- w ^= r->pool[(i + tap2) & wordmask];
- w ^= r->pool[(i + tap3) & wordmask];
- w ^= r->pool[(i + tap4) & wordmask];
- w ^= r->pool[(i + tap5) & wordmask];
+ w ^= r->pool[(i + POOL_TAP1) & POOL_WORDMASK];
+ w ^= r->pool[(i + POOL_TAP2) & POOL_WORDMASK];
+ w ^= r->pool[(i + POOL_TAP3) & POOL_WORDMASK];
+ w ^= r->pool[(i + POOL_TAP4) & POOL_WORDMASK];
+ w ^= r->pool[(i + POOL_TAP5) & POOL_WORDMASK];

/* Mix the result back in with a twist */
r->pool[i] = (w >> 3) ^ twist_table[w & 7];
@@ -672,7 +669,6 @@ static void process_random_ready_list(vo
static void credit_entropy_bits(struct entropy_store *r, int nbits)
{
int entropy_count, orig;
- const int pool_size = r->poolinfo->poolfracbits;
int nfrac = nbits << ENTROPY_SHIFT;

if (!nbits)
@@ -706,25 +702,25 @@ retry:
* turns no matter how large nbits is.
*/
int pnfrac = nfrac;
- const int s = r->poolinfo->poolbitshift + ENTROPY_SHIFT + 2;
+ const int s = POOL_BITSHIFT + ENTROPY_SHIFT + 2;
/* The +2 corresponds to the /4 in the denominator */

do {
- unsigned int anfrac = min(pnfrac, pool_size/2);
+ unsigned int anfrac = min(pnfrac, POOL_FRACBITS/2);
unsigned int add =
- ((pool_size - entropy_count)*anfrac*3) >> s;
+ ((POOL_FRACBITS - entropy_count)*anfrac*3) >> s;

entropy_count += add;
pnfrac -= anfrac;
- } while (unlikely(entropy_count < pool_size-2 && pnfrac));
+ } while (unlikely(entropy_count < POOL_FRACBITS-2 && pnfrac));
}

if (WARN_ON(entropy_count < 0)) {
pr_warn("negative entropy/overflow: pool %s count %d\n",
r->name, entropy_count);
entropy_count = 0;
- } else if (entropy_count > pool_size)
- entropy_count = pool_size;
+ } else if (entropy_count > POOL_FRACBITS)
+ entropy_count = POOL_FRACBITS;
if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
goto retry;

@@ -741,13 +737,11 @@ retry:

static int credit_entropy_bits_safe(struct entropy_store *r, int nbits)
{
- const int nbits_max = r->poolinfo->poolwords * 32;
-
if (nbits < 0)
return -EINVAL;

/* Cap the value to avoid overflows */
- nbits = min(nbits, nbits_max);
+ nbits = min(nbits, POOL_BITS);

credit_entropy_bits(r, nbits);
return 0;
@@ -1343,7 +1337,7 @@ static size_t account(struct entropy_sto
int entropy_count, orig, have_bytes;
size_t ibytes, nfrac;

- BUG_ON(r->entropy_count > r->poolinfo->poolfracbits);
+ BUG_ON(r->entropy_count > POOL_FRACBITS);

/* Can we pull enough? */
retry:
@@ -1409,8 +1403,7 @@ static void extract_buf(struct entropy_s

/* Generate a hash across the pool */
spin_lock_irqsave(&r->lock, flags);
- blake2s_update(&state, (const u8 *)r->pool,
- r->poolinfo->poolwords * sizeof(*r->pool));
+ blake2s_update(&state, (const u8 *)r->pool, POOL_BYTES);
blake2s_final(&state, hash); /* final zeros out state */

/*
@@ -1766,7 +1759,7 @@ static void __init init_std_data(struct
unsigned long rv;

mix_pool_bytes(r, &now, sizeof(now));
- for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) {
+ for (i = POOL_BYTES; i > 0; i -= sizeof(rv)) {
if (!arch_get_random_seed_long(&rv) &&
!arch_get_random_long(&rv))
rv = random_get_entropy();



2022-05-28 20:41:14

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 067/163] random: ensure early RDSEED goes through mixer on init

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

commit a02cf3d0dd77244fd5333ac48d78871de459ae6d upstream.

Continuing the reasoning of "random: use RDSEED instead of RDRAND in
entropy extraction" from this series, at init time we also don't want to
be xoring RDSEED directly into the crng. Instead it's safer to put it
into our entropy collector and then re-extract it, so that it goes
through a hash function with preimage resistance. As a matter of hygiene,
we also order these now so that the RDSEED byte are hashed in first,
followed by the bytes that are likely more predictable (e.g. utsname()).

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 | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)

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

- mix_pool_bytes(&now, sizeof(now));
for (i = BLAKE2S_BLOCK_SIZE; i > 0; i -= sizeof(rv)) {
- if (!arch_get_random_seed_long(&rv) &&
- !arch_get_random_long(&rv))
- rv = random_get_entropy();
- mix_pool_bytes(&rv, sizeof(rv));
- }
- mix_pool_bytes(utsname(), sizeof(*(utsname())));
-
- 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;
+ mix_pool_bytes(&rv, sizeof(rv));
}
+ mix_pool_bytes(&now, sizeof(now));
+ mix_pool_bytes(utsname(), sizeof(*(utsname())));
+
+ extract_entropy(&primary_crng.state[4], sizeof(u32) * 12);
if (arch_init && trust_cpu && crng_init < 2) {
invalidate_batched_entropy();
crng_init = 2;



2022-05-28 20:42:24

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 096/163] random: clear fast pool, crng, and batches in cpuhp bring up

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

commit 3191dd5a1179ef0fad5a050a1702ae98b6251e8f upstream.

For the irq randomness fast pool, rather than having to use expensive
atomics, which were visibly the most expensive thing in the entire irq
handler, simply take care of the extreme edge case of resetting count to
zero in the cpuhp online handler, just after workqueues have been
reenabled. This simplifies the code a bit and lets us use vanilla
variables rather than atomics, and performance should be improved.

As well, very early on when the CPU comes up, while interrupts are still
disabled, we clear out the per-cpu crng and its batches, so that it
always starts with fresh randomness.

Cc: Thomas Gleixner <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Theodore Ts'o <[email protected]>
Cc: Sultan Alsawaf <[email protected]>
Cc: Dominik Brodowski <[email protected]>
Acked-by: Sebastian Andrzej Siewior <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 62 ++++++++++++++++++++++++++++++++++-----------
include/linux/cpuhotplug.h | 2 +
include/linux/random.h | 5 +++
kernel/cpu.c | 11 +++++++
4 files changed, 65 insertions(+), 15 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -698,6 +698,25 @@ u32 get_random_u32(void)
}
EXPORT_SYMBOL(get_random_u32);

+#ifdef CONFIG_SMP
+/*
+ * This function is called when the CPU is coming up, with entry
+ * CPUHP_RANDOM_PREPARE, which comes before CPUHP_WORKQUEUE_PREP.
+ */
+int random_prepare_cpu(unsigned int cpu)
+{
+ /*
+ * When the cpu comes back online, immediately invalidate both
+ * the per-cpu crng and all batches, so that we serve fresh
+ * randomness.
+ */
+ per_cpu_ptr(&crngs, cpu)->generation = ULONG_MAX;
+ per_cpu_ptr(&batched_entropy_u32, cpu)->position = UINT_MAX;
+ per_cpu_ptr(&batched_entropy_u64, cpu)->position = UINT_MAX;
+ return 0;
+}
+#endif
+
/**
* randomize_page - Generate a random, page aligned address
* @start: The smallest acceptable address the caller will take.
@@ -1183,7 +1202,7 @@ struct fast_pool {
};
struct work_struct mix;
unsigned long last;
- atomic_t count;
+ unsigned int count;
u16 reg_idx;
};

@@ -1219,6 +1238,29 @@ static void fast_mix(u32 pool[4])

static DEFINE_PER_CPU(struct fast_pool, irq_randomness);

+#ifdef CONFIG_SMP
+/*
+ * This function is called when the CPU has just come online, with
+ * entry CPUHP_AP_RANDOM_ONLINE, just after CPUHP_AP_WORKQUEUE_ONLINE.
+ */
+int random_online_cpu(unsigned int cpu)
+{
+ /*
+ * During CPU shutdown and before CPU onlining, add_interrupt_
+ * randomness() may schedule mix_interrupt_randomness(), and
+ * set the MIX_INFLIGHT flag. However, because the worker can
+ * be scheduled on a different CPU during this period, that
+ * flag will never be cleared. For that reason, we zero out
+ * the flag here, which runs just after workqueues are onlined
+ * for the CPU again. This also has the effect of setting the
+ * irq randomness count to zero so that new accumulated irqs
+ * are fresh.
+ */
+ per_cpu_ptr(&irq_randomness, cpu)->count = 0;
+ return 0;
+}
+#endif
+
static u32 get_reg(struct fast_pool *f, struct pt_regs *regs)
{
u32 *ptr = (u32 *)regs;
@@ -1243,15 +1285,6 @@ static void mix_interrupt_randomness(str
local_irq_disable();
if (fast_pool != this_cpu_ptr(&irq_randomness)) {
local_irq_enable();
- /*
- * If we are unlucky enough to have been moved to another CPU,
- * during CPU hotplug while the CPU was shutdown then we set
- * our count to zero atomically so that when the CPU comes
- * back online, it can enqueue work again. The _release here
- * pairs with the atomic_inc_return_acquire in
- * add_interrupt_randomness().
- */
- atomic_set_release(&fast_pool->count, 0);
return;
}

@@ -1260,7 +1293,7 @@ static void mix_interrupt_randomness(str
* consistent view, before we reenable irqs again.
*/
memcpy(pool, fast_pool->pool32, sizeof(pool));
- atomic_set(&fast_pool->count, 0);
+ fast_pool->count = 0;
fast_pool->last = jiffies;
local_irq_enable();

@@ -1296,14 +1329,13 @@ void add_interrupt_randomness(int irq)
}

fast_mix(fast_pool->pool32);
- /* The _acquire here pairs with the atomic_set_release in mix_interrupt_randomness(). */
- new_count = (unsigned int)atomic_inc_return_acquire(&fast_pool->count);
+ new_count = ++fast_pool->count;

if (unlikely(crng_init == 0)) {
if (new_count >= 64 &&
crng_pre_init_inject(fast_pool->pool32, sizeof(fast_pool->pool32),
true, true) > 0) {
- atomic_set(&fast_pool->count, 0);
+ fast_pool->count = 0;
fast_pool->last = now;
if (spin_trylock(&input_pool.lock)) {
_mix_pool_bytes(&fast_pool->pool32, sizeof(fast_pool->pool32));
@@ -1321,7 +1353,7 @@ void add_interrupt_randomness(int irq)

if (unlikely(!fast_pool->mix.func))
INIT_WORK(&fast_pool->mix, mix_interrupt_randomness);
- atomic_or(MIX_INFLIGHT, &fast_pool->count);
+ fast_pool->count |= MIX_INFLIGHT;
queue_work_on(raw_smp_processor_id(), system_highpri_wq, &fast_pool->mix);
}
EXPORT_SYMBOL_GPL(add_interrupt_randomness);
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -61,6 +61,7 @@ enum cpuhp_state {
CPUHP_LUSTRE_CFS_DEAD,
CPUHP_AP_ARM_CACHE_B15_RAC_DEAD,
CPUHP_PADATA_DEAD,
+ CPUHP_RANDOM_PREPARE,
CPUHP_WORKQUEUE_PREP,
CPUHP_POWER_NUMA_PREPARE,
CPUHP_HRTIMERS_PREPARE,
@@ -187,6 +188,7 @@ enum cpuhp_state {
CPUHP_AP_PERF_POWERPC_HV_GPCI_ONLINE,
CPUHP_AP_WATCHDOG_ONLINE,
CPUHP_AP_WORKQUEUE_ONLINE,
+ CPUHP_AP_RANDOM_ONLINE,
CPUHP_AP_RCUTREE_ONLINE,
CPUHP_AP_BASE_CACHEINFO_ONLINE,
CPUHP_AP_ONLINE_DYN,
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -156,4 +156,9 @@ static inline bool __init arch_get_rando
}
#endif

+#ifdef CONFIG_SMP
+extern int random_prepare_cpu(unsigned int cpu);
+extern int random_online_cpu(unsigned int cpu);
+#endif
+
#endif /* _LINUX_RANDOM_H */
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -34,6 +34,7 @@
#include <linux/scs.h>
#include <linux/percpu-rwsem.h>
#include <linux/cpuset.h>
+#include <linux/random.h>

#include <trace/events/power.h>
#define CREATE_TRACE_POINTS
@@ -1581,6 +1582,11 @@ static struct cpuhp_step cpuhp_hp_states
.startup.single = perf_event_init_cpu,
.teardown.single = perf_event_exit_cpu,
},
+ [CPUHP_RANDOM_PREPARE] = {
+ .name = "random:prepare",
+ .startup.single = random_prepare_cpu,
+ .teardown.single = NULL,
+ },
[CPUHP_WORKQUEUE_PREP] = {
.name = "workqueue:prepare",
.startup.single = workqueue_prepare_cpu,
@@ -1697,6 +1703,11 @@ static struct cpuhp_step cpuhp_hp_states
.startup.single = workqueue_online_cpu,
.teardown.single = workqueue_offline_cpu,
},
+ [CPUHP_AP_RANDOM_ONLINE] = {
+ .name = "random:online",
+ .startup.single = random_online_cpu,
+ .teardown.single = NULL,
+ },
[CPUHP_AP_RCUTREE_ONLINE] = {
.name = "RCU/tree:online",
.startup.single = rcutree_online_cpu,



2022-05-28 20:42:42

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 114/163] random: do not allow user to keep crng key around on stack

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

commit aba120cc101788544aa3e2c30c8da88513892350 upstream.

The fast key erasure RNG design relies on the key that's used to be used
and then discarded. We do this, making judicious use of
memzero_explicit(). However, reads to /dev/urandom and calls to
getrandom() involve a copy_to_user(), and userspace can use FUSE or
userfaultfd, or make a massive call, dynamically remap memory addresses
as it goes, and set the process priority to idle, in order to keep a
kernel stack alive indefinitely. By probing
/proc/sys/kernel/random/entropy_avail to learn when the crng key is
refreshed, a malicious userspace could mount this attack every 5 minutes
thereafter, breaking the crng's forward secrecy.

In order to fix this, we just overwrite the stack's key with the first
32 bytes of the "free" fast key erasure output. If we're returning <= 32
bytes to the user, then we can still return those bytes directly, so
that short reads don't become slower. And for long reads, the difference
is hopefully lost in the amortization, so it doesn't change much, with
that amortization helping variously for medium reads.

We don't need to do this for get_random_bytes() and the various
kernel-space callers, and later, if we ever switch to always batching,
this won't be necessary either, so there's no need to change the API of
these functions.

Cc: Theodore Ts'o <[email protected]>
Reviewed-by: Jann Horn <[email protected]>
Fixes: c92e040d575a ("random: add backtracking protection to the CRNG")
Fixes: 186873c549df ("random: use simpler fast key erasure flow on per-cpu keys")
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 35 +++++++++++++++++++++++------------
1 file changed, 23 insertions(+), 12 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -534,19 +534,29 @@ static ssize_t get_random_bytes_user(voi
if (!nbytes)
return 0;

- len = min_t(size_t, 32, nbytes);
- crng_make_state(chacha_state, output, len);
-
- if (copy_to_user(buf, output, len))
- return -EFAULT;
- nbytes -= len;
- buf += len;
- ret += len;
+ /*
+ * Immediately overwrite the ChaCha key at index 4 with random
+ * bytes, in case userspace causes copy_to_user() below to sleep
+ * forever, so that we still retain forward secrecy in that case.
+ */
+ crng_make_state(chacha_state, (u8 *)&chacha_state[4], CHACHA_KEY_SIZE);
+ /*
+ * However, if we're doing a read of len <= 32, we don't need to
+ * use chacha_state after, so we can simply return those bytes to
+ * the user directly.
+ */
+ if (nbytes <= CHACHA_KEY_SIZE) {
+ ret = copy_to_user(buf, &chacha_state[4], nbytes) ? -EFAULT : nbytes;
+ goto out_zero_chacha;
+ }

- while (nbytes) {
+ do {
if (large_request && need_resched()) {
- if (signal_pending(current))
+ if (signal_pending(current)) {
+ if (!ret)
+ ret = -ERESTARTSYS;
break;
+ }
schedule();
}

@@ -563,10 +573,11 @@ static ssize_t get_random_bytes_user(voi
nbytes -= len;
buf += len;
ret += len;
- }
+ } while (nbytes);

- memzero_explicit(chacha_state, sizeof(chacha_state));
memzero_explicit(output, sizeof(output));
+out_zero_chacha:
+ memzero_explicit(chacha_state, sizeof(chacha_state));
return ret;
}




2022-05-28 20:42:54

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 157/163] random: move randomize_page() into mm where it belongs

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

commit 5ad7dd882e45d7fe432c32e896e2aaa0b21746ea upstream.

randomize_page is an mm function. It is documented like one. It contains
the history of one. It has the naming convention of one. It looks
just like another very similar function in mm, randomize_stack_top().
And it has always been maintained and updated by mm people. There is no
need for it to be in random.c. In the "which shape does not look like
the other ones" test, pointing to randomize_page() is correct.

So move randomize_page() into mm/util.c, right next to the similar
randomize_stack_top() function.

This commit contains no actual code changes.

Cc: Andrew Morton <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 32 --------------------------------
include/linux/mm.h | 1 +
include/linux/random.h | 2 --
mm/util.c | 32 ++++++++++++++++++++++++++++++++
4 files changed, 33 insertions(+), 34 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -624,38 +624,6 @@ int __cold random_prepare_cpu(unsigned i
}
#endif

-/**
- * randomize_page - Generate a random, page aligned address
- * @start: The smallest acceptable address the caller will take.
- * @range: The size of the area, starting at @start, within which the
- * random address must fall.
- *
- * If @start + @range would overflow, @range is capped.
- *
- * NOTE: Historical use of randomize_range, which this replaces, presumed that
- * @start was already page aligned. We now align it regardless.
- *
- * Return: A page aligned address within [start, start + range). On error,
- * @start is returned.
- */
-unsigned long randomize_page(unsigned long start, unsigned long range)
-{
- if (!PAGE_ALIGNED(start)) {
- range -= PAGE_ALIGN(start) - start;
- start = PAGE_ALIGN(start);
- }
-
- if (start > ULONG_MAX - range)
- range = ULONG_MAX - start;
-
- range >>= PAGE_SHIFT;
-
- if (range == 0)
- return start;
-
- return start + (get_random_long() % range << PAGE_SHIFT);
-}
-
/*
* This function will use the architecture-specific hardware random
* number generator if it is available. It is not recommended for
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2585,6 +2585,7 @@ extern int install_special_mapping(struc
unsigned long flags, struct page **pages);

unsigned long randomize_stack_top(unsigned long stack_top);
+unsigned long randomize_page(unsigned long start, unsigned long range);

extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);

--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -64,8 +64,6 @@ static inline unsigned long get_random_c
return get_random_long() & CANARY_MASK;
}

-unsigned long randomize_page(unsigned long start, unsigned long range);
-
int __init random_init(const char *command_line);
bool rng_is_initialized(void);
int wait_for_random_bytes(void);
--- a/mm/util.c
+++ b/mm/util.c
@@ -331,6 +331,38 @@ unsigned long randomize_stack_top(unsign
#endif
}

+/**
+ * randomize_page - Generate a random, page aligned address
+ * @start: The smallest acceptable address the caller will take.
+ * @range: The size of the area, starting at @start, within which the
+ * random address must fall.
+ *
+ * If @start + @range would overflow, @range is capped.
+ *
+ * NOTE: Historical use of randomize_range, which this replaces, presumed that
+ * @start was already page aligned. We now align it regardless.
+ *
+ * Return: A page aligned address within [start, start + range). On error,
+ * @start is returned.
+ */
+unsigned long randomize_page(unsigned long start, unsigned long range)
+{
+ if (!PAGE_ALIGNED(start)) {
+ range -= PAGE_ALIGN(start) - start;
+ start = PAGE_ALIGN(start);
+ }
+
+ if (start > ULONG_MAX - range)
+ range = ULONG_MAX - start;
+
+ range >>= PAGE_SHIFT;
+
+ if (range == 0)
+ return start;
+
+ return start + (get_random_long() % range << PAGE_SHIFT);
+}
+
#ifdef CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
unsigned long arch_randomize_brk(struct mm_struct *mm)
{



2022-05-28 20:46:04

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 095/163] 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:46:12

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 004/163] KVM: x86/mmu: fix NULL pointer dereference on guest INVPCID

From: Paolo Bonzini <[email protected]>

commit 9f46c187e2e680ecd9de7983e4d081c3391acc76 upstream.

With shadow paging enabled, the INVPCID instruction results in a call
to kvm_mmu_invpcid_gva. If INVPCID is executed with CR0.PG=0, the
invlpg callback is not set and the result is a NULL pointer dereference.
Fix it trivially by checking for mmu->invlpg before every call.

There are other possibilities:

- check for CR0.PG, because KVM (like all Intel processors after P5)
flushes guest TLB on CR0.PG changes so that INVPCID/INVLPG are a
nop with paging disabled

- check for EFER.LMA, because KVM syncs and flushes when switching
MMU contexts outside of 64-bit mode

All of these are tricky, go for the simple solution. This is CVE-2022-1789.

Reported-by: Yongkang Jia <[email protected]>
Cc: [email protected]
Signed-off-by: Paolo Bonzini <[email protected]>
[fix conflict due to missing b9e5603c2a3accbadfec570ac501a54431a6bdba]
Signed-off-by: Vegard Nossum <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/x86/kvm/mmu/mmu.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -5178,14 +5178,16 @@ void kvm_mmu_invpcid_gva(struct kvm_vcpu
uint i;

if (pcid == kvm_get_active_pcid(vcpu)) {
- mmu->invlpg(vcpu, gva, mmu->root_hpa);
+ if (mmu->invlpg)
+ mmu->invlpg(vcpu, gva, mmu->root_hpa);
tlb_flush = true;
}

for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++) {
if (VALID_PAGE(mmu->prev_roots[i].hpa) &&
pcid == kvm_get_pcid(vcpu, mmu->prev_roots[i].pgd)) {
- mmu->invlpg(vcpu, gva, mmu->prev_roots[i].hpa);
+ if (mmu->invlpg)
+ mmu->invlpg(vcpu, gva, mmu->prev_roots[i].hpa);
tlb_flush = true;
}
}



2022-05-28 20:46:16

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 115/163] random: check for signal_pending() outside of need_resched() check

From: Jann Horn <[email protected]>

commit 1448769c9cdb69ad65287f4f7ab58bc5f2f5d7ba upstream.

signal_pending() checks TIF_NOTIFY_SIGNAL and TIF_SIGPENDING, which
signal that the task should bail out of the syscall when possible. This
is a separate concept from need_resched(), which checks
TIF_NEED_RESCHED, signaling that the task should preempt.

In particular, with the current code, the signal_pending() bailout
probably won't work reliably.

Change this to look like other functions that read lots of data, such as
read_zero().

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Jann Horn <[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
@@ -551,13 +551,13 @@ static ssize_t get_random_bytes_user(voi
}

do {
- if (large_request && need_resched()) {
+ if (large_request) {
if (signal_pending(current)) {
if (!ret)
ret = -ERESTARTSYS;
break;
}
- schedule();
+ cond_resched();
}

chacha20_block(chacha_state, output);



2022-05-28 20:46:54

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 120/163] 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
@@ -1006,6 +1006,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;
@@ -1013,10 +1016,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:47:50

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 098/163] 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:48:35

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.10 155/163] 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
@@ -210,7 +210,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()
@@ -251,7 +251,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)
@@ -405,24 +405,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;
}
@@ -430,7 +430,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;
}

@@ -447,20 +447,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;

/*
@@ -474,8 +474,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;
}

@@ -484,17 +484,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);
@@ -668,24 +668,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);

@@ -696,15 +696,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)
*
**********************************************************************/

@@ -726,9 +726,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);
}

/*
@@ -736,12 +736,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);
}

@@ -749,7 +749,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];
@@ -778,12 +778,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;
}

@@ -791,16 +791,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);
@@ -836,13 +836,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
@@ -906,7 +904,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;
@@ -914,13 +912,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())));
@@ -943,14 +941,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);
@@ -960,10 +958,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);

/*
@@ -979,11 +976,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);

@@ -1183,8 +1180,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 };
@@ -1303,8 +1299,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;
@@ -1316,8 +1311,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;
@@ -1328,7 +1323,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)
@@ -1337,21 +1332,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();
}

@@ -1360,20 +1355,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;

@@ -1383,22 +1378,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)
@@ -1523,7 +1518,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;
@@ -1550,14 +1545,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);
}

extern 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 22:24:56

by Fox Chen

[permalink] [raw]
Subject: RE: [PATCH 5.10 000/163] 5.10.119-rc1 review

On Fri, 27 May 2022 10:48:00 +0200, Greg Kroah-Hartman <[email protected]> wrote:
> This is the start of the stable review cycle for the 5.10.119 release.
> There are 163 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:26 +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.10.119-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.10.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
>

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

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