Merge tag 'for-next-keys-7.2-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd

Pull keys update from Jarkko Sakkinen:
 "This contains only bug fixes"

* tag 'for-next-keys-7.2-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
  keys: keyctl_pkey: replace BUG with return -EOPNOTSUPP
  keys: request_key: replace BUG with return -EINVAL
  keys: Pin request_key_auth payload in instantiate paths
  keys: prevent slab cache merging for key_jar
  keys: Replace strcpy(derived_buf, "AUTH_KEY") with strscpy(..., HASH_SIZE)
  KEYS: Use acquire when reading state in keyring search
  keys/trusted_keys: mark 'migratable' as __ro_after_init
  keys: use kmalloc_flex in user_preparse
  KEYS: trusted: Debugging as a feature
  KEYS: encrypted: Remove unnecessary selection of CRYPTO_RNG
  KEYS: fix overflow in keyctl_pkey_params_get_2()
This commit is contained in:
Linus Torvalds
2026-06-19 12:14:08 -07:00
17 changed files with 158 additions and 49 deletions

View File

@@ -7872,6 +7872,22 @@ Kernel parameters
first trust source as a backend which is initialized
successfully during iteration.
trusted.debug= [KEYS]
Format: <bool>
Enable trusted keys debug traces at runtime when
CONFIG_TRUSTED_KEYS_DEBUG=y.
To make the traces visible after enabling the option,
use trusted.dyndbg='+p' as needed. By convention,
the subsystem uses pr_debug() for these traces.
SAFETY: The traces can leak sensitive data, so be
cautious before enabling this. They remain inactive
unless this parameter is set this option to a true
value.
Default: false
trusted.rng= [KEYS]
Format: <string>
The RNG used to generate key material for trusted keys.

View File

@@ -9,12 +9,14 @@
#define _KEYS_REQUEST_KEY_AUTH_TYPE_H
#include <linux/key.h>
#include <linux/refcount.h>
/*
* Authorisation record for request_key().
*/
struct request_key_auth {
struct rcu_head rcu;
refcount_t usage;
struct key *target_key;
struct key *dest_keyring;
const struct cred *cred;

View File

@@ -83,18 +83,21 @@ struct trusted_key_source {
extern struct key_type key_type_trusted;
#define TRUSTED_DEBUG 0
#ifdef CONFIG_TRUSTED_KEYS_DEBUG
extern bool trusted_debug;
#if TRUSTED_DEBUG
static inline void dump_payload(struct trusted_key_payload *p)
{
pr_info("key_len %d\n", p->key_len);
print_hex_dump(KERN_INFO, "key ", DUMP_PREFIX_NONE,
16, 1, p->key, p->key_len, 0);
pr_info("bloblen %d\n", p->blob_len);
print_hex_dump(KERN_INFO, "blob ", DUMP_PREFIX_NONE,
16, 1, p->blob, p->blob_len, 0);
pr_info("migratable %d\n", p->migratable);
if (!trusted_debug)
return;
pr_debug("key_len %d\n", p->key_len);
print_hex_dump_debug("key ", DUMP_PREFIX_NONE,
16, 1, p->key, p->key_len, 0);
pr_debug("bloblen %d\n", p->blob_len);
print_hex_dump_debug("blob ", DUMP_PREFIX_NONE,
16, 1, p->blob, p->blob_len, 0);
pr_debug("migratable %d\n", p->migratable);
}
#else
static inline void dump_payload(struct trusted_key_payload *p)

View File

@@ -87,7 +87,6 @@ config ENCRYPTED_KEYS
select CRYPTO_AES
select CRYPTO_CBC
select CRYPTO_LIB_SHA256
select CRYPTO_RNG
help
This option provides support for create/encrypting/decrypting keys
in the kernel. Encrypted keys are instantiated using kernel

View File

@@ -343,9 +343,9 @@ static int get_derived_key(u8 *derived_key, enum derived_key_type key_type,
return -ENOMEM;
if (key_type)
strcpy(derived_buf, "AUTH_KEY");
strscpy(derived_buf, "AUTH_KEY", HASH_SIZE);
else
strcpy(derived_buf, "ENC_KEY");
strscpy(derived_buf, "ENC_KEY", HASH_SIZE);
memcpy(derived_buf + strlen(derived_buf) + 1, master_key,
master_keylen);

View File

@@ -208,6 +208,8 @@ extern struct key *request_key_auth_new(struct key *target,
const void *callout_info,
size_t callout_len,
struct key *dest_keyring);
struct request_key_auth *request_key_auth_get(struct key *authkey);
void request_key_auth_put(struct request_key_auth *rka);
extern struct key *key_get_instantiation_authkey(key_serial_t target_id);

View File

@@ -1275,7 +1275,7 @@ void __init key_init(void)
{
/* allocate a slab in which we can store keys */
key_jar = kmem_cache_create("key_jar", sizeof(struct key),
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
0, SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_NO_MERGE, NULL);
/* add the special key types */
list_add_tail(&key_type_keyring.link, &key_types_list);

View File

@@ -1197,9 +1197,13 @@ static long keyctl_instantiate_key_common(key_serial_t id,
if (!instkey)
goto error;
rka = instkey->payload.data[0];
if (rka->target_key->serial != id)
rka = request_key_auth_get(instkey);
if (!rka) {
ret = -EKEYREVOKED;
goto error;
}
if (rka->target_key->serial != id)
goto error_put_rka;
/* pull the payload in if one was supplied */
payload = NULL;
@@ -1208,7 +1212,7 @@ static long keyctl_instantiate_key_common(key_serial_t id,
ret = -ENOMEM;
payload = kvmalloc(plen, GFP_KERNEL);
if (!payload)
goto error;
goto error_put_rka;
ret = -EFAULT;
if (!copy_from_iter_full(payload, plen, from))
@@ -1234,6 +1238,8 @@ static long keyctl_instantiate_key_common(key_serial_t id,
error2:
kvfree_sensitive(payload, plen);
error_put_rka:
request_key_auth_put(rka);
error:
return ret;
}
@@ -1358,15 +1364,19 @@ long keyctl_reject_key(key_serial_t id, unsigned timeout, unsigned error,
if (!instkey)
goto error;
rka = instkey->payload.data[0];
if (rka->target_key->serial != id)
rka = request_key_auth_get(instkey);
if (!rka) {
ret = -EKEYREVOKED;
goto error;
}
if (rka->target_key->serial != id)
goto error_put_rka;
/* find the destination keyring if present (which must also be
* writable) */
ret = get_instantiation_keyring(ringid, rka, &dest_keyring);
if (ret < 0)
goto error;
goto error_put_rka;
/* instantiate the key and link it into a keyring */
ret = key_reject_and_link(rka->target_key, timeout, error,
@@ -1379,6 +1389,8 @@ long keyctl_reject_key(key_serial_t id, unsigned timeout, unsigned error,
if (ret == 0)
keyctl_change_reqkey_auth(NULL);
error_put_rka:
request_key_auth_put(rka);
error:
return ret;
}

View File

@@ -138,28 +138,35 @@ static int keyctl_pkey_params_get_2(const struct keyctl_pkey_params __user *_par
if (uparams.in_len > info.max_dec_size ||
uparams.out_len > info.max_enc_size)
return -EINVAL;
params->out_len = info.max_enc_size;
break;
case KEYCTL_PKEY_DECRYPT:
if (uparams.in_len > info.max_enc_size ||
uparams.out_len > info.max_dec_size)
return -EINVAL;
params->out_len = info.max_dec_size;
break;
case KEYCTL_PKEY_SIGN:
if (uparams.in_len > info.max_data_size ||
uparams.out_len > info.max_sig_size)
return -EINVAL;
params->out_len = info.max_sig_size;
break;
case KEYCTL_PKEY_VERIFY:
if (uparams.in_len > info.max_data_size ||
uparams.in2_len > info.max_sig_size)
return -EINVAL;
params->out_len = info.max_sig_size;
break;
default:
BUG();
return -EOPNOTSUPP;
}
params->in_len = uparams.in_len;
params->out_len = uparams.out_len; /* Note: same as in2_len */
return 0;
}
@@ -238,7 +245,8 @@ long keyctl_pkey_e_d_s(int op,
params.op = kernel_pkey_sign;
break;
default:
BUG();
ret = -EOPNOTSUPP;
goto error_params;
}
in = memdup_user(_in, params.in_len);

View File

@@ -576,7 +576,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
struct keyring_search_context *ctx = iterator_data;
const struct key *key = keyring_ptr_to_key(object);
unsigned long kflags = READ_ONCE(key->flags);
short state = READ_ONCE(key->state);
short state = key_read_state(key);
kenter("{%d}", key->serial);

View File

@@ -332,7 +332,7 @@ static int construct_get_dest_keyring(struct key **_dest_keyring)
case KEY_REQKEY_DEFL_GROUP_KEYRING:
default:
BUG();
return -EINVAL;
}
/*

View File

@@ -23,6 +23,7 @@ static void request_key_auth_describe(const struct key *, struct seq_file *);
static void request_key_auth_revoke(struct key *);
static void request_key_auth_destroy(struct key *);
static long request_key_auth_read(const struct key *, char *, size_t);
static void request_key_auth_rcu_disposal(struct rcu_head *);
/*
* The request-key authorisation key type definition.
@@ -115,6 +116,31 @@ static void free_request_key_auth(struct request_key_auth *rka)
kfree(rka);
}
/*
* Take a reference to the request-key authorisation payload so callers can
* drop authkey->sem before doing operations that may sleep.
*/
struct request_key_auth *request_key_auth_get(struct key *authkey)
{
struct request_key_auth *rka;
down_read(&authkey->sem);
rka = dereference_key_locked(authkey);
if (rka && !test_bit(KEY_FLAG_REVOKED, &authkey->flags))
refcount_inc(&rka->usage);
else
rka = NULL;
up_read(&authkey->sem);
return rka;
}
void request_key_auth_put(struct request_key_auth *rka)
{
if (rka && refcount_dec_and_test(&rka->usage))
call_rcu(&rka->rcu, request_key_auth_rcu_disposal);
}
/*
* Dispose of the request_key_auth record under RCU conditions
*/
@@ -136,8 +162,10 @@ static void request_key_auth_revoke(struct key *key)
struct request_key_auth *rka = dereference_key_locked(key);
kenter("{%d}", key->serial);
if (!rka)
return;
rcu_assign_keypointer(key, NULL);
call_rcu(&rka->rcu, request_key_auth_rcu_disposal);
request_key_auth_put(rka);
}
/*
@@ -150,7 +178,7 @@ static void request_key_auth_destroy(struct key *key)
kenter("{%d}", key->serial);
if (rka) {
rcu_assign_keypointer(key, NULL);
call_rcu(&rka->rcu, request_key_auth_rcu_disposal);
request_key_auth_put(rka);
}
}
@@ -174,6 +202,7 @@ struct key *request_key_auth_new(struct key *target, const char *op,
rka = kzalloc_obj(*rka);
if (!rka)
goto error;
refcount_set(&rka->usage, 1);
rka->callout_info = kmemdup(callout_info, callout_len, GFP_KERNEL);
if (!rka->callout_info)
goto error_free_rka;

View File

@@ -1,10 +1,29 @@
config HAVE_TRUSTED_KEYS
bool
config HAVE_TRUSTED_KEYS_DEBUG
bool
config TRUSTED_KEYS_DEBUG
bool "Debug trusted keys"
depends on HAVE_TRUSTED_KEYS_DEBUG
default n
help
Trusted key backends and core code that support debug traces can
opt-in that feature here. Traces must only use debug level output, as
sensitive data may pass by. In the kernel-command line traces can be
enabled via trusted.dyndbg='+p'.
SAFETY: Debug dumps are inactive at runtime until trusted.debug is set
to a true value on the kernel command-line. Use at your utmost
consideration when enabling this feature on a production build. The
general advice is not to do this.
config TRUSTED_KEYS_TPM
bool "TPM-based trusted keys"
depends on TCG_TPM >= TRUSTED_KEYS
default y
select HAVE_TRUSTED_KEYS_DEBUG
select CRYPTO_HASH_INFO
select CRYPTO_LIB_SHA1
select CRYPTO_LIB_UTILS
@@ -23,6 +42,7 @@ config TRUSTED_KEYS_TEE
bool "TEE-based trusted keys"
depends on TEE >= TRUSTED_KEYS
default y
select HAVE_TRUSTED_KEYS_DEBUG
select HAVE_TRUSTED_KEYS
help
Enable use of the Trusted Execution Environment (TEE) as trusted
@@ -33,6 +53,7 @@ config TRUSTED_KEYS_CAAM
depends on CRYPTO_DEV_FSL_CAAM_JR >= TRUSTED_KEYS
select CRYPTO_DEV_FSL_CAAM_BLOB_GEN
default y
select HAVE_TRUSTED_KEYS_DEBUG
select HAVE_TRUSTED_KEYS
help
Enable use of NXP's Cryptographic Accelerator and Assurance Module
@@ -42,6 +63,7 @@ config TRUSTED_KEYS_DCP
bool "DCP-based trusted keys"
depends on CRYPTO_DEV_MXS_DCP >= TRUSTED_KEYS
default y
select HAVE_TRUSTED_KEYS_DEBUG
select HAVE_TRUSTED_KEYS
help
Enable use of NXP's DCP (Data Co-Processor) as trusted key backend.
@@ -50,6 +72,7 @@ config TRUSTED_KEYS_PKWM
bool "PKWM-based trusted keys"
depends on PSERIES_PLPKS >= TRUSTED_KEYS
default y
select HAVE_TRUSTED_KEYS_DEBUG
select HAVE_TRUSTED_KEYS
help
Enable use of IBM PowerVM Key Wrapping Module (PKWM) as a trusted key backend.

View File

@@ -28,10 +28,13 @@ static const match_table_t key_tokens = {
{opt_err, NULL}
};
#ifdef CAAM_DEBUG
#ifdef CONFIG_TRUSTED_KEYS_DEBUG
static inline void dump_options(const struct caam_pkey_info *pkey_info)
{
pr_info("key encryption algo %d\n", pkey_info->key_enc_algo);
if (!trusted_debug)
return;
pr_debug("key encryption algo %d\n", pkey_info->key_enc_algo);
}
#else
static inline void dump_options(const struct caam_pkey_info *pkey_info)

View File

@@ -31,6 +31,12 @@ static char *trusted_rng = "default";
module_param_named(rng, trusted_rng, charp, 0);
MODULE_PARM_DESC(rng, "Select trusted key RNG");
#ifdef CONFIG_TRUSTED_KEYS_DEBUG
bool trusted_debug;
module_param_named(debug, trusted_debug, bool, 0);
MODULE_PARM_DESC(debug, "Enable trusted keys debug traces (default: 0)");
#endif
static char *trusted_key_source;
module_param_named(source, trusted_key_source, charp, 0);
MODULE_PARM_DESC(source, "Select trusted keys source (tpm, tee, caam, dcp or pkwm)");
@@ -59,7 +65,7 @@ DEFINE_STATIC_CALL_NULL(trusted_key_unseal,
DEFINE_STATIC_CALL_NULL(trusted_key_get_random,
*trusted_key_sources[0].ops->get_random);
static void (*trusted_key_exit)(void);
static unsigned char migratable;
static unsigned char migratable __ro_after_init;
enum {
Opt_err,

View File

@@ -46,38 +46,44 @@ enum {
SRK_keytype = 4
};
#define TPM_DEBUG 0
#if TPM_DEBUG
#ifdef CONFIG_TRUSTED_KEYS_DEBUG
static inline void dump_options(struct trusted_key_options *o)
{
pr_info("sealing key type %d\n", o->keytype);
pr_info("sealing key handle %0X\n", o->keyhandle);
pr_info("pcrlock %d\n", o->pcrlock);
pr_info("pcrinfo %d\n", o->pcrinfo_len);
print_hex_dump(KERN_INFO, "pcrinfo ", DUMP_PREFIX_NONE,
16, 1, o->pcrinfo, o->pcrinfo_len, 0);
if (!trusted_debug)
return;
pr_debug("sealing key type %d\n", o->keytype);
pr_debug("sealing key handle %0X\n", o->keyhandle);
pr_debug("pcrlock %d\n", o->pcrlock);
pr_debug("pcrinfo %d\n", o->pcrinfo_len);
print_hex_dump_debug("pcrinfo ", DUMP_PREFIX_NONE,
16, 1, o->pcrinfo, o->pcrinfo_len, 0);
}
static inline void dump_sess(struct osapsess *s)
{
print_hex_dump(KERN_INFO, "trusted-key: handle ", DUMP_PREFIX_NONE,
16, 1, &s->handle, 4, 0);
pr_info("secret:\n");
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
16, 1, &s->secret, SHA1_DIGEST_SIZE, 0);
pr_info("trusted-key: enonce:\n");
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0);
if (!trusted_debug)
return;
print_hex_dump_debug("trusted-key: handle ", DUMP_PREFIX_NONE,
16, 1, &s->handle, 4, 0);
pr_debug("secret:\n");
print_hex_dump_debug("", DUMP_PREFIX_NONE,
16, 1, &s->secret, SHA1_DIGEST_SIZE, 0);
pr_debug("trusted-key: enonce:\n");
print_hex_dump_debug("", DUMP_PREFIX_NONE,
16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0);
}
static inline void dump_tpm_buf(unsigned char *buf)
{
int len;
pr_info("\ntpm buffer\n");
if (!trusted_debug)
return;
pr_debug("\ntpm buffer\n");
len = LOAD32(buf, TPM_SIZE_OFFSET);
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, buf, len, 0);
print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, buf, len, 0);
}
#else
static inline void dump_options(struct trusted_key_options *o)

View File

@@ -64,7 +64,7 @@ int user_preparse(struct key_preparsed_payload *prep)
if (datalen == 0 || datalen > 32767 || !prep->data)
return -EINVAL;
upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
upayload = kmalloc_flex(*upayload, data, datalen);
if (!upayload)
return -ENOMEM;