Skip to content

[rlc-10/6.12.0-211.47.1.el10_2] Multiple patches tested (26 commits) - #1556

Open
ciq-kernel-automation[bot] wants to merge 26 commits into
rlc-10/6.12.0-211.47.1.el10_2from
{jallison-fips}_rlc-10/6.12.0-211.47.1.el10_2
Open

[rlc-10/6.12.0-211.47.1.el10_2] Multiple patches tested (26 commits)#1556
ciq-kernel-automation[bot] wants to merge 26 commits into
rlc-10/6.12.0-211.47.1.el10_2from
{jallison-fips}_rlc-10/6.12.0-211.47.1.el10_2

Conversation

@ciq-kernel-automation

@ciq-kernel-automation ciq-kernel-automation Bot commented Aug 27, 2026

Copy link
Copy Markdown

Summary

This PR has been automatically created after successful completion of all CI stages.

Commit Message(s)

crypto: ecdh - implement FIPS PCT

commit -
commit-source https://build.opensuse.org/public/source/SUSE:SLE-15-SP6:GA/kernel-source/patches.suse.tar.bz2
commit-patch-path patches.suse/crypto-ecdh-implement-FIPS-PCT.patch
crypto: essiv - Zeroize keys on exit in essiv_aead_setkey()

In essiv_aead_setkey(), use the same logic as crypto_authenc_esn_setkey()
to zeroize keys on exit.
crypto: drbg - Align buffers to at least a cache line

None of the ciphers used by the DRBG have an alignment requirement; thus,
they all return 0 from .crypto_init, resulting in inconsistent alignment
across all buffers.
mm/gup: introduce pin_user_pages_fast_only()

Like pin_user_pages_fast(), but with the internal-only FOLL_FAST_ONLY flag.
crypto: rng - Convert crypto_default_rng_refcnt into an unsigned int

There is no reason this refcount should be a signed int. Convert it to an
unsigned int, thereby also making it less likely to ever overflow.
crypto: rng - Fix priority inversions due to mutex locks

Since crypto_devrandom_read_iter() is invoked directly by user tasks and is
accessible by every task in the system, there are glaring priority
inversions on crypto_reseed_rng_lock and crypto_default_rng_lock.
crypto: sha1 - Add FIPS known answer test for lib/crypto path

The kernel has two SHA-1 code paths: the crypto API (crypto/sha1_generic.c),
which is covered by testmgr's FIPS self-tests at algorithm registration
time, and the library implementation (lib/crypto/sha1.c), which provides
sha1_init() and sha1_transform() directly to in-kernel callers that
bypass the crypto API entirely.
crypto: sha256 - Add FIPS known answer test for lib/crypto path

The kernel has two SHA-256 code paths: the crypto API
(crypto/sha256_generic.c), which is covered by testmgr's FIPS
self-tests at algorithm registration time, and the library
implementation (lib/crypto/sha256.c), which provides sha256_init(),
sha256_update(), sha256_final(), and the sha256() one-shot function
directly to in-kernel callers that bypass the crypto API entirely.
crypto: testmgr - block Crypto API xxhash64 in FIPS mode

commit-author Joachim Vandersmissen <git@jvdsn.com>
commit -
commit-source https://lore.kernel.org/linux-crypto/20260303060509.246038-1-git@jvdsn.com/
When in fips mode, self-test errors must panic.

Requested by the lab.
When in fips mode, self-test errors must panic.

Requested by the lab.
In crypto_kdf108_ctr_generate() there is no minimum length check for the digest to be generated - it must be at least 112 bits.

Requested by the lab.
crypto: Kconfig - Make CRYPTO_FIPS depend on the DRBG being built-in

    When FIPS mode is enabled (via fips=1), there is an absolute need for the
    DRBG to be available. This is at odds with the fact that the DRBG can be
    built as a module when in FIPS mode, leaving critical RNG functionality at
    the whims of userspace.
crypto: rng - Ensure set_ent is always present

commit c0d36727bf39bb16ef0a67ed608e279535ebf0da upstream.
crypto: rng - Override drivers/char/random in FIPS mode

commit-author Herbert Xu <herbert.xu@redhat.com>
commit 8b0beca705b3877e24cccdd672422c66bbd75635
commit-source https://gitlab.com/cki-project/kernel-ark
crypto: rng - Implement fast per-CPU DRBG instances

When the kernel is booted with fips=1, the RNG exposed to userspace is
hijacked away from the CRNG and redirects to crypto_devrandom_read_iter(),
which utilizes the DRBG.
random: Restrict extrng registration to init time

It is technically a risk to permit extrng registration by modules after
kernel init completes. Since there is only one user of the extrng interface
and it is imperative that it is the _only_ registered extrng for FIPS
compliance, restrict the extrng registration interface to only permit
registration during kernel init and only from built-in drivers.
crypto: rng - Only allow the DRBG to register as "stdrng" in FIPS mode

In FIPS mode, the DRBG must take precedence over all stdrng algorithms.
The only problem standing in the way of this is that a different stdrng
algorithm could get registered and utilized before the DRBG is registered,
and since crypto_alloc_rng() only allocates an stdrng algorithm when
there's no existing allocation, this means that it's possible for the wrong
stdrng algorithm to remain in use indefinitely.
crypto: rng - Fix tabs vs spaces in the per-CPU DRBG code

The 6.18.y version of "crypto: rng - Implement fast per-CPU DRBG instances"
picked up a few spots that use spaces where the ciqlts9_6 tree's version
[1] uses tabs: the lock_default_rng() comment's numbered list, the line
continuations in the unlock_local_rng() macro, and a brace in
crypto_devrandom_read_iter(). A nearby block comment was also missing the
space before its '*'. Fix them up.
crypto: rng - Make the per-CPU DRBG instances permanent

The per-CPU DRBG instances used to be torn down by crypto_del_default_rng()
under del_pcpu_rwsem, and the read path took that rwsem as a reader to keep
an instance from being freed out from under it. That machinery only made
sense back when the extrng override could be unregistered and the DRBG
could be built as a module.
crypto: rng - Skip leading zero-length iovec segments

The fast per-CPU DRBG path computes its initial user destination address
straight from the iov_iter. For an ITER_IOVEC iter it reads iter_iov_addr()
and iter_iov_len() of the current segment, but when the iovec leads with
one or more zero-length segments, the current segment is one of those empty
entries. iter_iov_addr() then hands back the base of an empty segment,
which is whatever userspace put there: its base can be NULL or some other
unwritable address, since a zero-length segment is never actually touched.
crypto: rng - Fix spurious EFAULT when the destination PTE is zapped

While GUP pinning makes it possible to pin the page _backing_ a user
address, it *doesn't* pin the page table entry (PTE) for that mapping. This
means the pinned physical page can be separated from the user address it
was backing, and even back a _different_ user address within the same
process. PTE zapping naturally happens during memory reclaim when memory
pressure is elevated, and can even be done directly by userspace via
madvise(MADV_DONTNEED).
Revert "mm/gup: reintroduce pin_user_pages_fast_only()"

This reverts commit ef467f3c43338f72f4173c98b15bc8021f79c3a1.
crypto: rng - Fix double percpu offset in local_unlock() calls

local_unlock() is supposed to take a percpu pointer, which it then offsets
for the current CPU. The problem is that the per-CPU DRBG code passes
local_unlock() a pointer that has *already been offset for the current
CPU*, so the percpu offset gets added twice. `pcri` is the percpu pointer
and `cri` is the offset `pcri` pointer for the current CPU; passing `cri`
to local_unlock() results in the current CPU's offset getting added again
and thus the resulting pointer is garbage.
Add CONFIG_CRYPTO_FIPS_CUSTOM_VERSION=y,
CONFIG_CRYPTO_FIPS_VERSION="ciq.6.12.20260826"

Requested by lab.
Unset CRYPTO_JITTERENTROPY_MEMSIZE_2, set CRYPTO_JITTERENTROPY_MEMSIZE_128.
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=512
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=256

Requested by lab.

Test Results

✅ Build Stage

Architecture Build Time Total Time
x86_64 41m 26s 42m 18s
aarch64 25m 37s 26m 17s

✅ Boot Verification

✅ Kernel Selftests

Architecture Passed Failed Compared Against Status
x86_64 430 62 rlc-10/6.12.0-211.47.1.el10_2 ⚠️ No baseline available
aarch64 373 62 rlc-10/6.12.0-211.47.1.el10_2 ⚠️ No baseline available

✅ LTP Results

Architecture Passed Failed Compared Against Status
x86_64 1477 81 rlc-10/6.12.0-211.47.1.el10_2 ⚠️ No baseline available
aarch64 1451 81 rlc-10/6.12.0-211.47.1.el10_2 ⚠️ No baseline available

🤖 This PR was automatically generated by GitHub Actions
Run ID: 33030966462

jallisonciq and others added 13 commits August 26, 2026 10:35
commit -
commit-source https://build.opensuse.org/public/source/SUSE:SLE-15-SP6:GA/kernel-source/patches.suse.tar.bz2
commit-patch-path patches.suse/crypto-ecdh-implement-FIPS-PCT.patch

SP800-56Arev3, 5.6.2.1.4 ("Owner Assurance of Pair-wise Consistency")
requires that a pair-wise consistency check needs to be conducted on a
keypair. A pair-wise consistency test (PCT) is meant to ensure that a
some provided public key is indeed associated with the given private one.
As the kernel's ECDH implementation always computes the public key from
the private one, this is guaranteed already as per the API. However, in the
course of the certification process, there had been a lengthy discussion
regarding this topic, with the result that a PCT is nonetheless mandatory.
As the only user of the in-kernel ECDH is bluetooth, performance certainly
isn't super critical. Simply implement a PCT for ECDH and move on. As
mandated by SP800-56Arev3, 5.6.2.1.4, the PCT involves recomputing the
public key and comparing it against the one under test.

Signed-off-by: Nicolai Stange <nstange@suse.de>
Signed-off-by: Jeremy Allison <jallison@ciq.com>
In essiv_aead_setkey(), use the same logic as crypto_authenc_esn_setkey()
to zeroize keys on exit.

[Sultan: touched up commit message]

Signed-off-by: Jason Rodriguez <jrodriguez@ciq.com>
None of the ciphers used by the DRBG have an alignment requirement; thus,
they all return 0 from .crypto_init, resulting in inconsistent alignment
across all buffers.

Align all buffers to at least a cache line to improve performance. This is
especially useful when multiple DRBG instances are used, since it prevents
false sharing of cache lines between the different instances.

Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
Like pin_user_pages_fast(), but with the internal-only FOLL_FAST_ONLY flag.

This complements the get_user_pages*() API, which already has
get_user_pages_fast_only().

Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
There is no reason this refcount should be a signed int. Convert it to an
unsigned int, thereby also making it less likely to ever overflow.

Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
Since crypto_devrandom_read_iter() is invoked directly by user tasks and is
accessible by every task in the system, there are glaring priority
inversions on crypto_reseed_rng_lock and crypto_default_rng_lock.

Tasks of arbitrary scheduling priority access crypto_devrandom_read_iter().
When a low-priority task owns one of the mutex locks, higher-priority tasks
waiting on that mutex lock are stalled until the low-priority task is done.

Fix the priority inversions by converting the mutex locks into rt_mutex
locks which have PI support.

Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
The kernel has two SHA-1 code paths: the crypto API (crypto/sha1_generic.c),
which is covered by testmgr's FIPS self-tests at algorithm registration
time, and the library implementation (lib/crypto/sha1.c), which provides
sha1_init() and sha1_transform() directly to in-kernel callers that
bypass the crypto API entirely.

When booting with fips=1, the library path was not independently
validated, meaning any corruption or miscompilation of the lib/crypto
SHA-1 code would go undetected.  This is a gap in FIPS 140 coverage
since several subsystems use the library functions directly.

Add a known answer test that runs at subsys_initcall time when
CONFIG_CRYPTO_FIPS is enabled and fips_enabled is set.  The test
computes SHA-1 over the NIST one-block test message "abc" (pre-padded
to a full 64-byte SHA-1 input block) using the library's own
sha1_init() and sha1_transform() functions, and compares the result
against the known digest a9993e364706816aba3e25717850c26c9cd0d89d.
On mismatch the kernel panics, consistent with FIPS 140 self-test
failure handling elsewhere in the tree (e.g. the 6.18 HMAC-SHA-1 KAT
in the same file and DRBG self-tests in crypto/).

The test vector data and expected digest are marked __initconst so they
are freed after boot, and the workspace buffer is scrubbed with
memzero_explicit() after use.

No header, Kconfig, or Makefile changes are required: SHA1_BLOCK_SIZE,
SHA1_DIGEST_WORDS, and SHA1_WORKSPACE_WORDS are already provided by
include/crypto/sha1.h, and CONFIG_CRYPTO_FIPS already exists in
crypto/Kconfig.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The kernel has two SHA-256 code paths: the crypto API
(crypto/sha256_generic.c), which is covered by testmgr's FIPS
self-tests at algorithm registration time, and the library
implementation (lib/crypto/sha256.c), which provides sha256_init(),
sha256_update(), sha256_final(), and the sha256() one-shot function
directly to in-kernel callers that bypass the crypto API entirely.

When booting with fips=1, the library path was not independently
validated, meaning any corruption or miscompilation of the lib/crypto
SHA-256 code would go undetected.  This is a gap in FIPS 140 coverage
since several subsystems use the library functions directly.

Add a known answer test that runs at subsys_initcall time when
CONFIG_CRYPTO_FIPS is enabled and fips_enabled is set.  The test
uses the sha256() one-shot function to hash the NIST one-block test
message "abc", exercising the full sha256_init/update/final path
including the underlying sha256_transform compression function.  The
result is compared against the known digest
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad.
On mismatch the kernel panics, consistent with FIPS 140 self-test
failure handling elsewhere in the tree.

Unlike the SHA-1 library KAT (which could only test the raw transform
since the 6.12 lib/crypto/sha1.c lacks update/final), this test
covers the complete hash pipeline including padding and finalization
logic.

The test vector data and expected digest are marked __initconst so
they are freed after boot.  No header, Kconfig, or Makefile changes
are required.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
commit-author Joachim Vandersmissen <git@jvdsn.com>
commit -
commit-source https://lore.kernel.org/linux-crypto/20260303060509.246038-1-git@jvdsn.com/

xxhash64 is not a cryptographic hash algorithm, but is offered in the
same API (shash) as actual cryptographic hash algorithms such as
SHA-256. The Cryptographic Module Validation Program (CMVP), managing
FIPS certification, believes that this could cause confusion. xxhash64
must therefore be blocked in FIPS mode.

The only usage of xxhash64 in the kernel is btrfs. Commit fe11ac1
("btrfs: switch to library APIs for checksums") recently modified the
btrfs code to use the lib/crypto API, avoiding the Kernel Cryptographic
API. Consequently, the removal of xxhash64 from the Crypto API in FIPS
mode should now have no impact on btrfs usage.

Signed-off-by: Joachim Vandersmissen <git@jvdsn.com>
Signed-off-by: Jeremy Allison <jallison@ciq.com>
Requested by the lab.

Signed-off-by: Jeremy Allison <jallison@ciq.com>
Requested by the lab.

Signed-off-by: Jeremy Allison <jallison@ciq.com>
…the digest to be generated - it must be at least 112 bits.

Requested by the lab.

Signed-off-by: Jeremy Allison <jallison@ciq.com>
    When FIPS mode is enabled (via fips=1), there is an absolute need for the
    DRBG to be available. This is at odds with the fact that the DRBG can be
    built as a module when in FIPS mode, leaving critical RNG functionality at
    the whims of userspace.

    Userspace could simply rmmod the DRBG module, or not provide it at all and
    thus a different stdrng algorithm could be used without anyone noticing.

    Additionally, when running a FIPS-enabled userspace, modprobe itself may
    perform a getrandom() syscall _before_ loading a given module. As a result,
    there's a possible deadlock scenario where the RNG core (crypto/rng.c)
    initializes _before_ the DRBG, thereby installing its getrandom() override
    without having an stdrng algorithm available. Then, when userspace calls
    getrandom() which redirects to the override in crypto/rng.c,
    crypto_alloc_rng("stdrng") invokes the UMH (modprobe) to load the DRBG
    (which is aliased to stdrng). And *then* that modprobe invocation gets
    stuck at getrandom() because there's no stdrng algorithm available!

    There are too many risks that come with allowing the DRBG and RNG core to
    be modular for FIPS mode. Therefore, make CRYPTO_FIPS require the DRBG to
    be built-in, which in turn makes the DRBG require the RNG core to be
    built-in. That way, it's guaranteed for these drivers to be built-in when
    running in FIPS mode.

    Also clean up the CRYPTO_FIPS option name and remove the CRYPTO_ANSI_CPRNG
    dependency since it's obsolete for FIPS now.

    Signed-off-by: Sultan Alsawaf <sultan@ciq.com>

    Signed-off-by: Jonathan Maple <jmaple@ciq.com>

Signed-off-by: Jeremy Allison <jallison@ciq.com>
@ciq-kernel-automation ciq-kernel-automation Bot added the created-by-kernelci Tag PRs that were automatically created when a user branch was pushed to the repo (kernelCI) label Aug 27, 2026
herbertx and others added 13 commits August 26, 2026 18:39
commit c0d3672 upstream.

Ensure that set_ent is always set since only drbg provides it.

Fixes: 77ebdab ("crypto: af_alg - add extra parameters for DRBG interface")
Reported-by: Yiqi Sun <sunyiqixm@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
commit-author Herbert Xu <herbert.xu@redhat.com>
commit 8b0beca705b3877e24cccdd672422c66bbd75635
commit-source https://gitlab.com/cki-project/kernel-ark

Upstream Status: RHEL only

Restore the changes to use the crypto RNG in drivers/char/random
which were reverted after 5.18.

This reverts commit 297bcb88233101e8d5062729ff3a5f989bad1c3b.

This also brings the code up-to-date with respect to centos-stream
commit 9de3a73 so that changes that
were made after the kernel-ark revert have been brought in.

Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
Signed-off-by: Jeremy Allison <jallison@ciq.com>
When the kernel is booted with fips=1, the RNG exposed to userspace is
hijacked away from the CRNG and redirects to crypto_devrandom_read_iter(),
which utilizes the DRBG.

Notably, crypto_devrandom_read_iter() maintains just two global DRBG
instances _for the entire system_, and the two instances serve separate
request types: one instance for GRND_RANDOM requests (crypto_reseed_rng),
and one instance for non-GRND_RANDOM requests (crypto_default_rng). So in
essence, for requests of a single type, there is just one global RNG for
all CPUs in the entire system, which scales _very_ poorly.

To make matters worse, the temporary buffer used to ferry data between the
DRBG and userspace is woefully small at only 256 bytes, which doesn't do a
good job of maximizing throughput from the DRBG. This results in lost
performance when userspace requests >256 bytes; it is observed that DRBG
throughput improves by 70% on an i9-13900H when the buffer size is
increased to 4096 bytes (one page). Going beyond the size of one page up to
the DRBG maximum request limit of 65536 bytes produces diminishing returns
of only 3% improved throughput in comparison. And going below the size of
one page produces progressively less throughput at each power of 2: there's
a 5% loss going from 4096 bytes to 2048 bytes and a 9% loss going from 2048
bytes to 1024 bytes.

Thus, this implements per-CPU DRBG instances utilizing a page-sized buffer
for each CPU to utilize the DRBG itself more effectively. On top of that,
for non-GRND_RANDOM requests, the DRBG's operations now occur under a local
lock that disables preemption on non-PREEMPT_RT kernels, which not only
keeps each CPU's DRBG instance isolated from another, but also improves
temporal cache locality while the DRBG actively generates a new string of
random bytes.

Prefaulting one user destination page at a time is also employed to prevent
a DRBG instance from getting blocked on page faults, thereby maximizing the
use of the DRBG so that the only bottleneck is the DRBG itself.

Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
It is technically a risk to permit extrng registration by modules after
kernel init completes. Since there is only one user of the extrng interface
and it is imperative that it is the _only_ registered extrng for FIPS
compliance, restrict the extrng registration interface to only permit
registration during kernel init and only from built-in drivers.

This also eliminates the risks associated with the extrng interface itself
being designed to solely accommodate a single registration, which would
therefore permit the registered extrng to be overridden or even removed by
an unrelated module.

Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
Signed-off-by: Jonathan Maple <jmaple@ciq.com>
In FIPS mode, the DRBG must take precedence over all stdrng algorithms.
The only problem standing in the way of this is that a different stdrng
algorithm could get registered and utilized before the DRBG is registered,
and since crypto_alloc_rng() only allocates an stdrng algorithm when
there's no existing allocation, this means that it's possible for the wrong
stdrng algorithm to remain in use indefinitely.

This issue is also often impossible to observe from userspace; an RNG other
than the DRBG could be used somewhere in the kernel and userspace would be
none the wiser.

To ensure this can never happen, only allow stdrng instances from the DRBG
to be registered when running in FIPS mode. This works since the previous
commit forces the DRBG to be built into the kernel when CONFIG_CRYPTO_FIPS
is enabled, so the DRBG's presence is guaranteed when fips_enabled is true.

Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
Signed-off-by: Jonathan Maple <jmaple@ciq.com>
The 6.18.y version of "crypto: rng - Implement fast per-CPU DRBG instances"
picked up a few spots that use spaces where the ciqlts9_6 tree's version
[1] uses tabs: the lock_default_rng() comment's numbered list, the line
continuations in the unlock_local_rng() macro, and a brace in
crypto_devrandom_read_iter(). A nearby block comment was also missing the
space before its '*'. Fix them up.

[1] b0c560a

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
The per-CPU DRBG instances used to be torn down by crypto_del_default_rng()
under del_pcpu_rwsem, and the read path took that rwsem as a reader to keep
an instance from being freed out from under it. That machinery only made
sense back when the extrng override could be unregistered and the DRBG
could be built as a module.

That's no longer the case. extrng registration is now restricted to init
time from built-in drivers, and FIPS mode requires the DRBG to be built-in,
so the registered DRBG can't be unregistered or swapped out. As such, the
per-CPU instances are never torn down, and the deletion rwsem just adds a
lock to the hot read path for no reason.

Drop the deletion rwsem and crypto_del_pcpu_rng(), and stop freeing the
per-CPU instances in crypto_del_default_rng(). Since the instances are
permanent now, allocate their pages once at init time with __GFP_NOFAIL and
ditch free_pcpu_inst() along with the failure paths in crypto_rng_init();
failing to install the RNG override in FIPS mode would be catastrophic, so
the setup isn't allowed to fail anyway.

This brings the per-CPU DRBG implementation in line with the ciqlts9_6
tree's version of "crypto: rng - Implement fast per-CPU DRBG instances"
[1].

[1] b0c560a

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
The fast per-CPU DRBG path computes its initial user destination address
straight from the iov_iter. For an ITER_IOVEC iter it reads iter_iov_addr()
and iter_iov_len() of the current segment, but when the iovec leads with
one or more zero-length segments, the current segment is one of those empty
entries. iter_iov_addr() then hands back the base of an empty segment,
which is whatever userspace put there: its base can be NULL or some other
unwritable address, since a zero-length segment is never actually touched.

Right after the setup, that address is prefaulted, and on a bogus base it
fails. A failed prefault on the very first address is treated as fatal, so
the whole read bails out to -EFAULT even though there are perfectly good
non-empty segments later in the iovec. This is reachable with something as
simple as readv() on /dev/urandom where the first iovec entry is {NULL, 0}.

Fix it by advancing the iterator by zero before reading the first address.
The iovec advance loop walks past every leading empty segment and stops at
the first non-empty one, and there's guaranteed to be such a segment
because iov_iter_count() is nonzero at this point. Empty segments that crop
up mid-stream are already skipped by the per-copy advance, so this only
needs to run once during setup.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
While GUP pinning makes it possible to pin the page _backing_ a user
address, it *doesn't* pin the page table entry (PTE) for that mapping. This
means the pinned physical page can be separated from the user address it
was backing, and even back a _different_ user address within the same
process. PTE zapping naturally happens during memory reclaim when memory
pressure is elevated, and can even be done directly by userspace via
madvise(MADV_DONTNEED).

Since the optimized per-CPU DRBG loop assumes copy_to_user_nofault() will
always succeed on a GUP-pinned page, it immediately bails out when the
nofault copy actually *does* fail for the reasons described above. This
results in either fewer than requested random bytes copied or, more
seriously, a spurious EFAULT returned to userspace when no random bytes
were copied.

As it turns out, there's no way to pin a PTE. That means it's not possible
to guarantee a 100% success rate for the copy_to_user_nofault() attempt.

Fix this by handling copy_to_user_nofault() errors correctly with a fall
back to a faultable copy attempt outside of the RNG lock. In order to
guarantee forward progress for the caller, an on-stack bounce buffer is
used to copy up to 256 bytes of the generated random bytes whenever this
happens rather than discarding the whole thing.

There's no need to use GUP pinning anymore since there's no use for having
a page pinned without pinning a PTE to go along with that page, hence the
page pinning is eliminated which saves a software page table walk that was
performed for _at least_ every destination page.

Reported-by: Kun Yi <kunyi@google.com>
Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
This reverts commit ef467f3.

This helper is no longer used by the FIPS-mode RNG, which was the
motivation for reintroducing it. Remove it.

Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
local_unlock() is supposed to take a percpu pointer, which it then offsets
for the current CPU. The problem is that the per-CPU DRBG code passes
local_unlock() a pointer that has *already been offset for the current
CPU*, so the percpu offset gets added twice. `pcri` is the percpu pointer
and `cri` is the offset `pcri` pointer for the current CPU; passing `cri`
to local_unlock() results in the current CPU's offset getting added again
and thus the resulting pointer is garbage.

This went unnoticed at runtime because local_unlock() only dereferences
that pointer on PREEMPT_RT or CONFIG_DEBUG_LOCK_ALLOC=y kernels. The
pointer is never actually used otherwise.

This also went unnoticed at compile time because, for x86_64, __percpu only
expands to something on GCC 14+; __percpu is otherwise an empty macro. So
there's no pointer type mismatch detected at compile time on older GCC
versions. On GCC 14+, the following compile error occurs:

  ../crypto/rng.c: In function 'lock_default_rng':
  ../include/linux/percpu-defs.h:221:45: error: initialization from pointer to non-enclosed address space

Fix it by using __local_unlock() instead, which eliminates the duplicate
per-CPU offset addition. While using local_unlock() with `pcri` also works,
using `cri` with __local_unlock() is leaner because it doesn't need to redo
the offset addition, saving an instruction on kernels that actually use the
pointer.

Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
CONFIG_CRYPTO_FIPS_VERSION="ciq.6.12.20260826"

Requested by lab.

Signed-off-by: Jeremy Allison <jallison@ciq.com>
…E_128.

CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=512
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=256

Requested by lab.

Signed-off-by: Jeremy Allison <jallison@ciq.com>
@ciq-kernel-automation ciq-kernel-automation Bot changed the title [rlc-10/6.12.0-211.47.1.el10_2] Multiple patches tested (13 commits) [rlc-10/6.12.0-211.47.1.el10_2] Multiple patches tested (26 commits) Aug 27, 2026
@PlaidCat
PlaidCat requested a review from a team August 27, 2026 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

created-by-kernelci Tag PRs that were automatically created when a user branch was pushed to the repo (kernelCI)

Development

Successfully merging this pull request may close these issues.

4 participants