| Age | Commit message (Collapse) | Author |
|
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs keyring updates from Christian Brauner:
"The kernel has two keyrings that userspace fills with X.509
certificates at boot: .fs-verity for fs-verity built-in signatures
and .dm-verity for dm-verity root hash signatures.
Neither is linked into any process keyring. Hence, request_key() and
KEYCTL_SEARCH can't find them. The only way for userspace to identify
them is to read their serial number out of /proc/keys. That is not
just a large file often the names can also be reused and appear
multiple times which allows forging these keyrings.
This adds two fixed special key ids, KEY_SPEC_DM_VERITY_KEYRING and
KEY_SPEC_FS_VERITY_KEYRING next to KEY_SPEC_BPF_KEYRING. The latter
went in through bpf-next this merge window.
lookup_user_key() resolves the fixed key ids to the two keyrings. So
userspace can add a dm-verity (fixed keyring id: -10) certificate with
keyctl padd asymmetric "" -10 < cert.der
and seal the keyring with
keyctl restrict_keyring -10
without looking anything up first"
* tag 'vfs-7.4-rc1.keyring' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
Documentation: keys: document IDs added since KEY_SPEC_REQKEY_AUTH_KEY
keys: add KEY_SPEC_FS_VERITY_KEYRING
keys: add KEY_SPEC_DM_VERITY_KEYRING
|
|
git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
Pull bpf updates from Alexei Starovoitov:
"Major changes:
- Introduce scalar evolution (SCEV) analysis in the verifier.
It infers how registers and stack slots change in a loop and lets
the verifier check bounded loops with induction variables as ranges
instead of walking every iteration. The number of processed insns
drops ten fold in programs with loops (Eduard Zingerman)
- Add 'callx' instruction: indirect call of a static BPF subprogram.
The address is taken with ld_imm64 or loaded from read-only data.
Supported by x86-64, arm64 and riscv64 JITs (Alexei Starovoitov, Pu
Lehui)
- Add unwind_goto and unwind_exit instructions, so that Rust panic or
C++ exception can run destructors of every frame it passes through.
The normal path is free of unwind code. Supported by x86-64 and
arm64 JITs (Alexei Starovoitov)
- Support programs compiled by rust-bpf: treat load and store through
a number as arena access with BPF_F_ARENA_SCALAR, accept rust names
in BTF (Alexei Starovoitov)
- Raise BPF program stack size from 512 bytes to 2 KiB on x86-64 and
arm64 (Kumar Kartikeya Dwivedi)
- Support struct, union and __int128 up to 16 bytes passed and
returned by value in BPF subprograms and kfuncs, and fix x86-64 and
arm64 trampolines for such arguments (Yonghong Song)
- Introduce a common way to attach struct_ops to a cgroup via
bpf_link. bpf_tcp_ops is the first user and mirrors TCP sock_ops
callbacks (Martin KaFai Lau, Amery Hung)
- Describe inlined functions in BTF. New kinds tell where the inline
sites are and how to fetch the arguments there.
CONFIG_DEBUG_INFO_BTF_INLINE keeps it apart from the main BTF in
.BTF.inline section or in btf_vmlinux_inline.ko (Alan Maguire)
- Fix many memory safety, lifetime and locking bugs in BPF core,
verifier, iterators, local storage, dynptr, devmap, cpumap and
seg6local (Josef Bacik, Alexei Starovoitov)
- Diff stat is dominated by selftests and by removal of
lib/test_bpf.c. Its 16k lines of instruction tests were converted
to BPF selftests that BPF CI runs on every architecture it covers
(Daniel Borkmann)
Other features and fixes:
- Add KASAN checks to memory accesses of JITed programs on x86-64
(Alexis Lothoré)
- Complete unification of helper, kfunc and subprog argument checks
in the verifier (Amery Hung)
- Add bpf_copy_from_user_mm[_str]() kfuncs (Anastasios Papagiannis)
- Various features and fixes (Daniel Borkmann):
- Add .bpf keyring for program signature verification, modelled
after dm-verity keyring, and support ML-DSA in signing tools
- Emit shorter and faster code in x86-64 JIT for patterns that
LLVM generates
- Fix various issues in gotox handling
- Let BPF LSM set xattrs at inode creation with bpf_inode_init_xattr()
(David Windsor, Daniel Borkmann)
- Use sleepable page allocation in sleepable arena paths. Fix races
between arena free, allocation and user page fault (Emil Tsalapatis)
- Switch BPF crypto from lskcipher to AES-CBC and AES-ECB libraries
(Eric Biggers)
- Add bpf_proactive_reclaim() kfunc (Hui Zhu)
- Render decl_tags in libbpf btf_dump and add tests for bpftool C
dump (Ihor Solodrai)
- Speed up tracing_multi attach on x86 (Jiri Olsa)
- Various features and fixes (Kumar Kartikeya Dwivedi):
- Add BPF_PROG_STREAM_OPEN command to read BPF streams through a
file descriptor with poll support
- Let kernel structs publish arena pointers with __arena type tag
- Fix __uninit kfunc output buffers and fastcall rewrite with
indirect stack accesses
- Refuse CO-RE relocations for signed programs
- Add enqueue_rcvq and dequeue_rcvq hooks to bpf_tcp_ops to adjust
sk_rcvlowat and avoid unnecessary wakeups (Kuniyuki Iwashima)
- Add bpf_ksock_sendto() kfunc and allow ksock connect and send from
bpf_wq (Mahe Tardy)
- Fix racy plt target update in arm64 bpf_arch_text_poke()
(Matthew Wood)
- Restructure BPF selftests Makefile as a layered build
(Mykola Lysenko)
- Speed up hash map lookups for u32 and u64 keys (Mykyta Yatsenko)
- Add signed div/mod, movsx, bswap and gotol to MIPS JITs, signed
div/mod to parisc JITs (Nicholas Dudar, Johan Almbladh)
- Fix stack overflow in build ID parser on 32-bit (Nickolai
Zeldovich)
- Add stack arguments, signed arena loads and gotox to riscv64 JIT.
Pu Lehui is now co-maintainer of riscv BPF JITs (Pu Lehui, Chen
Pei, Feng Jiang)
- Add bpf_call_rcu() and bpf_call_rcu_tasks_trace() kfuncs. Support
fetching and/or/xor atomics in arena on x86-64 (Puranjay Mohan)
- Fix flaky selftests, selftests with clang 23 and bpf-gcc
(Qiliang Yuan, KaFai Wan, Vineet Gupta)
- Fix builds broken by fatal resolve_btfids warnings, BTF generation
on ARC, and define arch_cmpxchg_local() on arc, hexagon and
openrisc (Sasha Levin)
- Reduce memory use of hash maps by up to 50% per element
(T.J. Mercier)
- Mark pointer fields of sched_ext ops arguments as trusted (Tejun
Heo)
- Remove legacy bpf_asm, bpf_dbg and bpf_jit_disasm tools (Xia Yan)
- Fix index overflow in queue and stack maps, arena range tree after
allocation failure, tail call loop after freplace detach, lost
signal in bpf_send_signal() (Yuan Chen)
- Many more fixes and cleanups"
* tag 'bpf-next-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next: (660 commits)
selftests/bpf: Time tc_edt from its first packet with data
selftests/bpf: Test unwind_exit of an exception callback
selftests/bpf: Tests for 32-bit scalar evolution bounds computation
bpf: Reject unwind_goto and unwind_exit in offloaded progs
bpf: Support 32-bit linear scalar evolution
bpf: Make unwind_exit of an exception callback exit in JITs
selftests/bpf: Test forbidden bpf_ksock_sendto() LSM attach
selftests/bpf: Test ksock sendto()
bpf: Add bpf_ksock_sendto() kfunc
selftests/bpf: Test unwinding from R0: R2 subprog
selftests/bpf: Add a C++ prog with exceptions
selftests/bpf: Add tests for unwind_goto and unwind_exit
bpf, arm64: Support unwind_goto and unwind_exit
bpf, x86: Support unwind_goto and unwind_exit
bpf: Add unwind_goto and unwind_exit insns
tools/bpf: Remove legacy BPF tools
bpf: Annotate data races on bpf_lru_node type
selftests/bpf: Add arena allocation race tests
bpf: Fix arena race between page free and alloc leading to incoherency
bpf: Revalidate faulted arena pages before installing user mappings
...
|
|
git://git.kernel.org/pub/scm/linux/kernel/git/modules/linux
Pull module updates from Petr Pavlu:
- Ignore local labels and mapping symbols during module load
These symbols were already ignored during kallsyms address-to-symbol
lookups. Filter them out earlier during module loading to reduce
lookup overhead and prevent them from appearing in /proc/kallsyms.
- Fix potentially incorrect access of SetOnce<T> when setting Rust
module parameters.
- Fix a potential read of an uninitialized count when printing taint
information for unloaded modules.
- Allocate the kmod argument array using kmalloc_array() in preparation
for conversion to type-aware allocators.
- Clean up includes in linux/kmod.h
Add explicit includes of linux/umh.h to files that use usermode
helpers. Then clean up the #include list in linux/kmod.h, notably
removing the compatibility linux/umh.h include.
- Remove the error-injection.h include from linux/module.h
Add explicit includes of linux/error-injection.h to files that use
the ALLOW_ERROR_INJECTION() macro and currently rely on it being
provided indirectly via linux/module.h. Then remove the unnecessary
linux/error-injection.h include from linux/module.h.
- Replace __MODULE_STRING() with __stringify() in various drivers in
preparation for removing the former macro.
* tag 'modules-7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/modules/linux:
drivers: Replace __MODULE_STRING() with __stringify()
module: Fix uninitialized count read of unloaded taint tracking record
rust: module_param: Fix potentially incorrect access of `SetOnce<T>`
module: Remove the error-injection.h include from linux/module.h
drm/xe: Include error-injection.h for ALLOW_ERROR_INJECTION()
drm/i915: Include error-injection.h for ALLOW_ERROR_INJECTION()
syscalls: Include error-injection.h for ALLOW_ERROR_INJECTION()
net: Include error-injection.h for ALLOW_ERROR_INJECTION()
block: Include error-injection.h for ALLOW_ERROR_INJECTION()
module: Bring includes in linux/kmod.h up to date
time/jiffies: Include linux/sysctl.h for proc_int_u2k_conv_uop(), ...
umh, treewide: Explicitly include linux/umh.h where needed
modules/kmod: Allocate argv with kmalloc_array()
module/kallsyms: Ignore local labels and mapping symbols during module load
module/kallsyms: Refactor current symbol filtering into is_core_symbol()
module/kallsyms: Rename is_mapping_symbol() to is_ignored_kernel_symbol()
|
|
git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd
Pull keys updates from Jarkko Sakkinen:
"Highlight:
- Don't leak local kernel addresses (and complement the ongoing
rhashtable migration) (Kyle Zeng)
The index value for the associative array has been calculated with
the following formula:
mult_64x32_and_fold(description + type address + domain address)
By creating a sequence of dummy keys (e.g., "A", "B", "C", ...), it
is trivial to form a group of equations with a predictable hash
function, and ultimately break KASLR.
Kyle's solution is based on an ephemeral SipHash key and an atomic
64-bit counter, which is encapsulated to a key_index_id(). This
function is then used to assign identifiers for types and domains,
and since the IDs are unique for each power on, they are as unique
as memory addresses are.
With these ingredients the index value calculation can be changed
into form, which is not leaking any kernel addresses:
SipHash(description + type id + domain id)
Features and improvements:
- TPM fields were moved from trusted_key_options to the TPM backend.
They cost memory for non-TPM backends.
- A TPM trusted key now caches tpm_is_tpm2() at the root of each call
chain, and passes the result as a parameter. This decreases the
amount of I/O traffic given that tpm_is_tpm2() starts and stops the
chip via tpm_try_get_ops() and tpm_put_ops().
Bugfixes:
- A TPM trusted key corrupted the return value of a failed key
unsealing operation if the pcrlock feature was used.
- A TPM 2 trusted key allocated an off-by-four too large buffer for
the decoded ASN.1 blob coming from keyctl add trusted.
- Sometimes a TPM 2 trusted key rejected created keys based on the
TPM2_Create response size, treating them as too large. Now it
correctly checks the extracted TPM2 key blob size.
- The keyctl reject operation raced with keyctl restrict_keyring
because keyring->sem was not held in key_reject_and_link() before
accessing keyring->restrict_link.
- keyctl_describe_key() was not holding key->sem while accessing its
fields, which can lead to use-after-free of a retired key type.
- find_keyring_by_name() and procfs code were reading the UID from
key->user->uid instead of key->uid. The latter is the cached value
and is meant to protect against a use-after-free caused by keyctl
chown.
- search_process_keyrings_rcu() did not properly RCU-dereference the
authorization key payload, which could cause a null dereference if
the payload was revoked.
- keyctl_read_key() checked key->type->read without holding key->sem,
which can lead to use-after-free if the type is retired. Based on
my suggestion, this was addressed in __keyctl_read_key(), which
already did take key->sem"
* tag 'keys-v7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
keys/trusted_keys: reuse TPM version in option handling
security: keys: Fix comment of search_process_keyrings_rcu()
keys/trusted/tpm2: Validate TPM2_Create object sizes separately
keys/trusted_keys: move TPM-specific fields into struct trusted_key_tpm
keys: Protect the read method check against type removal
keys: Avoid owner account dereferences in /proc/keys
keys: make keyring indexes independent of kernel addresses
keys: Check the authorization payload in process keyring searches
keys: Avoid the owner account dereference in named keyring lookup
keys: Protect the type name while describing a key
KEYS: Fix key_reject_and_link() race with keyring restriction
KEYS: trusted: Fix blob allocation size in tpm2_key_decode()
keys/trusted_keys: return immediately after TPM unseal failure
|
|
git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux
Pull crypto library updates from Eric Biggers:
- Migrate the x86 and riscv optimized implementations of various AES
modes (ECB, CBC, CBC-CTS, CTR, XCTR, XTS) into lib/crypto/.
This makes the library APIs be properly accelerated on these
architectures, while still accelerating crypto_skcipher as well.
It removes a lot of redundant glue code, since the crypto API
boilerplate no longer needs to be duplicated for these architectures.
It also fixes the longstanding issue where optimizations for these
AES modes were disabled by default on these architectures.
- Optimize AES-XTS on SPARC64 using the SPARC crypto opcodes
- Move the SipHash code into lib/crypto/
- Update the ChaCha and Poly1305 functions to take size_t lengths,
resolving issues where lengths over INT_MAX were mishandled
- Make frame pointer unwinding work properly in some of the x86
assembly functions, by following the standard %rbp convention
- Add helper functions for zeroizing structs
- Make a few documentation improvements
* tag 'libcrypto-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux: (49 commits)
lib/crypto: md5: remove unused header
lib/crypto: mips/chacha: Handle lengths of 2 GiB or more
lib/crypto: arm/chacha: Handle lengths of 2 GiB or more in scalar code
lib/crypto: chacha: Use size_t length
lib/crypto: poly1305: Use size_t length
lib/crypto: x86/sha512: Follow the normal %rbp convention
lib/crypto: x86/sha256: Follow the normal %rbp convention
lib/crypto: x86/sha1: Follow the normal %rbp convention
lib/crypto: chacha20poly1305: zeroize state in __chacha20poly1305_decrypt
lib/crypto: sparc/aes-xts: Add optimization using the AES opcodes
lib: Move SipHash into lib/crypto/
lib/crypto: x86/aes-ctr: Remove some unreachable code
crypto: x86/aesni-intel - Add transitional selections
crypto: aes - Boost priority of encryption modes further
lib/crypto: x86/aes: Set RNDKEY in aes_cbc_encrypt_aesni()
lib/crypto: riscv/aes-xts: Migrate optimized code into library
lib/crypto: riscv/aes-ctr: Migrate optimized code into library
lib/crypto: riscv/aes-cbc: Migrate optimized code into library
lib/crypto: riscv/aes-ecb: Migrate optimized code into library
lib/crypto: riscv/aes: Pass key struct to assembly code
...
|
|
Determine the TPM version once in the seal and unseal paths, and reuse
it when allocating and parsing trusted key options.
This reduces the number of fallible calls to tpm_is_tpm2() and avoids
unnecessary I/O between the kernel and the TPM.
Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20261005062732.140733-1-ssrish@linux.ibm.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
search_my_process_keyrings() has been renamed to search_cred_keyrings_rcu()
in commit e59428f721ee ("keys: Move the RCU locks outwards from the keyring
search functions"), but one spot has been missed in a comment.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Jinjie Ruan <ruanjinjie@huawei.com>
Link: https://lore.kernel.org/r/20260928072024.91664-1-thuth@redhat.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
TPM2_Create returns outPrivate, outPublic, creationData, creationHash and
creationTicket in its response parameter area. However, only outPrivate and
outPublic are included in the trusted key blob. The size of the blob is
therefore not determined by the size of the complete response parameter
area.
tpm2_seal_trusted() currently compares the size of the complete response
parameter area against MAX_BLOB_SIZE. This can reject a valid response
when the remaining response outputs cause the entire response parameter
area to exceed MAX_BLOB_SIZE, even though the outPrivate and outPublic
TPM2B structures consumed by tpm2_key_encode() remain small enough to be
encoded in the key blob.
This is observed when creating larger trusted keys using the swtpm TPM 2.0
emulator backed by libtpms.
For example, requesting a 113-byte key succeeds, 114 fails.
~$ keyctl add trusted trusted_key1 "new 113 keyhandle=0x81000001" @u
520504613
~$ keyctl add trusted trusted_key2 "new 114 keyhandle=0x81000001" @u
add_key: Argument list too long
~$
Remove the MAX_BLOB_SIZE check on the complete response parameter area.
Instead, use the response length passed to tpm2_key_encode() to validate
that the outPrivate and outPublic TPM2B structures are fully contained
in the response before accessing them.
Previously, a response parameter area larger than MAX_BLOB_SIZE was
rejected with -E2BIG before ASN.1 encoding. With this change, if the
resulting encoded blob does not fit in payload->blob, the error returned by
asn1_encode_sequence() is propagated instead.
Also, use scope-based cleanup to simplify resource management.
Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
Link: https://lore.kernel.org/r/20260926184203.479203-1-ssrish@linux.ibm.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
The trusted_key_options struct contains TPM-specific fields (keyhandle,
keyauth, blobauth_len, blobauth, pcrinfo_len, pcrinfo, pcrlock, hash,
policydigest_len, policydigest, and policyhandle). This leads to the
accumulation of backend-specific fields in the generic options structure.
Define struct trusted_key_tpm and move the TPM-specific fields there. Store
a pointer to it in the private member of struct trusted_key_options.
Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260912062950.279104-3-ssrish@linux.ibm.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
keyctl_read_key() checks key->type->read without holding key->sem.
A reference keeps the key alive, but does not pin the module containing
its type. A surviving RxRPC key can therefore be read while AF_RXRPC
is being unloaded:
KEYCTL_READ task Module unload and key GC
---------------- ------------------------
lookup_user_key()
permission / possession checks
load key->type
af_rxrpc_exit()
unregister_key_type()
GC: down_write(key->sem)
GC: retype to key_type_dead
GC: up_write(key->sem)
unregister_key_type() returns
free_module()
read saved type's read member
The final access can read freed module storage. The read invocation in
__keyctl_read_key() is already protected by key->sem, but the earlier
method check is outside that critical section.
Move the method check into __keyctl_read_key(), after key_validate() and
under its existing read hold on key->sem. The check and invocation then
use the same protected type for length queries and every read retry.
The GC cannot retype the key until the semaphore is released, and type
unregistration waits for that GC pass before the module can be freed.
Return -EOPNOTSUPP when validation succeeds and the type has no read
method. A temporary buffer may now be allocated before this result;
allocation and copying to userspace remain outside the semaphore.
Assisted-by: LLM
Cc: stable@vger.kernel.org # v5.10+
Fixes: d3ec10aa9581 ("KEYS: Don't write out to userspace while holding key semaphore")
Suggested-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Reviewed-by: David Howells <dhowells@redhat.com>
Link: https://lore.kernel.org/r/pm-key-management-objects-candidate-0010-v7-fc85721ff5cfb9e33ac6@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
The namespace filters in find_ge_key() and key_serial_next() read
key->user->uid while traversing the serial tree under key_serial_lock.
That lock keeps the key allocated, but it does not protect the separate
key_user from ownership changes.
A /proc/keys read reaches find_ge_key() through proc_keys_start(), and
key_serial_next() through proc_keys_next(). The lock stays held until
proc_keys_stop().
A successful privileged KEYCTL_CHOWN on the same key replaces key->user
under key->sem and drops the old owner's reference after releasing the
semaphore. If that was the old dynamic key_user's last reference, a
/proc/keys reader can access freed memory:
/proc/keys reader KEYCTL_CHOWN
proc_keys_start() keyctl_chown_key()
spin_lock(key_serial_lock) down_write(key->sem)
find_ge_key()
old = minkey->user
zapowner = key->user
key->user = newowner
key->uid = uid
up_write(key->sem)
key_put(key)
key_user_put(zapowner)
kfree(zapowner)
read old->uid -> use-after-free
proc_keys_stop()
spin_unlock(key_serial_lock)
Use the inline key->uid in both filters, following the approach already
used by find_keyring_by_name(). The serial-tree lock keeps the containing
key alive, so filtering no longer depends on the quota owner's lifetime.
This also uses the same owner UID as proc_keys_show() and the permission
check.
For thread keyrings, key_fsuid_changed() can update key->uid without
changing the quota owner. The filters now follow that current owner UID,
including when its namespace mapping differs from the quota owner's.
Fixes: 454804ab0302 ("keys: make procfiles per-user-namespace")
Assisted-by: LLM
Suggested-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/pm-keys-proc-owner-uid-followup-20261017-v2-8f8f34a41eb1bbb94ef0@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
KEYCTL_READ returns the serial numbers in a keyring in associative-array
traversal order. The first word of the index is a public, deterministic
hash of the type pointer, domain pointer and description. An unprivileged
user can therefore insert keys with known descriptions, predict their
order for each possible KASLR slide, and recover the kernel image address.
On an x86-64 build with 16 MiB alignment, 45 user keys suffice to
distinguish the candidate slides.
Remove the addresses from the whole index, not just its first hash word.
Assign each key type and domain a nonzero 64-bit ID and hash those IDs and
the description with a once-initialized SipHash key. Use the full IDs in
the later index chunks as well. Truncating or hashing the IDs there would
lose the guarantee that distinct type/domain/description tuples have a
differing index bit.
Allocate IDs lazily since private key types need not be registered. Cache
them in the index key so tree walks and copies of an existing index do not
need to dereference a type descriptor that may have been unregistered.
Keep the 32-bit chunk layout and diff_objects() bit offsets consistent,
and retain the separate root slot for keyrings used by recursive search.
The key comparison, permissions and userspace data format are unchanged;
only the address-dependent in-memory ordering is replaced.
Cc: stable@vger.kernel.org
Fixes: b2a4df200d57 ("KEYS: Expand the capacity of a keyring")
Assisted-by: Codex:gpt-6-astra
Signed-off-by: Kyle Zeng <kylebot@openai.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20261013231251.56170-1-kylebot@openai.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
An authorization payload and its saved credentials must remain valid
while search_process_keyrings_rcu() searches the requestor's keyrings.
The function validates the authorization key, then separately loads
payload.data[0] and unconditionally reads rka->cred. Validation does
not prevent request_key_auth_revoke() from clearing the payload.
A request-key helper can assume authority and fork a descendant that
inherits the authorization key. If the descendant misses in its own
keyrings, it falls back to the saved requestor credentials. Successful
target instantiation invalidates the authorization key without clearing
the payload. After the helper exits, UMH_WAIT_PROC returns to the
requester, which calls complete_request_key() and revokes that key.
With the descendant paused after validation, the paths can interleave
as follows:
1. The descendant enters search_process_keyrings_rcu() under RCU and
key_validate() succeeds.
2. The helper instantiates the target, invalidates the authorization
key, and exits.
3. The requester resumes from UMH_WAIT_PROC, calls
complete_request_key(), and revokes the authorization key.
request_key_auth_revoke() sets its payload pointer to NULL.
4. The descendant loads NULL and dereferences rka->cred.
This NULL dereference can oops the kernel. RCU delays payload disposal
but does not prevent the pointer from being cleared.
Load the payload with dereference_key_rcu() and require a non-NULL
result before validating the authorization key and searching its saved
credentials. A non-NULL payload and its credentials remain alive for
the caller's RCU read-side section; a cleared payload skips the fallback
search and follows the existing error selection.
KASAN report as below:
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000005: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f]
RIP: 0010:search_process_keyrings_rcu+0x32b/0x790
Cc: stable@vger.kernel.org
Fixes: e59428f721ee ("keys: Move the RCU locks outwards from the keyring search functions")
Assisted-by: LLM
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/pm-key-management-objects-candidate-0004-v3-598361863b76bc25d58d@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Named keyring lookup must keep the storage containing the owner UID
alive through the namespace mapping check. find_keyring_by_name()
reads keyring->user->uid under keyring_name_lock, but that lock protects
the keyring's name entry and allocation, not its separate key_user.
A named session-keyring join can overlap a privileged KEYCTL_CHOWN on
another CPU. If the keyring holds the last reference to its old dynamic
key_user and the ownership transfer succeeds, the following ordering is
possible:
Named join Chown
find_keyring_by_name() keyctl_chown_key()
read_lock(keyring_name_lock) down_write(key->sem)
load old keyring->user
replace key->user and key->uid
up_write(key->sem)
key_put(key)
key_user_put(old user): free
read old user->uid
read_unlock(keyring_name_lock)
Chown neither takes keyring_name_lock nor key_session_mutex, so it can
free the old account between the pointer load and the UID read. The
lookup then reads freed memory even though the keyring itself is alive.
Use keyring->uid for the mapping check. key_alloc() initializes this
inline owner UID and keyctl_chown_key() updates it on chown.
The existing name lock keeps its containing keyring allocated throughout
the check, so lookup no longer depends on the account's lifetime. This
also matches the owner UID used by the permission check.
KASAN report as below:
BUG: KASAN: slab-use-after-free in find_keyring_by_name+0x577/0x5d0
Read of size 4 at addr ffff8881128ae2ec by task keycase/500
Cc: stable@vger.kernel.org
Fixes: 2ea190d0a006 ("keys: skip keys from another user namespace")
Assisted-by: LLM
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/pm-key-management-objects-candidate-0002-v3-2baa8cad2bb554364e10@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
keyctl_describe_key() must keep the key type's name alive until
kasprintf() has consumed it. The retained key reference keeps the key
and its description alive, but does not pin the module providing its
type. The name is passed to kasprintf() without holding key->sem.
kvasprintf() uses the saved name pointer in two formatting passes, with
a GFP_KERNEL allocation between them. With AF_RXRPC=m, a task that
passes View permission before type retirement can overlap a privileged
module unload in this order:
1. KEYCTL_DESCRIBE looks up the key, saves key->type->name in the
kasprintf() arguments and completes the first formatting pass.
2. While the formatter is delayed before its second pass,
af_rxrpc_exit() calls unregister_key_type(), which removes the type
from the registry and waits for key_gc_keytype().
3. The collector takes key->sem for writing, retypes the retained key
to key_type_dead and completes retirement. Unregistration and module
exit return, allowing free_module() to release the type and name.
4. The formatter resumes its second pass and reads the saved name from
released module storage, which can fault in string().
Hold key->sem for reading across kasprintf(). The collector then cannot
retype the key or complete retirement until both formatting passes have
finished. If retirement wins the lock first, formatting uses the core
key_type_dead name instead. Release the semaphore immediately after
kasprintf(), including on allocation failure, before copying to
userspace.
Oops report as below:
BUG: unable to handle page fault for address: fffffbfff8054794
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
RIP: 0010:string+0x23f/0x470
Call Trace:
vsnprintf+0x330/0x1110
Cc: stable@vger.kernel.org
Fixes: aa9d4437893f ("KEYS: Fix the size of the key description passed to/from userspace")
Assisted-by: LLM
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/pm-key-management-objects-candidate-0009-v4-6b537c5732fd957c33fa@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
The restrict_link check in key_reject_and_link() is done before taking
the keyring semaphore, racing with a concurrent keyring_restrict()
that installs the restriction while holding the semaphore in write
mode.
Move the check to after __key_link_lock(), so it is done under the
semaphore, matching the pattern used in __key_create_or_update().
Cc: stable@vger.kernel.org
Fixes: 5ac7eace2d00 ("KEYS: Add a facility to restrict new links into a keyring")
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Adrian Martinez <adrimg3196@gmail.com>
Link: https://lore.kernel.org/r/CACO1+RT+m==BY+ZPkE+fo536D0qu3wog4xE1dfuXQ56g+=Qv=A@mail.gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
tpm2_key_decode() allocates 4 bytes more than needed. The ASN.1
callbacks tpm2_key_priv() and tpm2_key_pub() provide the lengths
of TPM2B_PRIVATE and TPM2B_PUBLIC, so ctx.priv_len and ctx.pub_len
already account for the 2-byte `size` field each of those structures
starts with.
I noticed this while reviewing commit 114f00d738f1 ("KEYS: trusted:
Fix tpm2_load_cmd() boundary check"), which correctly reports
ctx.priv_len + ctx.pub_len as the decoded blob size [1].
Let's allocate exactly that amount, matching the data copied into
the blob.
[1] https://lore.kernel.org/linux-integrity/apfoKo-BdwaLXtkT@sgarzare-redhat/
Cc: stable@vger.kernel.org # v5.13+
Fixes: f2219745250f ("security: keys: trusted: use ASN.1 TPM2 key format for the blobs")
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Link: https://lore.kernel.org/r/20260923173506.41519-1-sgarzare@redhat.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
trusted_tpm_unseal() proceeds to pcrlock() when the TPM unseal operation
fails. If pcrlock() succeeds, its return value overwrites the unseal error,
causing key instantiation to succeed.
Return immediately when unseal fails to preserve the original error.
Cc: stable@vger.kernel.org # v5.15+
Fixes: 5d0682be3189 ("KEYS: trusted: Add generic trusted keys framework")
Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260912062950.279104-2-ssrish@linux.ibm.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Same problem as the dm-verity keyring: .fs-verity is allocated unlinked,
so the only way for userspace to name it is to scrape /proc/keys.
Suggested-by: Christian Brauner (Amutable) <brauner@kernel.org>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Reviewed-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Andrew Halaney <andrew@amutable.com>
Link: https://patch.msgid.link/20261008-ajhalaney-dmverity-key-identifier-v2-2-008456d189cb@amutable.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
The .dm-verity keyring is not linked into any process keyring, so
request_key() and KEYCTL_SEARCH cannot find it. Userspace has to scrape
/proc/keys for the serial to use.
That's not great, one could put in a bogus description containing
a newline to confuse userspace further. For example, thanks to AI
models, which I run as root but you could show off as any old user:
# DESC=$'.dm-verity: 1\n0badf00d I--Q--- 1 perm 082f0000 0 0 keyring .dm-verity'
# k=$(echo -n "1234567" | keyctl padd user "$DESC" @s)
# keyctl setperm "$k" 0x3f010001
# cat /proc/keys | grep dm-verity
10402023 I------ 2 perm 082f0000 0 0 keyring .dm-verity: empty
12e0bee6 I--Q--- 1 perm 3f010001 0 0 user .dm-verity: 1
0badf00d I--Q--- 1 perm 082f0000 0 0 keyring .dm-verity: 7
0x0badf00d is not a keyring, it is the text inside our user's key
description. Telling the two apart needs a KEYCTL_DESCRIBE per row
which is annoying to do. i.e.:
# keyctl rdescribe 0x10402023
keyring;0;0;082f0000;.dm-verity
# keyctl rdescribe 0x0badf00d
keyctl_describe: Required key not available
Let's just give it a well known identifier, i.e.:
# keyctl rdescribe -10
keyring;0;0;082f0000;.dm-verity
This is exactly what
commit 264d8fd2794f ("bpf, keys: Add a bpf keyring for program signature validation")
did, and was the inspiration for this commit minus the spinlock bits
required due to dm-verity being a module.
Suggested-by: Christian Brauner (Amutable) <brauner@kernel.org>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Reviewed-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Andrew Halaney <andrew@amutable.com>
Link: https://patch.msgid.link/20261008-ajhalaney-dmverity-key-identifier-v2-1-008456d189cb@amutable.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
__key_create_or_update() snapshots keyring->restrict_link before taking
the destination keyring's semaphore. keyring_restrict() installs a
restriction while holding that semaphore.
This allows a writer to observe no restriction, wait for the keyring
owner to install a reject-all restriction and return successfully, and
then link a key using the stale NULL snapshot. The writer only needs
write permission on the destination keyring.
Move the restrict_link read after __key_link_lock() and
__key_link_begin(). The read and the subsequent restriction check are
then serialized with restriction installation by keyring->sem.
The race was reproduced on v7.2.8 in 19 executions where restriction
installation returned before the link completed. All 19 linked the key
despite the reject-all restriction. With this change, 312 executions
reached the same ordering and every add_key() call failed with -EPERM.
The issue was found by manual concurrency analysis assisted by AI-based
analysis and independently verified with a QEMU reproducer and kernel
instrumentation.
Fixes: 5ac7eace2d00 ("KEYS: Add a facility to restrict new links into a keyring")
Cc: stable@vger.kernel.org
Signed-off-by: 성병찬 <tjdqudcks0424@naver.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260930041802.6114-1-tjdqudcks0424@naver.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
When no keyring exists for the requested UID, KEYCTL_GET_PERSISTENT
creates and registers one before linking it to the requested destination.
The configured timeout is set only after the destination link succeeds.
A destination restricted with KEYCTL_RESTRICT_KEYRING makes that link fail
with -EPERM. With persistent_keyring_expiry set to 60 seconds, /proc/keys
still reports the registered keyring's expiry as "perm".
The failed call therefore leaves a quota-exempt keyring in the namespace's
hidden register, where it may remain until namespace teardown.
Rename the write-locked helper to key_get_or_create_persistent() and return
the key reference through a result parameter. Return 0 when it creates a
keyring and 1 when the retry finds an existing one. Return a negative error
on failure. Another caller may create the keyring between the initial
read-locked lookup and the retry under the write lock.
Set the timeout after permission checking and linking. Do this on success,
or on failure if the call allocated the keyring. This leaves a new keyring
collectible after failure without starting its timeout while linking is
still in progress.
Cc: stable@vger.kernel.org # v5.10+
Fixes: f36f8c75ae2e ("KEYS: Add per-user_namespace registers for persistent per-UID kerberos caches")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://lore.kernel.org/r/20260912095440.79864-1-kmehltretter@gmail.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Clear the hmac_sha1_ctx structure via __cleanup(hmac_sha1_zeroize_ctx)
to make sure that the function does not leak sensitive data on the stack
when returning without calling hmac_sha1_final().
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Link: https://patch.msgid.link/20260916095022.604354-10-thuth@redhat.com
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
|
|
Cross-merge BPF and other fixes after downstream PR.
Conflicts:
kernel/bpf/helpers.c
tools/testing/selftests/bpf/prog_tests/cb_refs.c
tools/testing/selftests/bpf/prog_tests/verifier.c
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
|
|
The usermode helper declarations were previously provided by linux/kmod.h
but commit c1f3fa2a4fde ("kmod: split off umh headers into its own file")
moved them to linux/umh.h in 2017.
Add explicit includes of linux/umh.h to files that use usermode helpers and
remove linux/kmod.h where it is no longer needed.
Acked-by: Alex Elder <elder@riscstar.com> # for greybus
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
|
|
encrypted_key_alloc() stores datablob_len in a u16. It is computed from
multiple string and payload lengths. If the result exceeds U16_MAX, the
assignment truncates the allocation size. KASAN reports a 32760-byte
slab-out-of-bounds write when __ekey_init() copies the master key
description into the undersized buffer.
The total payload length stored in key->datalen is also a u16. Use
check_add_overflow() to reject values that do not fit either destination,
and use kzalloc_flex() for the flexible-array allocation.
Fixes: 7e70cb497850 ("keys: add new key-type encrypted")
Cc: stable@vger.kernel.org
Assisted-by: GitHub-Copilot:claude-opus-4.6
Signed-off-by: Cen Zhang <cenzhang@linux.microsoft.com>
Signed-off-by: Francis Perron <francis@akrites.dev>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>
Link: https://lore.kernel.org/r/20260909153433.83117-1-cenzhang@linux.microsoft.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
tpm2_load_cmd() does boundary checks against the ASN.1 size i.e.,
payload->blob_len. Address this by passing the decoded blob size to
tpm2_load_cmd(), and use it for the boundary checks.
Cc: stable@vger.kernel.org # v5.13+
Fixes: f2219745250f ("security: keys: trusted: use ASN.1 TPM2 key format for the blobs")
Reported-by: co+6a581c4284f721d4@bugs.sh
Closes: https://bugs.sh/b/6a581c4284f721d4/
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Tested-by: Srish Srinivasan <ssrish@linux.ibm.com>
Link: https://lore.kernel.org/r/20260901205809.2028454-1-jarkko@kernel.org
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
request_key_auth_describe() prints rka->pid into /proc/keys as a raw
pid_t in the initial pid namespace. A reader can open /proc/keys through
a mount in another pid namespace. That reader sees a number with no
meaning there. The number can even name an unrelated task. The line
needs VIEW on the key. So the reader either shares the key owner's uid
or possesses the key.
The fix keeps a struct pid. Commit 4f82f45730c6 ("net ip6 flowlabel:
Make owner a union of struct pid * and kuid_t") gave
/proc/net/ip6_flowlabel the same storage. The print goes through
pid_nr_ns(). It renders against the pid namespace of the procfs instance
the line is read through. Commit ad08978ab41c ("ipv6/flowlabel: simplify
pid namespace lookup") moved that print to the same anchor. Output
through an initial namespace /proc does not change. The line shows 0 for
a requestor with no number in that namespace.
Translating at read time was the alternative. find_pid_ns() can resolve
a recycled number. The line would then name a live task with no
connection to the key. A stored struct pid gives 0 instead when the
requestor has no number there.
Link: https://lore.kernel.org/keyrings/20260809110202.2180410-1-maoyixie.tju@gmail.com/
Fixes: 78b7280cce23 ("KEYS: Improve /proc/keys")
Cc: stable@vger.kernel.org # v5.10+
Assisted-by: Claude:claude-opus-5 codeql
Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
Link: https://lore.kernel.org/r/20260821095935.1864998-1-maoyixie.tju@gmail.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
clear_bit() is atomic with respect to the word it modifies, but it is
an unordered operation: it implies no memory barrier on either side
(Documentation/atomic_bitops.txt).
key_garbage_collector() clears KEY_GC_REAPING_KEYTYPE with clear_bit()
and calls wake_up_bit() after reaping a dead key type. wake_up_bit()
uses a lockless waitqueue check and requires a full barrier after the
clear.
The existing smp_mb() is before clear_bit(), so nothing orders the clear
against that check. The GC can see an empty waitqueue while
unregister_key_type() still sees the bit set. The final wakeup is then
lost, leaving module unload stuck in wait_on_bit().
Use clear_and_wake_up_bit(). Its clear_bit_unlock() has RELEASE
semantics, so the completed GC work stays ordered before the clear, and
its smp_mb__after_atomic() orders the clear before the waitqueue check.
Fixes: 0c061b5707ab ("KEYS: Correctly destroy key payloads when their keytype is removed")
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://lore.kernel.org/r/20260821025327.61488-1-kmehltretter@gmail.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Cross-merge BPF and other fixes after downstream PR.
Conflicts:
kernel/bpf/backtrack.c
include/linux/bpf_verifier.h
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
|
|
BPF program signatures can currently be verified against one of the
system keyrings (builtin, secondary, platform) or against an arbitrary
user/session caller-supplied keyring named through keyring_id. There
is nothing in between: the system keyrings need a kernel rebuild or a
vouched-for enrollment to rotate a key, while a caller-supplied keyring
is fully controlled by the loader and therefore carries no trust on
its own (unless explicitly combined with BPF LSM to protect against
key tampering).
Add a dedicated bpf keyring to fill that gap, modelled after the
dm-verity keyring which was added in commit 033724b1c627 ("dm-verity:
add dm-verity keyring") and which can eventually be used also via
systemd [0] through the same enrollment method as in dm-verity's case.
It is selected with the new KEY_SPEC_BPF_KEYRING special key id and
gives an operator a place to enroll a BPF-only signing key at boot,
specifically scoped to BPF program loading and nothing else in the
kernel's trust hierarchy.
The id is reserved from the KEY_SPEC space so that the latter is not
linked into any process keyring, and lookup_user_key() resolves
KEY_SPEC_BPF_KEYRING constant instead of having to look it up via
/proc/keys first.
By default the keyring is sealed empty at init. Systems that want to
provision keys pass bpf.keyring_unsealed=1, which leaves the keyring
open for the initrd to add keys to. The keyring is only ever consulted
once it is both non-empty and restricted. An unrestricted keyring is
ignored.
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://github.com/systemd/systemd/pull/43549 [0]
Link: https://lore.kernel.org/r/20260828175227.1537793-2-daniel@iogearbox.net
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
|
|
Decouple kzalloc from buffer creation, so that a managed allocation can be
used:
struct tpm_buf *buf __free(kfree) buf = kzalloc(TPM_BUFSIZE,
GFP_KERNEL);
if (!buf)
return -ENOMEM;
tpm_buf_init(buf, TPM_BUFSIZE);
Alternatively, other allocations are also possible (static data, stack,
etc) for example:
u8 buf_data[512];
struct tpm_buf *buf = (struct tpm_buf *)buf_data;
tpm_buf_init(buf, sizeof(buf_data));
This is achieved by embedding buffer's header inside the allocated blob,
instead of having an outer wrapper.
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@opinsys.com>
Tested-by: Srish Srinivasan <ssrish@linux.ibm.com>
Message-ID: <20260522013555.1063716-1-jarkko@kernel.org>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
|
|
Merge TPM_BUF_BOUNDARY_ERROR and TPM_BUF_OVERFLOW flags into
the TPM_BUF_INVALID flag, as their behavior is identical (the only
difference being the associated log messages).
Message-ID: <20260125192526.782202-11-jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@opinsys.com>
Reviewed-by: Jonathan McDowell <noodles@meta.com>
Signed-off-by: Ross Philipson <ross.philipson@gmail.com>
|
|
Consolidate TPM1 constants in tpm_command.h and remove duplicate
constants from tpm1-cmd.c.
Co-developed-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Co-developed-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Ross Philipson <ross.philipson@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
trusted_tpm_exit() drops the TPM chip reference and frees the digest
array before unregistering the trusted key type. key_type_lookup()
holds key_types_sem for reading until the key operation finishes, while
unregister_key_type() takes it for writing. It therefore provides the
synchronization point that must precede backend teardown.
The current order permits this interleaving:
CPU 0 CPU 1
trusted_tpm_exit() key_type_lookup("trusted")
put_device(&chip->dev) trusted_tpm_seal()
kfree(digests) pcrlock()
unregister_key_type() tpm_pcr_extend(..., digests)
CPU 1 can consequently dereference the freed digest array. The chip can
also be released before callbacks stop using it.
KASAN reported:
BUG: KASAN: slab-use-after-free in tpm_pcr_extend+0x1f0/0x200
Read of size 2 at addr ffff88810872d000 by task poc/89
Call Trace:
tpm_pcr_extend+0x1f0/0x200
pcrlock+0x42/0x70 [trusted]
trusted_tpm_seal+0x1b6/0x570 [trusted]
trusted_instantiate+0x293/0x340 [trusted]
__key_instantiate_and_link+0xb2/0x2b0
__key_create_or_update+0x61e/0xb50
__do_sys_add_key+0x1b8/0x310
Allocated by task 88:
__kmalloc_noprof+0x1a7/0x490
do_one_initcall+0xa1/0x390
do_init_module+0x2df/0x840
Freed by task 90:
kfree+0x131/0x3c0
trusted_tpm_exit+0x59/0xa0 [trusted]
__do_sys_delete_module+0x346/0x510
Move unregister_key_type() before releasing either resource. This stops
new lookups and waits for in-flight key operations to finish before the
backend state is destroyed.
Fixes: 0b6cf6b97b7e ("tpm: pass an array of tpm_extend_digest structures to tpm_pcr_extend()")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Link: https://lore.kernel.org/r/20260731140925.2973492-1-nicoyip.dev@gmail.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
keyring_get_key_chunk() loads description bytes into the index chunk low
address first, while keyring_diff_objects() numbers the first differing
bit from the low end and folds the absolute byte index into the level
without removing the inline-prefix offset the level already carries.
The two disagree on byte order and bit position, so the array can be
told two keys first differ at a bit that does not differ in the chunk
the walker uses, letting crafted descriptions collide into one node.
Load the chunk in the order keyring_diff_objects() assumes and drop the
inline-prefix length when folding the byte index into the level. This
only changes the in-memory ordering used to place keys within a keyring;
add, search and read of non-colliding keys are unaffected.
Fixes: f771fde82051 ("keys: Simplify key description management")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260719161505.2423935-3-michael.bommarito@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
For description-level chunks keyring_get_key_chunk() advances the read
pointer by level * sizeof(long) past the inline prefix but only
bounds-checks the prefix, so a long enough key description is read past
its kmemdup(desc, desc_len + 1) allocation. Compute the full byte
offset and bounds-check the description against it before reading.
The walk only reaches a description-level chunk when two keys collide
through the hash, x, type and domain_tag chunks, so this is reached from
an unprivileged add_key(2) with a crafted pair of same-type keys whose
index hashes collide; KASAN reports a slab-out-of-bounds read.
Fixes: f771fde82051 ("keys: Simplify key description management")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260719161505.2423935-2-michael.bommarito@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Two correctness and type-hygiene issues exist in the DCP trusted keys
implementation.
First, trusted_dcp_unseal() reads p->key_len from a user-supplied blob
without checking if it exceeds MAX_KEY_SIZE. If a crafted blob provides a
payload_len larger than 128, the subsequent do_aead_crypto() call writes
past the end of the p->key array into the adjacent p->blob buffer within
the same struct trusted_key_payload -- the caller's own input, not
unrelated kernel memory. While not exploitable, this violates strict array
bounds and triggers static analyzers. Fix this by adding a validation
check against MIN_KEY_SIZE and MAX_KEY_SIZE immediately after reading the
length, matching the checks already done in trusted_core.c.
Second, calc_blob_len() calculates a sum in size_t that truncates to
unsigned int on 64-bit platforms. Because the DCP hardware is only present
on 32-bit i.MX SoC platforms, size_t and unsigned int are functionally
equivalent in production, making this truncation harmless in practice.
Nevertheless, updating the return type to size_t (and subsequently updating
'blen' in the seal/unseal paths) resolves type-narrowing warnings and
improves overall code hygiene.
Fixes: 2e8a0f40a39c ("KEYS: trusted: Introduce NXP DCP-backed trusted keys")
Signed-off-by: Fabrice Derepas <fabrice.derepas@canonical.com>
Reviewed-by: David Gstir <david@sigma-star.at>
Reviewed-by: Richard Weinberger <richard@nod.at>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260719163939.3624767-1-fabrice.derepas@canonical.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Replace two BUG() calls in keyctl_pkey_params_get_2() and
keyctl_pkey_e_d_s() default cases with -EOPNOTSUPP, matching
the error style already used in these functions.
Signed-off-by: Mohammed EL Kadiri <med08elkadiri@gmail.com>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Replace BUG() in construct_get_dest_keyring() default case
with return -EINVAL to handle the unimplemented group keyring
destination gracefully.
Signed-off-by: Mohammed EL Kadiri <med08elkadiri@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260613130408.13709-2-med08elkadiri@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
A: request_key() B: KEYCTL_INSTANTIATE_IOV
================ =========================
create auth key
store rka in auth key
wait for helper
get auth key
load rka from auth key
copy user payload
sleep on #PF
helper completed
detach and free rka
destroy auth key
wake up
use rka->target_key
**USE-AFTER-FREE**
Give request_key_auth payloads a refcount. Take a payload reference while
authkey->sem stabilizes the payload and revocation state. Hold that
reference across the instantiate and reject paths. Drop the auth key
owning reference from revoke and destroy.
[jarkko: Replaced the first two paragraphs of text with an actual
concurrency scenario.]
Cc: stable@vger.kernel.org # v5.10+
Fixes: b5f545c880a2 ("[PATCH] keys: Permit running process to instantiate keys")
Reported-by: Shaomin Chen <eeesssooo020@gmail.com>
Closes: https://lore.kernel.org/r/20260519144403.436694-1-eeesssooo020@gmail.com
Signed-off-by: Shaomin Chen <eeesssooo020@gmail.com>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Add SLAB_NO_MERGE to key_jar to prevent the allocator from merging it
with other similarly-sized caches. This hardens struct key isolation by
ensuring dedicated slab pages.
Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Signed-off-by: Mohammed EL Kadiri <med08elkadiri@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260610065052.9120-1-med08elkadiri@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
derived_buf is guaranteed to be HASH_SIZE - and it is more than enough.
The strscpy() degenerates into an memcpy() (as did the strcpy()).
Do the same for the associated "ENC_KEY" copy.
Removes a possibly unbounded strcpy().
Signed-off-by: David Laight <david.laight.linux@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260606202633.5018-9-david.laight.linux@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
The negative-key race fix added release/acquire ordering for key use.
Publish payload before state; read state before payload.
keyring_search_iterator() still uses READ_ONCE() before match callbacks.
An asymmetric match callback calls asymmetric_key_ids(), which reads
key->payload.data[asym_key_ids].
Use key_read_state() there to complete that ordering.
Fixes: 363b02dab09b ("KEYS: Fix race between updating and finding a negative key")
Signed-off-by: Gui-Dong Han <hanguidong02@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260529033406.20673-1-hanguidong02@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
The 'migratable' variable is initialized only during the init phase
in the 'init_trusted' function and never changed. So, mark it as
__ro_after_init.
Signed-off-by: Len Bao <len.bao@gmx.us>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260516152249.41851-1-len.bao@gmx.us
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Use kmalloc_flex() when allocating a new struct user_key_payload in
user_preparse() to replace the open-coded size arithmetic and to keep
the size type-safe.
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Link: https://lore.kernel.org/r/20260504093058.49720-3-thorsten.blum@linux.dev
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
TPM_DEBUG, and other similar flags, are a non-standard way to specify a
feature in Linux kernel. Introduce CONFIG_TRUSTED_KEYS_DEBUG for trusted
keys, and use it to replace these ad-hoc feature flags.
Given that trusted keys debug dumps can contain sensitive data, harden the
feature as follows:
1. In the Kconfig description postulate that pr_debug() statements must be
used.
2. Use pr_debug() statements in TPM 1.x driver to print the protocol dump.
3. Require trusted.debug=1 on the kernel command line (default: 0) to
activate dumps at runtime, even when CONFIG_TRUSTED_KEYS_DEBUG=y.
Traces, when actually needed, can be easily enabled by providing
trusted.dyndbg='+p' and trusted.debug=1 in the kernel command-line.
Reported-by: Nayna Jain <nayna@linux.ibm.com>
Closes: https://lore.kernel.org/all/7f8b8478-5cd8-4d97-bfd0-341fd5cf10f9@linux.ibm.com/
Reviewed-by: Nayna Jain <nayna@linux.ibm.com>
Tested-by: Srish Srinivasan <ssrish@linux.ibm.com>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
encrypted-keys uses the regular Linux RNG (get_random_bytes()), not the
duplicative crypto_rng one. So it does not need to select CRYPTO_RNG.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
The length for the internal output buffer is calculated incorrectly, which
can result overflow when a too small buffer is provided.
Fix the bug by allocating internal output with the size of the maximum
length of the cryptographic primitive instead of caller provided size.
Link: https://lore.kernel.org/keyrings/20260531024914.3712130-1-jarkko@kernel.org/
Cc: stable@vger.kernel.org # v4.20+
Fixes: 00d60fd3b932 ("KEYS: Provide keyctls to drive the new key type ops for asymmetric keys [ver #2]")
Reported-by: Alessandro Groppo <ale.grpp@gmail.com>
Tested-by: Alessandro Groppo <ale.grpp@gmail.com>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Nicholas Carlini reports that the keyring code calls assoc_array_find()
in find_key_to_update() without holding the RCU read lock, while the
assoc_array_gc() code really is designed around removing the node from
the tree and then freeing it after an RCU grace-period.
The regular key handling doesn't see this because holding the keyring
semaphore hides any lifetime issues, but the persistent key handling
uses a different model.
Instead of extending the keyring locking, just do the simple RCU locking
that the assoc_array was designed for.
Reported-by: Nicholas Carlini <npc@anthropic.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Jarkko Sakkinen <jarkko@kernel.org>
Cc: Paul Moore <paul@paul-moore.com>
Cc: James Morris James Morris <jmorris@namei.org>
Cc: Serge E. Hallyn <serge@hallyn.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|