2022-05-28 20:18:21

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 000/145] 5.15.44-rc1 review

This is the start of the stable review cycle for the 5.15.44 release.
There are 145 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:32 +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.15.44-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.15.y
and the diffstat can be found below.

thanks,

greg k-h

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

Greg Kroah-Hartman <[email protected]>
Linux 5.15.44-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

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

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

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

Magnus Karlsson <[email protected]>
ice: fix crash at allocation failure

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

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


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

Diffstat:

Documentation/admin-guide/kernel-parameters.txt | 6 +
Documentation/admin-guide/sysctl/kernel.rst | 22 +-
MAINTAINERS | 2 +
Makefile | 4 +-
arch/alpha/include/asm/timex.h | 1 +
arch/arm/crypto/Makefile | 4 +-
arch/arm/crypto/blake2s-core.S | 8 +-
arch/arm/crypto/blake2s-glue.c | 73 +-
arch/arm/crypto/blake2s-shash.c | 75 +
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 | 68 +-
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/mmu/mmu.c | 6 +-
arch/xtensa/include/asm/timex.h | 6 +-
crypto/Kconfig | 3 +-
crypto/blake2s_generic.c | 4 +-
crypto/drbg.c | 17 +-
drivers/acpi/sysfs.c | 25 +-
drivers/char/Kconfig | 3 +-
drivers/char/hw_random/core.c | 1 +
drivers/char/random.c | 3011 +++++++++--------------
drivers/hid/amd-sfh-hid/amd_sfh_client.c | 11 +
drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 7 +
drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 4 +
drivers/hv/vmbus_drv.c | 2 +-
drivers/net/Kconfig | 1 -
drivers/net/ethernet/intel/ice/ice_xsk.c | 2 +-
drivers/net/wireguard/noise.c | 45 +-
include/crypto/blake2s.h | 3 -
include/crypto/chacha.h | 15 +-
include/crypto/drbg.h | 2 +-
include/crypto/internal/blake2s.h | 46 +-
include/linux/cpuhotplug.h | 2 +
include/linux/hw_random.h | 2 -
include/linux/mm.h | 1 +
include/linux/prandom.h | 23 +-
include/linux/random.h | 100 +-
include/linux/siphash.h | 28 +
include/linux/timex.h | 10 +-
include/trace/events/random.h | 247 --
init/main.c | 13 +-
kernel/cpu.c | 11 +
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 | 31 -
lib/crypto/blake2s.c | 47 +-
lib/random32.c | 16 +-
lib/sha1.c | 95 +-
lib/siphash.c | 32 +-
lib/vsprintf.c | 10 +-
mm/util.c | 32 +
sound/pci/ctxfi/ctatc.c | 2 +
sound/pci/ctxfi/cthardware.h | 3 +-
71 files changed, 1683 insertions(+), 2700 deletions(-)




2022-05-28 20:18:54

by Naresh Kamboju

[permalink] [raw]
Subject: Re: [PATCH 5.15 000/145] 5.15.44-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.15.44 release.
> There are 145 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:32 +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.15.44-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.15.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.15.44-rc1
* git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc
* git branch: linux-5.15.y
* git commit: 510d04da560ccd2e08230967864dfdd47b9b74a8
* git describe: v5.15.43-146-g510d04da560c
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.15.y/build/v5.15.43-146-g510d04da560c/

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

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

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

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

## Test result summary
total: 100757, pass: 85945, fail: 475, skip: 13420, xfail: 917

## Build Summary
* arc: 10 total, 10 passed, 0 failed
* arm: 296 total, 293 passed, 3 failed
* arm64: 47 total, 47 passed, 0 failed
* i386: 44 total, 40 passed, 4 failed
* mips: 41 total, 38 passed, 3 failed
* parisc: 14 total, 14 passed, 0 failed
* powerpc: 59 total, 56 passed, 3 failed
* riscv: 27 total, 27 passed, 0 failed
* s390: 26 total, 23 passed, 3 failed
* sh: 26 total, 24 passed, 2 failed
* sparc: 14 total, 14 passed, 0 failed
* x86_64: 47 total, 46 passed, 1 failed

## Test suites summary
* fwts
* igt-gpu-tools
* kselftest-android
* kselftest-arm64
* 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-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-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:19:35

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 099/145] random: allow partial reads if later user copies fail

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

commit 5209aed5137880fa229746cb521f715e55596460 upstream.

Rather than failing entirely if a copy_to_user() fails at some point,
instead we should return a partial read for the amount that succeeded
prior, unless none succeeded at all, in which case we return -EFAULT as
before.

This makes it consistent with other reader interfaces. For example, the
following snippet for /dev/zero outputs "4" followed by "1":

int fd;
void *x = mmap(NULL, 4096, PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
assert(x != MAP_FAILED);
fd = open("/dev/zero", O_RDONLY);
assert(fd >= 0);
printf("%zd\n", read(fd, x, 4));
printf("%zd\n", read(fd, x + 4095, 4));
close(fd);

This brings that same standard behavior to the various RNG reader
interfaces.

While we're at it, we can streamline the loop logic a little bit.

Suggested-by: Linus Torvalds <[email protected]>
Cc: Jann Horn <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -525,8 +525,7 @@ EXPORT_SYMBOL(get_random_bytes);

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

@@ -545,37 +544,40 @@ static ssize_t get_random_bytes_user(voi
* the user directly.
*/
if (nbytes <= CHACHA_KEY_SIZE) {
- ret = copy_to_user(buf, &chacha_state[4], nbytes) ? -EFAULT : nbytes;
+ ret = nbytes - copy_to_user(buf, &chacha_state[4], nbytes);
goto out_zero_chacha;
}

- do {
+ for (;;) {
chacha20_block(chacha_state, output);
if (unlikely(chacha_state[12] == 0))
++chacha_state[13];

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

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

BUILD_BUG_ON(PAGE_SIZE % CHACHA_BLOCK_SIZE != 0);
- if (!(ret % PAGE_SIZE) && nbytes) {
+ if (ret % PAGE_SIZE == 0) {
if (signal_pending(current))
break;
cond_resched();
}
- } while (nbytes);
+ }

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

/*



2022-05-28 20:24:33

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 040/145] random: use linear min-entropy accumulation crediting

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

commit c570449094844527577c5c914140222cb1893e3f upstream.

30e37ec516ae ("random: account for entropy loss due to overwrites")
assumed that adding new entropy to the LFSR pool probabilistically
cancelled out old entropy there, so entropy was credited asymptotically,
approximating Shannon entropy of independent sources (rather than a
stronger min-entropy notion) using 1/8th fractional bits and replacing
a constant 2-2/√???? term (~0.786938) with 3/4 (0.75) to slightly
underestimate it. This wasn't superb, but it was perhaps better than
nothing, so that's what was done. Which entropy specifically was being
cancelled out and how much precisely each time is hard to tell, though
as I showed with the attack code in my previous commit, a motivated
adversary with sufficient information can actually cancel out
everything.

Since we're no longer using an LFSR for entropy accumulation, this
probabilistic cancellation is no longer relevant. Rather, we're now
using a computational hash function as the accumulator and we've
switched to working in the random oracle model, from which we can now
revisit the question of min-entropy accumulation, which is done in
detail in <https://eprint.iacr.org/2019/198>.

Consider a long input bit string that is built by concatenating various
smaller independent input bit strings. Each one of these inputs has a
designated min-entropy, which is what we're passing to
credit_entropy_bits(h). When we pass the concatenation of these to a
random oracle, it means that an adversary trying to receive back the
same reply as us would need to become certain about each part of the
concatenated bit string we passed in, which means becoming certain about
all of those h values. That means we can estimate the accumulation by
simply adding up the h values in calls to credit_entropy_bits(h);
there's no probabilistic cancellation at play like there was said to be
for the LFSR. Incidentally, this is also what other entropy accumulators
based on computational hash functions do as well.

So this commit replaces credit_entropy_bits(h) with essentially `total =
min(POOL_BITS, total + h)`, done with a cmpxchg loop as before.

What if we're wrong and the above is nonsense? It's not, but let's
assume we don't want the actual _behavior_ of the code to change much.
Currently that behavior is not extracting from the input pool until it
has 128 bits of entropy in it. With the old algorithm, we'd hit that
magic 128 number after roughly 256 calls to credit_entropy_bits(1). So,
we can retain more or less the old behavior by waiting to extract from
the input pool until it hits 256 bits of entropy using the new code. For
people concerned about this change, it means that there's not that much
practical behavioral change. And for folks actually trying to model
the behavior rigorously, it means that we have an even higher margin
against attacks.

Cc: Theodore Ts'o <[email protected]>
Cc: Dominik Brodowski <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Reviewed-by: Eric Biggers <[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 | 114 ++++++++------------------------------------------
1 file changed, 20 insertions(+), 94 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -286,17 +286,9 @@

/* #define ADD_INTERRUPT_BENCH */

-enum poolinfo {
+enum {
POOL_BITS = BLAKE2S_HASH_SIZE * 8,
- POOL_BITSHIFT = ilog2(POOL_BITS),
- POOL_MIN_BITS = POOL_BITS / 2,
-
- /* To allow fractional bits to be tracked, the entropy_count field is
- * denominated in units of 1/8th bits. */
- POOL_ENTROPY_SHIFT = 3,
-#define POOL_ENTROPY_BITS() (input_pool.entropy_count >> POOL_ENTROPY_SHIFT)
- POOL_FRACBITS = POOL_BITS << POOL_ENTROPY_SHIFT,
- POOL_MIN_FRACBITS = POOL_MIN_BITS << POOL_ENTROPY_SHIFT
+ POOL_MIN_BITS = POOL_BITS /* No point in settling for less. */
};

/*
@@ -309,7 +301,7 @@ static struct fasync_struct *fasync;
* should wake up processes which are selecting or polling on write
* access to /dev/random.
*/
-static int random_write_wakeup_bits = POOL_BITS * 3 / 4;
+static int random_write_wakeup_bits = POOL_MIN_BITS;

static DEFINE_SPINLOCK(random_ready_list_lock);
static LIST_HEAD(random_ready_list);
@@ -469,66 +461,18 @@ static void process_random_ready_list(vo
static void credit_entropy_bits(int nbits)
{
int entropy_count, orig;
- int nfrac = nbits << POOL_ENTROPY_SHIFT;
-
- /* Ensure that the multiplication can avoid being 64 bits wide. */
- BUILD_BUG_ON(2 * (POOL_ENTROPY_SHIFT + POOL_BITSHIFT) > 31);

if (!nbits)
return;

-retry:
- entropy_count = orig = READ_ONCE(input_pool.entropy_count);
- if (nfrac < 0) {
- /* Debit */
- entropy_count += nfrac;
- } else {
- /*
- * Credit: we have to account for the possibility of
- * overwriting already present entropy. Even in the
- * ideal case of pure Shannon entropy, new contributions
- * approach the full value asymptotically:
- *
- * entropy <- entropy + (pool_size - entropy) *
- * (1 - exp(-add_entropy/pool_size))
- *
- * For add_entropy <= pool_size/2 then
- * (1 - exp(-add_entropy/pool_size)) >=
- * (add_entropy/pool_size)*0.7869...
- * so we can approximate the exponential with
- * 3/4*add_entropy/pool_size and still be on the
- * safe side by adding at most pool_size/2 at a time.
- *
- * The use of pool_size-2 in the while statement is to
- * prevent rounding artifacts from making the loop
- * arbitrarily long; this limits the loop to log2(pool_size)*2
- * turns no matter how large nbits is.
- */
- int pnfrac = nfrac;
- const int s = POOL_BITSHIFT + POOL_ENTROPY_SHIFT + 2;
- /* The +2 corresponds to the /4 in the denominator */
-
- do {
- unsigned int anfrac = min(pnfrac, POOL_FRACBITS / 2);
- unsigned int add =
- ((POOL_FRACBITS - entropy_count) * anfrac * 3) >> s;
-
- entropy_count += add;
- pnfrac -= anfrac;
- } while (unlikely(entropy_count < POOL_FRACBITS - 2 && pnfrac));
- }
-
- if (WARN_ON(entropy_count < 0)) {
- pr_warn("negative entropy/overflow: count %d\n", entropy_count);
- entropy_count = 0;
- } else if (entropy_count > POOL_FRACBITS)
- entropy_count = POOL_FRACBITS;
- if (cmpxchg(&input_pool.entropy_count, orig, entropy_count) != orig)
- goto retry;
+ do {
+ orig = READ_ONCE(input_pool.entropy_count);
+ entropy_count = min(POOL_BITS, orig + nbits);
+ } while (cmpxchg(&input_pool.entropy_count, orig, entropy_count) != orig);

- trace_credit_entropy_bits(nbits, entropy_count >> POOL_ENTROPY_SHIFT, _RET_IP_);
+ trace_credit_entropy_bits(nbits, entropy_count, _RET_IP_);

- if (crng_init < 2 && entropy_count >= POOL_MIN_FRACBITS)
+ if (crng_init < 2 && entropy_count >= POOL_MIN_BITS)
crng_reseed(&primary_crng, true);
}

@@ -791,7 +735,7 @@ static void crng_reseed(struct crng_stat
int entropy_count;
do {
entropy_count = READ_ONCE(input_pool.entropy_count);
- if (entropy_count < POOL_MIN_FRACBITS)
+ if (entropy_count < POOL_MIN_BITS)
return;
} while (cmpxchg(&input_pool.entropy_count, entropy_count, 0) != entropy_count);
extract_entropy(buf.key, sizeof(buf.key));
@@ -1014,7 +958,7 @@ void add_input_randomness(unsigned int t
last_value = value;
add_timer_randomness(&input_timer_state,
(type << 4) ^ code ^ (code >> 4) ^ value);
- trace_add_input_randomness(POOL_ENTROPY_BITS());
+ trace_add_input_randomness(input_pool.entropy_count);
}
EXPORT_SYMBOL_GPL(add_input_randomness);

@@ -1112,7 +1056,7 @@ void add_disk_randomness(struct gendisk
return;
/* first major is 1, so we get >= 0x200 here */
add_timer_randomness(disk->random, 0x100 + disk_devt(disk));
- trace_add_disk_randomness(disk_devt(disk), POOL_ENTROPY_BITS());
+ trace_add_disk_randomness(disk_devt(disk), input_pool.entropy_count);
}
EXPORT_SYMBOL_GPL(add_disk_randomness);
#endif
@@ -1137,7 +1081,7 @@ static void extract_entropy(void *buf, s
} block;
size_t i;

- trace_extract_entropy(nbytes, POOL_ENTROPY_BITS());
+ trace_extract_entropy(nbytes, input_pool.entropy_count);

for (i = 0; i < ARRAY_SIZE(block.rdrand); ++i) {
if (!arch_get_random_long(&block.rdrand[i]))
@@ -1486,9 +1430,9 @@ static ssize_t urandom_read_nowarn(struc
{
int ret;

- nbytes = min_t(size_t, nbytes, INT_MAX >> (POOL_ENTROPY_SHIFT + 3));
+ nbytes = min_t(size_t, nbytes, INT_MAX >> 6);
ret = extract_crng_user(buf, nbytes);
- trace_urandom_read(8 * nbytes, 0, POOL_ENTROPY_BITS());
+ trace_urandom_read(8 * nbytes, 0, input_pool.entropy_count);
return ret;
}

@@ -1527,7 +1471,7 @@ static __poll_t random_poll(struct file
mask = 0;
if (crng_ready())
mask |= EPOLLIN | EPOLLRDNORM;
- if (POOL_ENTROPY_BITS() < random_write_wakeup_bits)
+ if (input_pool.entropy_count < random_write_wakeup_bits)
mask |= EPOLLOUT | EPOLLWRNORM;
return mask;
}
@@ -1582,8 +1526,7 @@ static long random_ioctl(struct file *f,
switch (cmd) {
case RNDGETENTCNT:
/* inherently racy, no point locking */
- ent_count = POOL_ENTROPY_BITS();
- if (put_user(ent_count, p))
+ if (put_user(input_pool.entropy_count, p))
return -EFAULT;
return 0;
case RNDADDTOENTCNT:
@@ -1734,23 +1677,6 @@ static int proc_do_uuid(struct ctl_table
return proc_dostring(&fake_table, write, buffer, lenp, ppos);
}

-/*
- * Return entropy available scaled to integral bits
- */
-static int proc_do_entropy(struct ctl_table *table, int write, void *buffer,
- size_t *lenp, loff_t *ppos)
-{
- struct ctl_table fake_table;
- int entropy_count;
-
- entropy_count = *(int *)table->data >> POOL_ENTROPY_SHIFT;
-
- fake_table.data = &entropy_count;
- fake_table.maxlen = sizeof(entropy_count);
-
- return proc_dointvec(&fake_table, write, buffer, lenp, ppos);
-}
-
static int sysctl_poolsize = POOL_BITS;
extern struct ctl_table random_table[];
struct ctl_table random_table[] = {
@@ -1763,10 +1689,10 @@ struct ctl_table random_table[] = {
},
{
.procname = "entropy_avail",
+ .data = &input_pool.entropy_count,
.maxlen = sizeof(int),
.mode = 0444,
- .proc_handler = proc_do_entropy,
- .data = &input_pool.entropy_count,
+ .proc_handler = proc_dointvec,
},
{
.procname = "write_wakeup_threshold",
@@ -1962,7 +1888,7 @@ void add_hwgenerator_randomness(const ch
*/
wait_event_interruptible_timeout(random_write_wait,
!system_wq || kthread_should_stop() ||
- POOL_ENTROPY_BITS() <= random_write_wakeup_bits,
+ input_pool.entropy_count <= random_write_wakeup_bits,
CRNG_RESEED_INTERVAL);
mix_pool_bytes(buffer, count);
credit_entropy_bits(entropy);



2022-05-28 20:25:48

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 119/145] random: insist on random_get_entropy() existing in order to simplify

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

commit 4b758eda851eb9336ca86a0041a4d3da55f66511 upstream.

All platforms are now guaranteed to provide some value for
random_get_entropy(). In case some bug leads to this not being so, we
print a warning, because that indicates that something is really very
wrong (and likely other things are impacted too). This should never be
hit, but it's a good and cheap way of finding out if something ever is
problematic.

Since we now have viable fallback code for random_get_entropy() on all
platforms, which is, in the worst case, not worse than jiffies, we can
count on getting the best possible value out of it. That means there's
no longer a use for using jiffies as entropy input. It also means we no
longer have a reason for doing the round-robin register flow in the IRQ
handler, which was always of fairly dubious value.

Instead we can greatly simplify the IRQ handler inputs and also unify
the construction between 64-bits and 32-bits. We now collect the cycle
counter and the return address, since those are the two things that
matter. Because the return address and the irq number are likely
related, to the extent we mix in the irq number, we can just xor it into
the top unchanging bytes of the return address, rather than the bottom
changing bytes of the cycle counter as before. Then, we can do a fixed 2
rounds of SipHash/HSipHash. Finally, we use the same construction of
hashing only half of the [H]SipHash state on 32-bit and 64-bit. We're
not actually discarding any entropy, since that entropy is carried
through until the next time. And more importantly, it lets us do the
same sponge-like construction everywhere.

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

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1022,15 +1022,14 @@ int __init rand_initialize(void)
*/
void add_device_randomness(const void *buf, size_t size)
{
- unsigned long cycles = random_get_entropy();
- unsigned long flags, now = jiffies;
+ unsigned long entropy = random_get_entropy();
+ unsigned long flags;

if (crng_init == 0 && size)
crng_pre_init_inject(buf, size, false);

spin_lock_irqsave(&input_pool.lock, flags);
- _mix_pool_bytes(&cycles, sizeof(cycles));
- _mix_pool_bytes(&now, sizeof(now));
+ _mix_pool_bytes(&entropy, sizeof(entropy));
_mix_pool_bytes(buf, size);
spin_unlock_irqrestore(&input_pool.lock, flags);
}
@@ -1053,12 +1052,11 @@ struct timer_rand_state {
*/
static void add_timer_randomness(struct timer_rand_state *state, unsigned int num)
{
- unsigned long cycles = random_get_entropy(), now = jiffies, flags;
+ unsigned long entropy = random_get_entropy(), now = jiffies, flags;
long delta, delta2, delta3;

spin_lock_irqsave(&input_pool.lock, flags);
- _mix_pool_bytes(&cycles, sizeof(cycles));
- _mix_pool_bytes(&now, sizeof(now));
+ _mix_pool_bytes(&entropy, sizeof(entropy));
_mix_pool_bytes(&num, sizeof(num));
spin_unlock_irqrestore(&input_pool.lock, flags);

@@ -1186,7 +1184,6 @@ struct fast_pool {
unsigned long pool[4];
unsigned long last;
unsigned int count;
- u16 reg_idx;
};

static DEFINE_PER_CPU(struct fast_pool, irq_randomness) = {
@@ -1204,13 +1201,13 @@ static DEFINE_PER_CPU(struct fast_pool,
* This is [Half]SipHash-1-x, starting from an empty key. Because
* the key is fixed, it assumes that its inputs are non-malicious,
* and therefore this has no security on its own. s represents the
- * 128 or 256-bit SipHash state, while v represents a 128-bit input.
+ * four-word SipHash state, while v represents a two-word input.
*/
-static void fast_mix(unsigned long s[4], const unsigned long *v)
+static void fast_mix(unsigned long s[4], const unsigned long v[2])
{
size_t i;

- for (i = 0; i < 16 / sizeof(long); ++i) {
+ for (i = 0; i < 2; ++i) {
s[3] ^= v[i];
#ifdef CONFIG_64BIT
s[0] += s[1]; s[1] = rol64(s[1], 13); s[1] ^= s[0]; s[0] = rol64(s[0], 32);
@@ -1250,33 +1247,17 @@ int random_online_cpu(unsigned int cpu)
}
#endif

-static unsigned long get_reg(struct fast_pool *f, struct pt_regs *regs)
-{
- unsigned long *ptr = (unsigned long *)regs;
- unsigned int idx;
-
- if (regs == NULL)
- return 0;
- idx = READ_ONCE(f->reg_idx);
- if (idx >= sizeof(struct pt_regs) / sizeof(unsigned long))
- idx = 0;
- ptr += idx++;
- WRITE_ONCE(f->reg_idx, idx);
- return *ptr;
-}
-
static void mix_interrupt_randomness(struct work_struct *work)
{
struct fast_pool *fast_pool = container_of(work, struct fast_pool, mix);
/*
- * The size of the copied stack pool is explicitly 16 bytes so that we
- * tax mix_pool_byte()'s compression function the same amount on all
- * platforms. This means on 64-bit we copy half the pool into this,
- * while on 32-bit we copy all of it. The entropy is supposed to be
- * sufficiently dispersed between bits that in the sponge-like
- * half case, on average we don't wind up "losing" some.
+ * The size of the copied stack pool is explicitly 2 longs so that we
+ * only ever ingest half of the siphash output each time, retaining
+ * the other half as the next "key" that carries over. The entropy is
+ * supposed to be sufficiently dispersed between bits so on average
+ * we don't wind up "losing" some.
*/
- u8 pool[16];
+ unsigned long pool[2];

/* Check to see if we're running on the wrong CPU due to hotplug. */
local_irq_disable();
@@ -1308,36 +1289,21 @@ static void mix_interrupt_randomness(str
void add_interrupt_randomness(int irq)
{
enum { MIX_INFLIGHT = 1U << 31 };
- unsigned long cycles = random_get_entropy(), now = jiffies;
+ unsigned long entropy = random_get_entropy();
struct fast_pool *fast_pool = this_cpu_ptr(&irq_randomness);
struct pt_regs *regs = get_irq_regs();
unsigned int new_count;
- union {
- u32 u32[4];
- u64 u64[2];
- unsigned long longs[16 / sizeof(long)];
- } irq_data;
-
- if (cycles == 0)
- cycles = get_reg(fast_pool, regs);
-
- if (sizeof(unsigned long) == 8) {
- irq_data.u64[0] = cycles ^ rol64(now, 32) ^ irq;
- irq_data.u64[1] = regs ? instruction_pointer(regs) : _RET_IP_;
- } else {
- irq_data.u32[0] = cycles ^ irq;
- irq_data.u32[1] = now;
- irq_data.u32[2] = regs ? instruction_pointer(regs) : _RET_IP_;
- irq_data.u32[3] = get_reg(fast_pool, regs);
- }

- fast_mix(fast_pool->pool, irq_data.longs);
+ fast_mix(fast_pool->pool, (unsigned long[2]){
+ entropy,
+ (regs ? instruction_pointer(regs) : _RET_IP_) ^ swab(irq)
+ });
new_count = ++fast_pool->count;

if (new_count & MIX_INFLIGHT)
return;

- if (new_count < 64 && (!time_after(now, fast_pool->last + HZ) ||
+ if (new_count < 64 && (!time_is_before_jiffies(fast_pool->last + HZ) ||
unlikely(crng_init == 0)))
return;

@@ -1373,28 +1339,28 @@ static void entropy_timer(struct timer_l
static void try_to_generate_entropy(void)
{
struct {
- unsigned long cycles;
+ unsigned long entropy;
struct timer_list timer;
} stack;

- stack.cycles = random_get_entropy();
+ stack.entropy = random_get_entropy();

/* Slow counter - or none. Don't even bother */
- if (stack.cycles == random_get_entropy())
+ if (stack.entropy == random_get_entropy())
return;

timer_setup_on_stack(&stack.timer, entropy_timer, 0);
while (!crng_ready() && !signal_pending(current)) {
if (!timer_pending(&stack.timer))
mod_timer(&stack.timer, jiffies + 1);
- mix_pool_bytes(&stack.cycles, sizeof(stack.cycles));
+ mix_pool_bytes(&stack.entropy, sizeof(stack.entropy));
schedule();
- stack.cycles = random_get_entropy();
+ stack.entropy = random_get_entropy();
}

del_timer_sync(&stack.timer);
destroy_timer_on_stack(&stack.timer);
- mix_pool_bytes(&stack.cycles, sizeof(stack.cycles));
+ mix_pool_bytes(&stack.entropy, sizeof(stack.entropy));
}





2022-05-28 20:26:34

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 145/145] ALSA: ctxfi: Add SB046x PCI ID

From: Edward Matijevic <[email protected]>

commit 1b073ebb174d0c7109b438e0a5eb4495137803ec upstream.

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

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

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

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

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

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

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

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



2022-05-28 20:27:17

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 080/145] 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:27:21

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 108/145] powerpc: define get_cycles macro for arch-override

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

commit 408835832158df0357e18e96da7f2d1ed6b80e7f upstream.

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

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

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

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



2022-05-28 20:27:27

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 042/145] 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:27:54

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 056/145] random: zero buffer after reading entropy from userspace

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

commit 7b5164fb1279bf0251371848e40bae646b59b3a8 upstream.

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

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

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

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

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

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



2022-05-28 20:29:10

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 016/145] random: mix bootloader randomness into pool

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

commit 57826feeedb63b091f807ba8325d736775d39afd upstream.

If we're trusting bootloader randomness, crng_fast_load() is called by
add_hwgenerator_randomness(), which sets us to crng_init==1. However,
usually it is only called once for an initial 64-byte push, so bootloader
entropy will not mix any bytes into the input pool. So it's conceivable
that crng_init==1 when crng_initialize_primary() is called later, but
then the input pool is empty. When that happens, the crng state key will
be overwritten with extracted output from the empty input pool. That's
bad.

In contrast, if we're not trusting bootloader randomness, we call
crng_slow_load() *and* we call mix_pool_bytes(), so that later
crng_initialize_primary() isn't drawing on nothing.

In order to prevent crng_initialize_primary() from extracting an empty
pool, have the trusted bootloader case mirror that of the untrusted
bootloader case, mixing the input into the pool.

[[email protected]: rewrite commit message]
Signed-off-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 | 1 +
1 file changed, 1 insertion(+)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -2301,6 +2301,7 @@ void add_hwgenerator_randomness(const ch

if (unlikely(crng_init == 0)) {
size_t ret = crng_fast_load(buffer, count);
+ mix_pool_bytes(poolp, buffer, ret);
count -= ret;
buffer += ret;
if (!count || crng_init == 0)



2022-05-28 20:30:56

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 010/145] lib/crypto: blake2s: avoid indirect calls to compression function for Clang CFI

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

commit d2a02e3c8bb6b347818518edff5a4b40ff52d6d8 upstream.

blake2s_compress_generic is weakly aliased by blake2s_compress. The
current harness for function selection uses a function pointer, which is
ordinarily inlined and resolved at compile time. But when Clang's CFI is
enabled, CFI still triggers when making an indirect call via a weak
symbol. This seems like a bug in Clang's CFI, as though it's bucketing
weak symbols and strong symbols differently. It also only seems to
trigger when "full LTO" mode is used, rather than "thin LTO".

[ 0.000000][ T0] Kernel panic - not syncing: CFI failure (target: blake2s_compress_generic+0x0/0x1444)
[ 0.000000][ T0] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.16.0-mainline-06981-g076c855b846e #1
[ 0.000000][ T0] Hardware name: MT6873 (DT)
[ 0.000000][ T0] Call trace:
[ 0.000000][ T0] dump_backtrace+0xfc/0x1dc
[ 0.000000][ T0] dump_stack_lvl+0xa8/0x11c
[ 0.000000][ T0] panic+0x194/0x464
[ 0.000000][ T0] __cfi_check_fail+0x54/0x58
[ 0.000000][ T0] __cfi_slowpath_diag+0x354/0x4b0
[ 0.000000][ T0] blake2s_update+0x14c/0x178
[ 0.000000][ T0] _extract_entropy+0xf4/0x29c
[ 0.000000][ T0] crng_initialize_primary+0x24/0x94
[ 0.000000][ T0] rand_initialize+0x2c/0x6c
[ 0.000000][ T0] start_kernel+0x2f8/0x65c
[ 0.000000][ T0] __primary_switched+0xc4/0x7be4
[ 0.000000][ T0] Rebooting in 5 seconds..

Nonetheless, the function pointer method isn't so terrific anyway, so
this patch replaces it with a simple boolean, which also gets inlined
away. This successfully works around the Clang bug.

In general, I'm not too keen on all of the indirection involved here; it
clearly does more harm than good. Hopefully the whole thing can get
cleaned up down the road when lib/crypto is overhauled more
comprehensively. But for now, we go with a simple bandaid.

Fixes: 6048fdcc5f26 ("lib/crypto: blake2s: include as built-in")
Link: https://github.com/ClangBuiltLinux/linux/issues/1567
Reported-by: Miles Chen <[email protected]>
Tested-by: Miles Chen <[email protected]>
Tested-by: Nathan Chancellor <[email protected]>
Tested-by: John Stultz <[email protected]>
Acked-by: Nick Desaulniers <[email protected]>
Reviewed-by: Eric Biggers <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/arm/crypto/blake2s-shash.c | 4 +--
arch/x86/crypto/blake2s-shash.c | 4 +--
crypto/blake2s_generic.c | 4 +--
include/crypto/internal/blake2s.h | 40 +++++++++++++++++++++++---------------
lib/crypto/blake2s.c | 4 +--
5 files changed, 33 insertions(+), 23 deletions(-)

--- a/arch/arm/crypto/blake2s-shash.c
+++ b/arch/arm/crypto/blake2s-shash.c
@@ -13,12 +13,12 @@
static int crypto_blake2s_update_arm(struct shash_desc *desc,
const u8 *in, unsigned int inlen)
{
- return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
+ return crypto_blake2s_update(desc, in, inlen, false);
}

static int crypto_blake2s_final_arm(struct shash_desc *desc, u8 *out)
{
- return crypto_blake2s_final(desc, out, blake2s_compress);
+ return crypto_blake2s_final(desc, out, false);
}

#define BLAKE2S_ALG(name, driver_name, digest_size) \
--- a/arch/x86/crypto/blake2s-shash.c
+++ b/arch/x86/crypto/blake2s-shash.c
@@ -18,12 +18,12 @@
static int crypto_blake2s_update_x86(struct shash_desc *desc,
const u8 *in, unsigned int inlen)
{
- return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
+ return crypto_blake2s_update(desc, in, inlen, false);
}

static int crypto_blake2s_final_x86(struct shash_desc *desc, u8 *out)
{
- return crypto_blake2s_final(desc, out, blake2s_compress);
+ return crypto_blake2s_final(desc, out, false);
}

#define BLAKE2S_ALG(name, driver_name, digest_size) \
--- a/crypto/blake2s_generic.c
+++ b/crypto/blake2s_generic.c
@@ -15,12 +15,12 @@
static int crypto_blake2s_update_generic(struct shash_desc *desc,
const u8 *in, unsigned int inlen)
{
- return crypto_blake2s_update(desc, in, inlen, blake2s_compress_generic);
+ return crypto_blake2s_update(desc, in, inlen, true);
}

static int crypto_blake2s_final_generic(struct shash_desc *desc, u8 *out)
{
- return crypto_blake2s_final(desc, out, blake2s_compress_generic);
+ return crypto_blake2s_final(desc, out, true);
}

#define BLAKE2S_ALG(name, driver_name, digest_size) \
--- a/include/crypto/internal/blake2s.h
+++ b/include/crypto/internal/blake2s.h
@@ -24,14 +24,11 @@ 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);
-
/* Helper functions for BLAKE2s shared by the library and shash APIs */

-static inline void __blake2s_update(struct blake2s_state *state,
- const u8 *in, size_t inlen,
- blake2s_compress_t compress)
+static __always_inline void
+__blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen,
+ bool force_generic)
{
const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;

@@ -39,7 +36,12 @@ static inline void __blake2s_update(stru
return;
if (inlen > fill) {
memcpy(state->buf + state->buflen, in, fill);
- (*compress)(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
+ if (force_generic)
+ blake2s_compress_generic(state, state->buf, 1,
+ BLAKE2S_BLOCK_SIZE);
+ else
+ blake2s_compress(state, state->buf, 1,
+ BLAKE2S_BLOCK_SIZE);
state->buflen = 0;
in += fill;
inlen -= fill;
@@ -47,7 +49,12 @@ static inline void __blake2s_update(stru
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);
+ if (force_generic)
+ blake2s_compress_generic(state, in, nblocks - 1,
+ BLAKE2S_BLOCK_SIZE);
+ else
+ blake2s_compress(state, in, nblocks - 1,
+ BLAKE2S_BLOCK_SIZE);
in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
}
@@ -55,13 +62,16 @@ static inline void __blake2s_update(stru
state->buflen += inlen;
}

-static inline void __blake2s_final(struct blake2s_state *state, u8 *out,
- blake2s_compress_t compress)
+static __always_inline void
+__blake2s_final(struct blake2s_state *state, u8 *out, bool force_generic)
{
blake2s_set_lastblock(state);
memset(state->buf + state->buflen, 0,
BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
- (*compress)(state, state->buf, 1, state->buflen);
+ if (force_generic)
+ blake2s_compress_generic(state, state->buf, 1, state->buflen);
+ else
+ blake2s_compress(state, state->buf, 1, state->buflen);
cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
memcpy(out, state->h, state->outlen);
}
@@ -99,20 +109,20 @@ static inline int crypto_blake2s_init(st

static inline int crypto_blake2s_update(struct shash_desc *desc,
const u8 *in, unsigned int inlen,
- blake2s_compress_t compress)
+ bool force_generic)
{
struct blake2s_state *state = shash_desc_ctx(desc);

- __blake2s_update(state, in, inlen, compress);
+ __blake2s_update(state, in, inlen, force_generic);
return 0;
}

static inline int crypto_blake2s_final(struct shash_desc *desc, u8 *out,
- blake2s_compress_t compress)
+ bool force_generic)
{
struct blake2s_state *state = shash_desc_ctx(desc);

- __blake2s_final(state, out, compress);
+ __blake2s_final(state, out, force_generic);
return 0;
}

--- a/lib/crypto/blake2s.c
+++ b/lib/crypto/blake2s.c
@@ -18,14 +18,14 @@

void blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen)
{
- __blake2s_update(state, in, inlen, blake2s_compress);
+ __blake2s_update(state, in, inlen, false);
}
EXPORT_SYMBOL(blake2s_update);

void blake2s_final(struct blake2s_state *state, u8 *out)
{
WARN_ON(IS_ENABLED(DEBUG) && !out);
- __blake2s_final(state, out, blake2s_compress);
+ __blake2s_final(state, out, false);
memzero_explicit(state, sizeof(*state));
}
EXPORT_SYMBOL(blake2s_final);



2022-05-28 20:31:20

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 103/145] init: call time_init() before rand_initialize()

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

commit fe222a6ca2d53c38433cba5d3be62a39099e708e upstream.

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

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

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

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

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



2022-05-28 20:32:49

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 073/145] random: defer fast pool mixing to worker

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

commit 58340f8e952b613e0ead0bed58b97b05bf4743c5 upstream.

On PREEMPT_RT, it's problematic to take spinlocks from hard irq
handlers. We can fix this by deferring to a workqueue the dumping of
the fast pool into the input pool.

We accomplish this with some careful rules on fast_pool->count:

- When it's incremented to >= 64, we schedule the work.
- If the top bit is set, we never schedule the work, even if >= 64.
- The worker is responsible for setting it back to 0 when it's done.

There are two small issues around using workqueues for this purpose that
we work around.

The first issue is that mix_interrupt_randomness() might be migrated to
another CPU during CPU hotplug. This issue is rectified by checking that
it hasn't been migrated (after disabling irqs). If it has been migrated,
then we set the count to zero, so that when the CPU comes online again,
it can requeue the work. As part of this, we switch to using an
atomic_t, so that the increment in the irq handler doesn't wipe out the
zeroing if the CPU comes back online while this worker is running.

The second issue is that, though relatively minor in effect, we probably
want to make sure we get a consistent view of the pool onto the stack,
in case it's interrupted by an irq while reading. To do this, we don't
reenable irqs until after the copy. There are only 18 instructions
between the cli and sti, so this is a pretty tiny window.

Cc: Thomas Gleixner <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Theodore Ts'o <[email protected]>
Cc: Jonathan Neuschäfer <[email protected]>
Acked-by: Sebastian Andrzej Siewior <[email protected]>
Reviewed-by: Sultan Alsawaf <[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 | 63 ++++++++++++++++++++++++++++++++++++++------------
1 file changed, 49 insertions(+), 14 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1178,9 +1178,10 @@ struct fast_pool {
u32 pool32[4];
u64 pool64[2];
};
+ struct work_struct mix;
unsigned long last;
+ atomic_t count;
u16 reg_idx;
- u8 count;
};

/*
@@ -1230,12 +1231,49 @@ static u32 get_reg(struct fast_pool *f,
return *ptr;
}

+static void mix_interrupt_randomness(struct work_struct *work)
+{
+ struct fast_pool *fast_pool = container_of(work, struct fast_pool, mix);
+ u32 pool[4];
+
+ /* Check to see if we're running on the wrong CPU due to hotplug. */
+ 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;
+ }
+
+ /*
+ * Copy the pool to the stack so that the mixer always has a
+ * consistent view, before we reenable irqs again.
+ */
+ memcpy(pool, fast_pool->pool32, sizeof(pool));
+ atomic_set(&fast_pool->count, 0);
+ fast_pool->last = jiffies;
+ local_irq_enable();
+
+ mix_pool_bytes(pool, sizeof(pool));
+ credit_entropy_bits(1);
+ memzero_explicit(pool, sizeof(pool));
+}
+
void add_interrupt_randomness(int irq)
{
+ enum { MIX_INFLIGHT = 1U << 31 };
struct fast_pool *fast_pool = this_cpu_ptr(&irq_randomness);
struct pt_regs *regs = get_irq_regs();
unsigned long now = jiffies;
cycles_t cycles = random_get_entropy();
+ unsigned int new_count;

if (cycles == 0)
cycles = get_reg(fast_pool, regs);
@@ -1255,12 +1293,13 @@ void add_interrupt_randomness(int irq)
}

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

if (unlikely(crng_init == 0)) {
- if (fast_pool->count >= 64 &&
+ if (new_count >= 64 &&
crng_fast_load(fast_pool->pool32, sizeof(fast_pool->pool32)) > 0) {
- fast_pool->count = 0;
+ atomic_set(&fast_pool->count, 0);
fast_pool->last = now;
if (spin_trylock(&input_pool.lock)) {
_mix_pool_bytes(&fast_pool->pool32, sizeof(fast_pool->pool32));
@@ -1270,20 +1309,16 @@ void add_interrupt_randomness(int irq)
return;
}

- if ((fast_pool->count < 64) && !time_after(now, fast_pool->last + HZ))
+ if (new_count & MIX_INFLIGHT)
return;

- if (!spin_trylock(&input_pool.lock))
+ if (new_count < 64 && !time_after(now, fast_pool->last + HZ))
return;

- fast_pool->last = now;
- _mix_pool_bytes(&fast_pool->pool32, sizeof(fast_pool->pool32));
- spin_unlock(&input_pool.lock);
-
- fast_pool->count = 0;
-
- /* Award one bit for the contents of the fast pool. */
- credit_entropy_bits(1);
+ if (unlikely(!fast_pool->mix.func))
+ INIT_WORK(&fast_pool->mix, mix_interrupt_randomness);
+ atomic_or(MIX_INFLIGHT, &fast_pool->count);
+ queue_work_on(raw_smp_processor_id(), system_highpri_wq, &fast_pool->mix);
}
EXPORT_SYMBOL_GPL(add_interrupt_randomness);




2022-05-28 20:33:31

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 025/145] random: remove incomplete last_data logic

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

commit a4bfa9b31802c14ff5847123c12b98d5e36b3985 upstream.

There were a few things added under the "if (fips_enabled)" banner,
which never really got completed, and the FIPS people anyway are
choosing a different direction. Rather than keep around this halfbaked
code, get rid of it so that we can focus on a single design of the RNG
rather than two designs.

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 | 39 ++++-----------------------------------
1 file changed, 4 insertions(+), 35 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -337,7 +337,6 @@
#include <linux/spinlock.h>
#include <linux/kthread.h>
#include <linux/percpu.h>
-#include <linux/fips.h>
#include <linux/ptrace.h>
#include <linux/workqueue.h>
#include <linux/irq.h>
@@ -517,14 +516,12 @@ struct entropy_store {
u16 add_ptr;
u16 input_rotate;
int entropy_count;
- unsigned int last_data_init:1;
- u8 last_data[EXTRACT_SIZE];
};

static ssize_t extract_entropy(struct entropy_store *r, void *buf,
size_t nbytes, int min, int rsvd);
static ssize_t _extract_entropy(struct entropy_store *r, void *buf,
- size_t nbytes, int fips);
+ size_t nbytes);

static void crng_reseed(struct crng_state *crng, struct entropy_store *r);
static u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy;
@@ -821,7 +818,7 @@ static void crng_initialize_secondary(st

static void __init crng_initialize_primary(struct crng_state *crng)
{
- _extract_entropy(&input_pool, &crng->state[4], sizeof(u32) * 12, 0);
+ _extract_entropy(&input_pool, &crng->state[4], sizeof(u32) * 12);
if (crng_init_try_arch_early(crng) && trust_cpu && crng_init < 2) {
invalidate_batched_entropy();
numa_crng_init();
@@ -1426,22 +1423,13 @@ static void extract_buf(struct entropy_s
}

static ssize_t _extract_entropy(struct entropy_store *r, void *buf,
- size_t nbytes, int fips)
+ size_t nbytes)
{
ssize_t ret = 0, i;
u8 tmp[EXTRACT_SIZE];
- unsigned long flags;

while (nbytes) {
extract_buf(r, tmp);
-
- if (fips) {
- spin_lock_irqsave(&r->lock, flags);
- if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
- panic("Hardware RNG duplicated output!\n");
- memcpy(r->last_data, tmp, EXTRACT_SIZE);
- spin_unlock_irqrestore(&r->lock, flags);
- }
i = min_t(int, nbytes, EXTRACT_SIZE);
memcpy(buf, tmp, i);
nbytes -= i;
@@ -1467,28 +1455,9 @@ static ssize_t _extract_entropy(struct e
static ssize_t extract_entropy(struct entropy_store *r, void *buf,
size_t nbytes, int min, int reserved)
{
- u8 tmp[EXTRACT_SIZE];
- unsigned long flags;
-
- /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */
- if (fips_enabled) {
- spin_lock_irqsave(&r->lock, flags);
- if (!r->last_data_init) {
- r->last_data_init = 1;
- spin_unlock_irqrestore(&r->lock, flags);
- trace_extract_entropy(r->name, EXTRACT_SIZE,
- ENTROPY_BITS(r), _RET_IP_);
- extract_buf(r, tmp);
- spin_lock_irqsave(&r->lock, flags);
- memcpy(r->last_data, tmp, EXTRACT_SIZE);
- }
- spin_unlock_irqrestore(&r->lock, flags);
- }
-
trace_extract_entropy(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_);
nbytes = account(r, nbytes, min, reserved);
-
- return _extract_entropy(r, buf, nbytes, fips_enabled);
+ return _extract_entropy(r, buf, nbytes);
}

#define warn_unseeded_randomness(previous) \



2022-05-28 20:34:08

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 091/145] random: skip fast_init if hwrng provides large chunk of entropy

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

commit af704c856e888fb044b058d731d61b46eeec499d upstream.

At boot time, EFI calls add_bootloader_randomness(), which in turn calls
add_hwgenerator_randomness(). Currently add_hwgenerator_randomness()
feeds the first 64 bytes of randomness to the "fast init"
non-crypto-grade phase. But if add_hwgenerator_randomness() gets called
with more than POOL_MIN_BITS of entropy, there's no point in passing it
off to the "fast init" stage, since that's enough entropy to bootstrap
the real RNG. The "fast init" stage is just there to provide _something_
in the case where we don't have enough entropy to properly bootstrap the
RNG. But if we do have enough entropy to bootstrap the RNG, the current
logic doesn't serve a purpose. So, in the case where we're passed
greater than or equal to POOL_MIN_BITS of entropy, this commit makes us
skip the "fast init" phase.

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 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1125,7 +1125,7 @@ void rand_initialize_disk(struct gendisk
void add_hwgenerator_randomness(const void *buffer, size_t count,
size_t entropy)
{
- if (unlikely(crng_init == 0)) {
+ if (unlikely(crng_init == 0 && entropy < POOL_MIN_BITS)) {
size_t ret = crng_pre_init_inject(buffer, count, true);
mix_pool_bytes(buffer, ret);
count -= ret;



2022-05-28 20:34:19

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 032/145] random: access input_pool_data directly rather than through pointer

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

commit 6c0eace6e1499712583b6ee62d95161e8b3449f5 upstream.

This gets rid of another abstraction we no longer need. It would be nice
if we could instead make pool an array rather than a pointer, but the
latent entropy plugin won't be able to do its magic in that case. So
instead we put all accesses to the input pool's actual data through the
input_pool_data array directly.

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 | 21 ++++++++-------------
1 file changed, 8 insertions(+), 13 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -496,17 +496,12 @@ MODULE_PARM_DESC(ratelimit_disable, "Dis
static u32 input_pool_data[POOL_WORDS] __latent_entropy;

static struct {
- /* read-only data: */
- u32 *pool;
-
- /* read-write data: */
spinlock_t lock;
u16 add_ptr;
u16 input_rotate;
int entropy_count;
} input_pool = {
.lock = __SPIN_LOCK_UNLOCKED(input_pool.lock),
- .pool = input_pool_data
};

static ssize_t extract_entropy(void *buf, size_t nbytes, int min);
@@ -544,15 +539,15 @@ static void _mix_pool_bytes(const void *
i = (i - 1) & POOL_WORDMASK;

/* XOR in the various taps */
- w ^= input_pool.pool[i];
- w ^= input_pool.pool[(i + POOL_TAP1) & POOL_WORDMASK];
- w ^= input_pool.pool[(i + POOL_TAP2) & POOL_WORDMASK];
- w ^= input_pool.pool[(i + POOL_TAP3) & POOL_WORDMASK];
- w ^= input_pool.pool[(i + POOL_TAP4) & POOL_WORDMASK];
- w ^= input_pool.pool[(i + POOL_TAP5) & POOL_WORDMASK];
+ w ^= input_pool_data[i];
+ w ^= input_pool_data[(i + POOL_TAP1) & POOL_WORDMASK];
+ w ^= input_pool_data[(i + POOL_TAP2) & POOL_WORDMASK];
+ w ^= input_pool_data[(i + POOL_TAP3) & POOL_WORDMASK];
+ w ^= input_pool_data[(i + POOL_TAP4) & POOL_WORDMASK];
+ w ^= input_pool_data[(i + POOL_TAP5) & POOL_WORDMASK];

/* Mix the result back in with a twist */
- input_pool.pool[i] = (w >> 3) ^ twist_table[w & 7];
+ input_pool_data[i] = (w >> 3) ^ twist_table[w & 7];

/*
* Normally, we add 7 bits of rotation to the pool.
@@ -1369,7 +1364,7 @@ static void extract_buf(u8 *out)

/* Generate a hash across the pool */
spin_lock_irqsave(&input_pool.lock, flags);
- blake2s_update(&state, (const u8 *)input_pool.pool, POOL_BYTES);
+ blake2s_update(&state, (const u8 *)input_pool_data, POOL_BYTES);
blake2s_final(&state, hash); /* final zeros out state */

/*



2022-05-28 20:34:55

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 098/145] random: check for signals every PAGE_SIZE chunk of /dev/[u]random

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

commit e3c1c4fd9e6d14059ed93ebfe15e1c57793b1a05 upstream.

In 1448769c9cdb ("random: check for signal_pending() outside of
need_resched() check"), Jann pointed out that we previously were only
checking the TIF_NOTIFY_SIGNAL and TIF_SIGPENDING flags if the process
had TIF_NEED_RESCHED set, which meant in practice, super long reads to
/dev/[u]random would delay signal handling by a long time. I tried this
using the below program, and indeed I wasn't able to interrupt a
/dev/urandom read until after several megabytes had been read. The bug
he fixed has always been there, and so code that reads from /dev/urandom
without checking the return value of read() has mostly worked for a long
time, for most sizes, not just for <= 256.

Maybe it makes sense to keep that code working. The reason it was so
small prior, ignoring the fact that it didn't work anyway, was likely
because /dev/random used to block, and that could happen for pretty
large lengths of time while entropy was gathered. But now, it's just a
chacha20 call, which is extremely fast and is just operating on pure
data, without having to wait for some external event. In that sense,
/dev/[u]random is a lot more like /dev/zero.

Taking a page out of /dev/zero's read_zero() function, it always returns
at least one chunk, and then checks for signals after each chunk. Chunk
sizes there are of length PAGE_SIZE. Let's just copy the same thing for
/dev/[u]random, and check for signals and cond_resched() for every
PAGE_SIZE amount of data. This makes the behavior more consistent with
expectations, and should mitigate the impact of Jann's fix for the
age-old signal check bug.

---- test program ----

#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <sys/random.h>

static unsigned char x[~0U];

static void handle(int) { }

int main(int argc, char *argv[])
{
pid_t pid = getpid(), child;
signal(SIGUSR1, handle);
if (!(child = fork())) {
for (;;)
kill(pid, SIGUSR1);
}
pause();
printf("interrupted after reading %zd bytes\n", getrandom(x, sizeof(x), 0));
kill(child, SIGTERM);
return 0;
}

Cc: Jann Horn <[email protected]>
Cc: Theodore Ts'o <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -525,7 +525,6 @@ EXPORT_SYMBOL(get_random_bytes);

static ssize_t get_random_bytes_user(void __user *buf, size_t nbytes)
{
- bool large_request = nbytes > 256;
ssize_t ret = 0;
size_t len;
u32 chacha_state[CHACHA_STATE_WORDS];
@@ -551,15 +550,6 @@ static ssize_t get_random_bytes_user(voi
}

do {
- if (large_request) {
- if (signal_pending(current)) {
- if (!ret)
- ret = -ERESTARTSYS;
- break;
- }
- cond_resched();
- }
-
chacha20_block(chacha_state, output);
if (unlikely(chacha_state[12] == 0))
++chacha_state[13];
@@ -573,6 +563,13 @@ static ssize_t get_random_bytes_user(voi
nbytes -= len;
buf += len;
ret += len;
+
+ BUILD_BUG_ON(PAGE_SIZE % CHACHA_BLOCK_SIZE != 0);
+ if (!(ret % PAGE_SIZE) && nbytes) {
+ if (signal_pending(current))
+ break;
+ cond_resched();
+ }
} while (nbytes);

memzero_explicit(output, sizeof(output));



2022-05-28 20:35:33

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 029/145] random: de-duplicate INPUT_POOL constants

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

commit 5b87adf30f1464477169a1d653e9baf8c012bbfe upstream.

We already had the POOL_* constants, so deduplicate the older INPUT_POOL
ones. As well, fold EXTRACT_SIZE into the poolinfo enum, since it's
related.

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

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -359,13 +359,6 @@
/* #define ADD_INTERRUPT_BENCH */

/*
- * Configuration information
- */
-#define INPUT_POOL_SHIFT 12
-#define INPUT_POOL_WORDS (1 << (INPUT_POOL_SHIFT-5))
-#define EXTRACT_SIZE (BLAKE2S_HASH_SIZE / 2)
-
-/*
* To allow fractional bits to be tracked, the entropy_count field is
* denominated in units of 1/8th bits.
*
@@ -440,7 +433,9 @@ enum poolinfo {
POOL_TAP2 = 76,
POOL_TAP3 = 51,
POOL_TAP4 = 25,
- POOL_TAP5 = 1
+ POOL_TAP5 = 1,
+
+ EXTRACT_SIZE = BLAKE2S_HASH_SIZE / 2
};

/*
@@ -503,7 +498,7 @@ MODULE_PARM_DESC(ratelimit_disable, "Dis
*
**********************************************************************/

-static u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy;
+static u32 input_pool_data[POOL_WORDS] __latent_entropy;

static struct {
/* read-only data: */
@@ -1964,7 +1959,7 @@ SYSCALL_DEFINE3(getrandom, char __user *
#include <linux/sysctl.h>

static int min_write_thresh;
-static int max_write_thresh = INPUT_POOL_WORDS * 32;
+static int max_write_thresh = POOL_BITS;
static int random_min_urandom_seed = 60;
static char sysctl_bootid[16];

@@ -2021,7 +2016,7 @@ static int proc_do_entropy(struct ctl_ta
return proc_dointvec(&fake_table, write, buffer, lenp, ppos);
}

-static int sysctl_poolsize = INPUT_POOL_WORDS * 32;
+static int sysctl_poolsize = POOL_BITS;
extern struct ctl_table random_table[];
struct ctl_table random_table[] = {
{



2022-05-28 20:35:51

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 028/145] random: remove unused OUTPUT_POOL constants

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

commit 0f63702718c91d89c922081ac1e6baeddc2d8b1a upstream.

We no longer have an output pool. Rather, we have just a wakeup bits
threshold for /dev/random reads, presumably so that processes don't
hang. This value, random_write_wakeup_bits, is configurable anyway. So
all the no longer usefully named OUTPUT_POOL constants were doing was
setting a reasonable default for random_write_wakeup_bits. This commit
gets rid of the constants and just puts it all in the default value of
random_write_wakeup_bits.

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

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -363,8 +363,6 @@
*/
#define INPUT_POOL_SHIFT 12
#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 (BLAKE2S_HASH_SIZE / 2)

/*
@@ -382,7 +380,7 @@
* should wake up processes which are selecting or polling on write
* access to /dev/random.
*/
-static int random_write_wakeup_bits = 28 * OUTPUT_POOL_WORDS;
+static int random_write_wakeup_bits = 28 * (1 << 5);

/*
* Originally, we used a primitive polynomial of degree .poolwords



2022-05-28 20:37:12

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 134/145] random: use static branch for crng_ready()

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

commit f5bda35fba615ace70a656d4700423fa6c9bebee upstream.

Since crng_ready() is only false briefly during initialization and then
forever after becomes true, we don't need to evaluate it after, making
it a prime candidate for a static branch.

One complication, however, is that it changes state in a particular call
to credit_init_bits(), which might be made from atomic context, which
means we must kick off a workqueue to change the static key. Further
complicating things, credit_init_bits() may be called sufficiently early
on in system initialization such that system_wq is NULL.

Fortunately, there exists the nice function execute_in_process_context(),
which will immediately execute the function if !in_interrupt(), and
otherwise defer it to a workqueue. During early init, before workqueues
are available, in_interrupt() is always false, because interrupts
haven't even been enabled yet, which means the function in that case
executes immediately. Later on, after workqueues are available,
in_interrupt() might be true, but in that case, the work is queued in
system_wq and all goes well.

Cc: Theodore Ts'o <[email protected]>
Cc: Sultan Alsawaf <[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 | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -77,8 +77,9 @@ 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))
+} crng_init __read_mostly = CRNG_EMPTY;
+static DEFINE_STATIC_KEY_FALSE(crng_is_ready);
+#define crng_ready() (static_branch_likely(&crng_is_ready) || 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;
@@ -108,6 +109,11 @@ bool rng_is_initialized(void)
}
EXPORT_SYMBOL(rng_is_initialized);

+static void crng_set_ready(struct work_struct *work)
+{
+ static_branch_enable(&crng_is_ready);
+}
+
/* Used by wait_for_random_bytes(), and considered an entropy collector, below. */
static void try_to_generate_entropy(void);

@@ -269,7 +275,7 @@ static void crng_reseed(void)
++next_gen;
WRITE_ONCE(base_crng.generation, next_gen);
WRITE_ONCE(base_crng.birth, jiffies);
- if (!crng_ready())
+ if (!static_branch_likely(&crng_is_ready))
crng_init = CRNG_READY;
spin_unlock_irqrestore(&base_crng.lock, flags);
memzero_explicit(key, sizeof(key));
@@ -787,6 +793,7 @@ static void extract_entropy(void *buf, s

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

@@ -802,6 +809,7 @@ static void credit_init_bits(size_t nbit

if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) {
crng_reseed(); /* Sets crng_init to CRNG_READY under base_crng.lock. */
+ execute_in_process_context(crng_set_ready, &set_ready);
process_random_ready_list();
wake_up_interruptible(&crng_init_wait);
kill_fasync(&fasync, SIGIO, POLL_IN);
@@ -1311,7 +1319,7 @@ SYSCALL_DEFINE3(getrandom, char __user *
if (count > INT_MAX)
count = INT_MAX;

- if (!(flags & GRND_INSECURE) && !crng_ready()) {
+ if (!crng_ready() && !(flags & GRND_INSECURE)) {
int ret;

if (flags & GRND_NONBLOCK)



2022-05-28 20:38:40

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 050/145] random: do not xor RDRAND when writing into /dev/random

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

commit 91c2afca290ed3034841c8c8532e69ed9e16cf34 upstream.

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

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

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

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



2022-05-28 20:39:44

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 116/145] um: use fallback for random_get_entropy() instead of zero

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

commit 9f13fb0cd11ed2327abff69f6501a2c124c88b5a upstream.

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

This is accomplished by just including the asm-generic code like on
other architectures, which means we can get rid of the empty stub
function here.

Cc: Thomas Gleixner <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Richard Weinberger <[email protected]>
Cc: Anton Ivanov <[email protected]>
Acked-by: Johannes Berg <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/um/include/asm/timex.h | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)

--- a/arch/um/include/asm/timex.h
+++ b/arch/um/include/asm/timex.h
@@ -2,13 +2,8 @@
#ifndef __UM_TIMEX_H
#define __UM_TIMEX_H

-typedef unsigned long cycles_t;
-
-static inline cycles_t get_cycles (void)
-{
- return 0;
-}
-
#define CLOCK_TICK_RATE (HZ)

+#include <asm-generic/timex.h>
+
#endif



2022-05-28 20:39:55

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 142/145] random: convert to using fops->write_iter()

From: Jens Axboe <[email protected]>

commit 22b0a222af4df8ee9bb8e07013ab44da9511b047 upstream.

Now that the read side has been converted to fix a regression with
splice, convert the write side as well to have some symmetry in the
interface used (and help deprecate ->write()).

Signed-off-by: Jens Axboe <[email protected]>
[Jason: cleaned up random_ioctl a bit, require full writes in
RNDADDENTROPY since it's crediting entropy, simplify control flow of
write_pool(), and incorporate suggestions from Al.]
Cc: Al Viro <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/random.c | 67 ++++++++++++++++++++++++++------------------------
1 file changed, 35 insertions(+), 32 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1255,39 +1255,31 @@ static __poll_t random_poll(struct file
return crng_ready() ? EPOLLIN | EPOLLRDNORM : EPOLLOUT | EPOLLWRNORM;
}

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

- while (len) {
- block_len = min(len, sizeof(block));
- if (copy_from_user(block, ubuf, block_len)) {
- ret = -EFAULT;
- goto out;
- }
- len -= block_len;
- ubuf += block_len;
- mix_pool_bytes(block, block_len);
+ if (unlikely(!iov_iter_count(iter)))
+ return 0;
+
+ for (;;) {
+ copied = copy_from_iter(block, sizeof(block), iter);
+ ret += copied;
+ mix_pool_bytes(block, copied);
+ if (!iov_iter_count(iter) || copied != sizeof(block))
+ break;
cond_resched();
}

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

-static ssize_t random_write(struct file *file, const char __user *ubuf,
- size_t len, loff_t *ppos)
+static ssize_t random_write_iter(struct kiocb *kiocb, struct iov_iter *iter)
{
- int ret;
-
- ret = write_pool(ubuf, len);
- if (ret)
- return ret;
-
- return (ssize_t)len;
+ return write_pool(iter);
}

static ssize_t urandom_read_iter(struct kiocb *kiocb, struct iov_iter *iter)
@@ -1319,9 +1311,8 @@ static ssize_t random_read_iter(struct k

static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
- int size, ent_count;
int __user *p = (int __user *)arg;
- int retval;
+ int ent_count;

switch (cmd) {
case RNDGETENTCNT:
@@ -1338,20 +1329,32 @@ static long random_ioctl(struct file *f,
return -EINVAL;
credit_init_bits(ent_count);
return 0;
- case RNDADDENTROPY:
+ case RNDADDENTROPY: {
+ struct iov_iter iter;
+ struct iovec iov;
+ ssize_t ret;
+ int len;
+
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (get_user(ent_count, p++))
return -EFAULT;
if (ent_count < 0)
return -EINVAL;
- if (get_user(size, p++))
+ if (get_user(len, p++))
+ return -EFAULT;
+ ret = import_single_range(WRITE, p, len, &iov, &iter);
+ if (unlikely(ret))
+ return ret;
+ ret = write_pool(&iter);
+ if (unlikely(ret < 0))
+ return ret;
+ /* Since we're crediting, enforce that it was all written into the pool. */
+ if (unlikely(ret != len))
return -EFAULT;
- retval = write_pool((const char __user *)p, size);
- if (retval < 0)
- return retval;
credit_init_bits(ent_count);
return 0;
+ }
case RNDZAPENTCNT:
case RNDCLEARPOOL:
/* No longer has any effect. */
@@ -1377,7 +1380,7 @@ static int random_fasync(int fd, struct

const struct file_operations random_fops = {
.read_iter = random_read_iter,
- .write = random_write,
+ .write_iter = random_write_iter,
.poll = random_poll,
.unlocked_ioctl = random_ioctl,
.compat_ioctl = compat_ptr_ioctl,
@@ -1387,7 +1390,7 @@ const struct file_operations random_fops

const struct file_operations urandom_fops = {
.read_iter = urandom_read_iter,
- .write = random_write,
+ .write_iter = random_write_iter,
.unlocked_ioctl = random_ioctl,
.compat_ioctl = compat_ptr_ioctl,
.fasync = random_fasync,



2022-05-28 20:41:40

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 036/145] random: access primary_pool directly rather than through pointer

From: Dominik Brodowski <[email protected]>

commit ebf7606388732ecf2821ca21087e9446cb4a5b57 upstream.

Both crng_initialize_primary() and crng_init_try_arch_early() are
only called for the primary_pool. Accessing it directly instead of
through a function parameter simplifies the code.

Signed-off-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 | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -762,7 +762,7 @@ static bool crng_init_try_arch(struct cr
return arch_init;
}

-static bool __init crng_init_try_arch_early(struct crng_state *crng)
+static bool __init crng_init_try_arch_early(void)
{
int i;
bool arch_init = true;
@@ -774,7 +774,7 @@ static bool __init crng_init_try_arch_ea
rv = random_get_entropy();
arch_init = false;
}
- crng->state[i] ^= rv;
+ primary_crng.state[i] ^= rv;
}

return arch_init;
@@ -788,16 +788,16 @@ static void crng_initialize_secondary(st
crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
}

-static void __init crng_initialize_primary(struct crng_state *crng)
+static void __init crng_initialize_primary(void)
{
- _extract_entropy(&crng->state[4], sizeof(u32) * 12);
- if (crng_init_try_arch_early(crng) && trust_cpu && crng_init < 2) {
+ _extract_entropy(&primary_crng.state[4], sizeof(u32) * 12);
+ if (crng_init_try_arch_early() && trust_cpu && crng_init < 2) {
invalidate_batched_entropy();
numa_crng_init();
crng_init = 2;
pr_notice("crng init done (trusting CPU's manufacturer)\n");
}
- crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
+ primary_crng.init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
}

static void crng_finalize_init(struct crng_state *crng)
@@ -1698,7 +1698,7 @@ int __init rand_initialize(void)
init_std_data();
if (crng_need_final_init)
crng_finalize_init(&primary_crng);
- crng_initialize_primary(&primary_crng);
+ crng_initialize_primary();
crng_global_init_time = jiffies;
if (ratelimit_disable) {
urandom_warning.interval = 0;



2022-05-28 20:41:46

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 047/145] random: get rid of secondary crngs

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

commit a9412d510ab9a9ba411fea612903631d2e1f1601 upstream.

As the comment said, this is indeed a "hack". Since it was introduced,
it's been a constant state machine nightmare, with lots of subtle early
boot issues and a wildly complex set of machinery to keep everything in
sync. Rather than continuing to play whack-a-mole with this approach,
this commit simply removes it entirely. This commit is preparation for
"random: use simpler fast key erasure flow on per-cpu keys" in this
series, which introduces a simpler (and faster) mechanism to accomplish
the same thing.

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 | 227 +++++++++++---------------------------------------
1 file changed, 54 insertions(+), 173 deletions(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -323,14 +323,11 @@ static struct crng_state primary_crng =
* its value (from 0->1->2).
*/
static int crng_init = 0;
-static bool crng_need_final_init = false;
#define crng_ready() (likely(crng_init > 1))
static int crng_init_cnt = 0;
-static unsigned long crng_global_init_time = 0;
#define CRNG_INIT_CNT_THRESH (2 * CHACHA_KEY_SIZE)
-static void _extract_crng(struct crng_state *crng, u8 out[CHACHA_BLOCK_SIZE]);
-static void _crng_backtrack_protect(struct crng_state *crng,
- u8 tmp[CHACHA_BLOCK_SIZE], int used);
+static void extract_crng(u8 out[CHACHA_BLOCK_SIZE]);
+static void crng_backtrack_protect(u8 tmp[CHACHA_BLOCK_SIZE], int used);
static void process_random_ready_list(void);
static void _get_random_bytes(void *buf, int nbytes);

@@ -365,7 +362,7 @@ static struct {

static void extract_entropy(void *buf, size_t nbytes);

-static void crng_reseed(struct crng_state *crng);
+static void crng_reseed(void);

/*
* This function adds bytes into the entropy "pool". It does not
@@ -464,7 +461,7 @@ static void credit_entropy_bits(int nbit
trace_credit_entropy_bits(nbits, entropy_count, _RET_IP_);

if (crng_init < 2 && entropy_count >= POOL_MIN_BITS)
- crng_reseed(&primary_crng);
+ crng_reseed();
}

/*********************************************************************
@@ -477,16 +474,7 @@ static void credit_entropy_bits(int nbit

static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);

-/*
- * Hack to deal with crazy userspace progams when they are all trying
- * to access /dev/urandom in parallel. The programs are almost
- * certainly doing something terribly wrong, but we'll work around
- * their brain damage.
- */
-static struct crng_state **crng_node_pool __read_mostly;
-
static void invalidate_batched_entropy(void);
-static void numa_crng_init(void);

static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
static int __init parse_trust_cpu(char *arg)
@@ -495,24 +483,6 @@ static int __init parse_trust_cpu(char *
}
early_param("random.trust_cpu", parse_trust_cpu);

-static bool crng_init_try_arch(struct crng_state *crng)
-{
- int i;
- bool arch_init = true;
- unsigned long rv;
-
- for (i = 4; i < 16; i++) {
- if (!arch_get_random_seed_long(&rv) &&
- !arch_get_random_long(&rv)) {
- rv = random_get_entropy();
- arch_init = false;
- }
- crng->state[i] ^= rv;
- }
-
- return arch_init;
-}
-
static bool __init crng_init_try_arch_early(void)
{
int i;
@@ -531,100 +501,17 @@ static bool __init crng_init_try_arch_ea
return arch_init;
}

-static void crng_initialize_secondary(struct crng_state *crng)
-{
- chacha_init_consts(crng->state);
- _get_random_bytes(&crng->state[4], sizeof(u32) * 12);
- crng_init_try_arch(crng);
- crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
-}
-
-static void __init crng_initialize_primary(void)
+static void __init crng_initialize(void)
{
extract_entropy(&primary_crng.state[4], sizeof(u32) * 12);
if (crng_init_try_arch_early() && trust_cpu && crng_init < 2) {
invalidate_batched_entropy();
- numa_crng_init();
crng_init = 2;
pr_notice("crng init done (trusting CPU's manufacturer)\n");
}
primary_crng.init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
}

-static void crng_finalize_init(void)
-{
- if (!system_wq) {
- /* We can't call numa_crng_init until we have workqueues,
- * so mark this for processing later. */
- crng_need_final_init = true;
- return;
- }
-
- invalidate_batched_entropy();
- numa_crng_init();
- crng_init = 2;
- crng_need_final_init = false;
- process_random_ready_list();
- 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) {
- pr_notice("%d urandom warning(s) missed due to ratelimiting\n",
- urandom_warning.missed);
- urandom_warning.missed = 0;
- }
-}
-
-static void do_numa_crng_init(struct work_struct *work)
-{
- int i;
- struct crng_state *crng;
- struct crng_state **pool;
-
- pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL | __GFP_NOFAIL);
- for_each_online_node(i) {
- crng = kmalloc_node(sizeof(struct crng_state),
- GFP_KERNEL | __GFP_NOFAIL, i);
- spin_lock_init(&crng->lock);
- crng_initialize_secondary(crng);
- pool[i] = crng;
- }
- /* pairs with READ_ONCE() in select_crng() */
- if (cmpxchg_release(&crng_node_pool, NULL, pool) != NULL) {
- for_each_node(i)
- kfree(pool[i]);
- kfree(pool);
- }
-}
-
-static DECLARE_WORK(numa_crng_init_work, do_numa_crng_init);
-
-static void numa_crng_init(void)
-{
- if (IS_ENABLED(CONFIG_NUMA))
- schedule_work(&numa_crng_init_work);
-}
-
-static struct crng_state *select_crng(void)
-{
- if (IS_ENABLED(CONFIG_NUMA)) {
- struct crng_state **pool;
- int nid = numa_node_id();
-
- /* pairs with cmpxchg_release() in do_numa_crng_init() */
- pool = READ_ONCE(crng_node_pool);
- if (pool && pool[nid])
- return pool[nid];
- }
-
- return &primary_crng;
-}
-
/*
* crng_fast_load() can be called by code in the interrupt service
* path. So we can't afford to dilly-dally. Returns the number of
@@ -702,68 +589,71 @@ static int crng_slow_load(const u8 *cp,
return 1;
}

-static void crng_reseed(struct crng_state *crng)
+static void crng_reseed(void)
{
unsigned long flags;
- int i;
+ int i, entropy_count;
union {
u8 block[CHACHA_BLOCK_SIZE];
u32 key[8];
} buf;

- if (crng == &primary_crng) {
- int entropy_count;
- do {
- entropy_count = READ_ONCE(input_pool.entropy_count);
- if (entropy_count < POOL_MIN_BITS)
- return;
- } while (cmpxchg(&input_pool.entropy_count, entropy_count, 0) != entropy_count);
- extract_entropy(buf.key, sizeof(buf.key));
- wake_up_interruptible(&random_write_wait);
- kill_fasync(&fasync, SIGIO, POLL_OUT);
- } else {
- _extract_crng(&primary_crng, buf.block);
- _crng_backtrack_protect(&primary_crng, buf.block,
- CHACHA_KEY_SIZE);
- }
- spin_lock_irqsave(&crng->lock, flags);
+ do {
+ entropy_count = READ_ONCE(input_pool.entropy_count);
+ if (entropy_count < POOL_MIN_BITS)
+ return;
+ } while (cmpxchg(&input_pool.entropy_count, entropy_count, 0) != entropy_count);
+ extract_entropy(buf.key, sizeof(buf.key));
+ wake_up_interruptible(&random_write_wait);
+ kill_fasync(&fasync, SIGIO, POLL_OUT);
+
+ spin_lock_irqsave(&primary_crng.lock, flags);
for (i = 0; i < 8; i++)
- crng->state[i + 4] ^= buf.key[i];
+ primary_crng.state[i + 4] ^= buf.key[i];
memzero_explicit(&buf, sizeof(buf));
- WRITE_ONCE(crng->init_time, jiffies);
- spin_unlock_irqrestore(&crng->lock, flags);
- if (crng == &primary_crng && crng_init < 2)
- crng_finalize_init();
+ WRITE_ONCE(primary_crng.init_time, jiffies);
+ spin_unlock_irqrestore(&primary_crng.lock, flags);
+ if (crng_init < 2) {
+ invalidate_batched_entropy();
+ crng_init = 2;
+ process_random_ready_list();
+ 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) {
+ pr_notice("%d urandom warning(s) missed due to ratelimiting\n",
+ urandom_warning.missed);
+ urandom_warning.missed = 0;
+ }
+ }
}

-static void _extract_crng(struct crng_state *crng, u8 out[CHACHA_BLOCK_SIZE])
+static void extract_crng(u8 out[CHACHA_BLOCK_SIZE])
{
unsigned long flags, init_time;

if (crng_ready()) {
- init_time = READ_ONCE(crng->init_time);
- if (time_after(READ_ONCE(crng_global_init_time), init_time) ||
- time_after(jiffies, init_time + CRNG_RESEED_INTERVAL))
- crng_reseed(crng);
- }
- spin_lock_irqsave(&crng->lock, flags);
- chacha20_block(&crng->state[0], out);
- if (crng->state[12] == 0)
- crng->state[13]++;
- spin_unlock_irqrestore(&crng->lock, flags);
-}
-
-static void extract_crng(u8 out[CHACHA_BLOCK_SIZE])
-{
- _extract_crng(select_crng(), out);
+ init_time = READ_ONCE(primary_crng.init_time);
+ if (time_after(jiffies, init_time + CRNG_RESEED_INTERVAL))
+ crng_reseed();
+ }
+ spin_lock_irqsave(&primary_crng.lock, flags);
+ chacha20_block(&primary_crng.state[0], out);
+ if (primary_crng.state[12] == 0)
+ primary_crng.state[13]++;
+ spin_unlock_irqrestore(&primary_crng.lock, flags);
}

/*
* Use the leftover bytes from the CRNG block output (if there is
* enough) to mutate the CRNG key to provide backtracking protection.
*/
-static void _crng_backtrack_protect(struct crng_state *crng,
- u8 tmp[CHACHA_BLOCK_SIZE], int used)
+static void crng_backtrack_protect(u8 tmp[CHACHA_BLOCK_SIZE], int used)
{
unsigned long flags;
u32 *s, *d;
@@ -774,17 +664,12 @@ static void _crng_backtrack_protect(stru
extract_crng(tmp);
used = 0;
}
- spin_lock_irqsave(&crng->lock, flags);
+ spin_lock_irqsave(&primary_crng.lock, flags);
s = (u32 *)&tmp[used];
- d = &crng->state[4];
+ d = &primary_crng.state[4];
for (i = 0; i < 8; i++)
*d++ ^= *s++;
- spin_unlock_irqrestore(&crng->lock, flags);
-}
-
-static void crng_backtrack_protect(u8 tmp[CHACHA_BLOCK_SIZE], int used)
-{
- _crng_backtrack_protect(select_crng(), tmp, used);
+ spin_unlock_irqrestore(&primary_crng.lock, flags);
}

static ssize_t extract_crng_user(void __user *buf, size_t nbytes)
@@ -1371,10 +1256,7 @@ static void __init init_std_data(void)
int __init rand_initialize(void)
{
init_std_data();
- if (crng_need_final_init)
- crng_finalize_init();
- crng_initialize_primary();
- crng_global_init_time = jiffies;
+ crng_initialize();
if (ratelimit_disable) {
urandom_warning.interval = 0;
unseeded_warning.interval = 0;
@@ -1544,8 +1426,7 @@ static long random_ioctl(struct file *f,
return -EPERM;
if (crng_init < 2)
return -ENODATA;
- crng_reseed(&primary_crng);
- WRITE_ONCE(crng_global_init_time, jiffies - 1);
+ crng_reseed();
return 0;
default:
return -EINVAL;



2022-05-28 20:42:23

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 014/145] random: do not sign extend bytes for rotation when mixing

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

commit 0d9488ffbf2faddebc6bac055bfa6c93b94056a3 upstream.

By using `char` instead of `unsigned char`, certain platforms will sign
extend the byte when `w = rol32(*bytes++, input_rotate)` is called,
meaning that bit 7 is overrepresented when mixing. This isn't a real
problem (unless the mixer itself is already broken) since it's still
invertible, but it's not quite correct either. Fix this by using an
explicit unsigned type.

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
@@ -547,7 +547,7 @@ static void _mix_pool_bytes(struct entro
unsigned long i, tap1, tap2, tap3, tap4, tap5;
int input_rotate;
int wordmask = r->poolinfo->poolwords - 1;
- const char *bytes = in;
+ const unsigned char *bytes = in;
__u32 w;

tap1 = r->poolinfo->tap1;



2022-05-28 20:42:54

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 094/145] random: mix build-time latent entropy into pool at init

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

commit 1754abb3e7583c570666fa1e1ee5b317e88c89a0 upstream.

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

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

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

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



2022-05-28 20:43:46

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 008/145] lib/crypto: blake2s: move hmac construction into wireguard

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

commit d8d83d8ab0a453e17e68b3a3bed1f940c34b8646 upstream.

Basically nobody should use blake2s in an HMAC construction; it already
has a keyed variant. But unfortunately for historical reasons, Noise,
used by WireGuard, uses HKDF quite strictly, which means we have to use
this. Because this really shouldn't be used by others, this commit moves
it into wireguard's noise.c locally, so that kernels that aren't using
WireGuard don't get this superfluous code baked in. On m68k systems,
this shaves off ~314 bytes.

Cc: Herbert Xu <[email protected]>
Tested-by: Geert Uytterhoeven <[email protected]>
Acked-by: Ard Biesheuvel <[email protected]>
Signed-off-by: Jason A. Donenfeld <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/net/wireguard/noise.c | 45 ++++++++++++++++++++++++++++++++++++------
include/crypto/blake2s.h | 3 --
lib/crypto/blake2s-selftest.c | 31 ----------------------------
lib/crypto/blake2s.c | 37 ----------------------------------
4 files changed, 39 insertions(+), 77 deletions(-)

--- a/drivers/net/wireguard/noise.c
+++ b/drivers/net/wireguard/noise.c
@@ -302,6 +302,41 @@ void wg_noise_set_static_identity_privat
static_identity->static_public, private_key);
}

+static void hmac(u8 *out, const u8 *in, const u8 *key, const size_t inlen, const size_t keylen)
+{
+ struct blake2s_state state;
+ u8 x_key[BLAKE2S_BLOCK_SIZE] __aligned(__alignof__(u32)) = { 0 };
+ u8 i_hash[BLAKE2S_HASH_SIZE] __aligned(__alignof__(u32));
+ int i;
+
+ if (keylen > BLAKE2S_BLOCK_SIZE) {
+ blake2s_init(&state, BLAKE2S_HASH_SIZE);
+ blake2s_update(&state, key, keylen);
+ blake2s_final(&state, x_key);
+ } else
+ memcpy(x_key, key, keylen);
+
+ for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i)
+ x_key[i] ^= 0x36;
+
+ blake2s_init(&state, BLAKE2S_HASH_SIZE);
+ blake2s_update(&state, x_key, BLAKE2S_BLOCK_SIZE);
+ blake2s_update(&state, in, inlen);
+ blake2s_final(&state, i_hash);
+
+ for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i)
+ x_key[i] ^= 0x5c ^ 0x36;
+
+ blake2s_init(&state, BLAKE2S_HASH_SIZE);
+ blake2s_update(&state, x_key, BLAKE2S_BLOCK_SIZE);
+ blake2s_update(&state, i_hash, BLAKE2S_HASH_SIZE);
+ blake2s_final(&state, i_hash);
+
+ memcpy(out, i_hash, BLAKE2S_HASH_SIZE);
+ memzero_explicit(x_key, BLAKE2S_BLOCK_SIZE);
+ memzero_explicit(i_hash, BLAKE2S_HASH_SIZE);
+}
+
/* This is Hugo Krawczyk's HKDF:
* - https://eprint.iacr.org/2010/264.pdf
* - https://tools.ietf.org/html/rfc5869
@@ -322,14 +357,14 @@ static void kdf(u8 *first_dst, u8 *secon
((third_len || third_dst) && (!second_len || !second_dst))));

/* Extract entropy from data into secret */
- blake2s256_hmac(secret, data, chaining_key, data_len, NOISE_HASH_LEN);
+ hmac(secret, data, chaining_key, data_len, NOISE_HASH_LEN);

if (!first_dst || !first_len)
goto out;

/* Expand first key: key = secret, data = 0x1 */
output[0] = 1;
- blake2s256_hmac(output, output, secret, 1, BLAKE2S_HASH_SIZE);
+ hmac(output, output, secret, 1, BLAKE2S_HASH_SIZE);
memcpy(first_dst, output, first_len);

if (!second_dst || !second_len)
@@ -337,8 +372,7 @@ static void kdf(u8 *first_dst, u8 *secon

/* Expand second key: key = secret, data = first-key || 0x2 */
output[BLAKE2S_HASH_SIZE] = 2;
- blake2s256_hmac(output, output, secret, BLAKE2S_HASH_SIZE + 1,
- BLAKE2S_HASH_SIZE);
+ hmac(output, output, secret, BLAKE2S_HASH_SIZE + 1, BLAKE2S_HASH_SIZE);
memcpy(second_dst, output, second_len);

if (!third_dst || !third_len)
@@ -346,8 +380,7 @@ static void kdf(u8 *first_dst, u8 *secon

/* Expand third key: key = secret, data = second-key || 0x3 */
output[BLAKE2S_HASH_SIZE] = 3;
- blake2s256_hmac(output, output, secret, BLAKE2S_HASH_SIZE + 1,
- BLAKE2S_HASH_SIZE);
+ hmac(output, output, secret, BLAKE2S_HASH_SIZE + 1, BLAKE2S_HASH_SIZE);
memcpy(third_dst, output, third_len);

out:
--- a/include/crypto/blake2s.h
+++ b/include/crypto/blake2s.h
@@ -101,7 +101,4 @@ static inline void blake2s(u8 *out, cons
blake2s_final(&state, out);
}

-void blake2s256_hmac(u8 *out, const u8 *in, const u8 *key, const size_t inlen,
- const size_t keylen);
-
#endif /* _CRYPTO_BLAKE2S_H */
--- a/lib/crypto/blake2s-selftest.c
+++ b/lib/crypto/blake2s-selftest.c
@@ -15,7 +15,6 @@
* #include <stdio.h>
*
* #include <openssl/evp.h>
- * #include <openssl/hmac.h>
*
* #define BLAKE2S_TESTVEC_COUNT 256
*
@@ -58,16 +57,6 @@
* }
* printf("};\n\n");
*
- * printf("static const u8 blake2s_hmac_testvecs[][BLAKE2S_HASH_SIZE] __initconst = {\n");
- *
- * HMAC(EVP_blake2s256(), key, sizeof(key), buf, sizeof(buf), hash, NULL);
- * print_vec(hash, BLAKE2S_OUTBYTES);
- *
- * HMAC(EVP_blake2s256(), buf, sizeof(buf), key, sizeof(key), hash, NULL);
- * print_vec(hash, BLAKE2S_OUTBYTES);
- *
- * printf("};\n");
- *
* return 0;
*}
*/
@@ -554,15 +543,6 @@ static const u8 blake2s_testvecs[][BLAKE
0xd6, 0x98, 0x6b, 0x07, 0x10, 0x65, 0x52, 0x65, },
};

-static const u8 blake2s_hmac_testvecs[][BLAKE2S_HASH_SIZE] __initconst = {
- { 0xce, 0xe1, 0x57, 0x69, 0x82, 0xdc, 0xbf, 0x43, 0xad, 0x56, 0x4c, 0x70,
- 0xed, 0x68, 0x16, 0x96, 0xcf, 0xa4, 0x73, 0xe8, 0xe8, 0xfc, 0x32, 0x79,
- 0x08, 0x0a, 0x75, 0x82, 0xda, 0x3f, 0x05, 0x11, },
- { 0x77, 0x2f, 0x0c, 0x71, 0x41, 0xf4, 0x4b, 0x2b, 0xb3, 0xc6, 0xb6, 0xf9,
- 0x60, 0xde, 0xe4, 0x52, 0x38, 0x66, 0xe8, 0xbf, 0x9b, 0x96, 0xc4, 0x9f,
- 0x60, 0xd9, 0x24, 0x37, 0x99, 0xd6, 0xec, 0x31, },
-};
-
bool __init blake2s_selftest(void)
{
u8 key[BLAKE2S_KEY_SIZE];
@@ -607,16 +587,5 @@ bool __init blake2s_selftest(void)
}
}

- if (success) {
- blake2s256_hmac(hash, buf, key, sizeof(buf), sizeof(key));
- success &= !memcmp(hash, blake2s_hmac_testvecs[0], BLAKE2S_HASH_SIZE);
-
- blake2s256_hmac(hash, key, buf, sizeof(key), sizeof(buf));
- success &= !memcmp(hash, blake2s_hmac_testvecs[1], BLAKE2S_HASH_SIZE);
-
- if (!success)
- pr_err("blake2s256_hmac self-test: FAIL\n");
- }
-
return success;
}
--- a/lib/crypto/blake2s.c
+++ b/lib/crypto/blake2s.c
@@ -30,43 +30,6 @@ void blake2s_final(struct blake2s_state
}
EXPORT_SYMBOL(blake2s_final);

-void blake2s256_hmac(u8 *out, const u8 *in, const u8 *key, const size_t inlen,
- const size_t keylen)
-{
- struct blake2s_state state;
- u8 x_key[BLAKE2S_BLOCK_SIZE] __aligned(__alignof__(u32)) = { 0 };
- u8 i_hash[BLAKE2S_HASH_SIZE] __aligned(__alignof__(u32));
- int i;
-
- if (keylen > BLAKE2S_BLOCK_SIZE) {
- blake2s_init(&state, BLAKE2S_HASH_SIZE);
- blake2s_update(&state, key, keylen);
- blake2s_final(&state, x_key);
- } else
- memcpy(x_key, key, keylen);
-
- for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i)
- x_key[i] ^= 0x36;
-
- blake2s_init(&state, BLAKE2S_HASH_SIZE);
- blake2s_update(&state, x_key, BLAKE2S_BLOCK_SIZE);
- blake2s_update(&state, in, inlen);
- blake2s_final(&state, i_hash);
-
- for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i)
- x_key[i] ^= 0x5c ^ 0x36;
-
- blake2s_init(&state, BLAKE2S_HASH_SIZE);
- blake2s_update(&state, x_key, BLAKE2S_BLOCK_SIZE);
- blake2s_update(&state, i_hash, BLAKE2S_HASH_SIZE);
- blake2s_final(&state, i_hash);
-
- memcpy(out, i_hash, BLAKE2S_HASH_SIZE);
- memzero_explicit(x_key, BLAKE2S_BLOCK_SIZE);
- memzero_explicit(i_hash, BLAKE2S_HASH_SIZE);
-}
-EXPORT_SYMBOL(blake2s256_hmac);
-
static int __init blake2s_mod_init(void)
{
if (!IS_ENABLED(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS) &&



2022-05-28 20:48:23

by Greg KH

[permalink] [raw]
Subject: [PATCH 5.15 048/145] random: inline leaves of rand_initialize()

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

commit 8566417221fcec51346ec164e920dacb979c6b5f upstream.

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

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

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

static void invalidate_batched_entropy(void);

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

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

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

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



2022-05-28 21:08:55

by Ron Economos

[permalink] [raw]
Subject: Re: [PATCH 5.15 000/145] 5.15.44-rc1 review

On 5/27/22 1:48 AM, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.15.44 release.
> There are 145 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:32 +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.15.44-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.15.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h

Built and booted successfully on RISC-V RV64 (HiFive Unmatched).

Tested-by: Ron Economos <[email protected]>


2022-05-29 00:35:46

by Fox Chen

[permalink] [raw]
Subject: RE: [PATCH 5.15 000/145] 5.15.44-rc1 review

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

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

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