summaryrefslogtreecommitdiff
path: root/security/keys/request_key.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-07-18 08:43:35 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2023-07-18 08:43:35 -0700
commitf2f393c385af0635eddb58df8bcd645cb6a18f5d (patch)
tree2c0fdfac5796d1f8f3b631974aabc72a549a157e /security/keys/request_key.c
parentfdf0eaf11452d72945af31804e2a1048ee1b574c (diff)
parent481c2d14627de8ecbb54dd125466e4b4a5069b47 (diff)
Merge tag 'tpmdd-v6.5-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd
Pull tpm fixes from Jarkko Sakkinen. Mostly interrupt storm fixes, with some other minor changes. * tag 'tpmdd-v6.5-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd: tpm,tpm_tis: Disable interrupts after 1000 unhandled IRQs tpm/tpm_tis: Disable interrupts for Lenovo L590 devices tpm: Do not remap from ACPI resources again for Pluton TPM tpm/tpm_tis: Disable interrupts for Framework Laptop Intel 13th gen tpm/tpm_tis: Disable interrupts for Framework Laptop Intel 12th gen security: keys: Modify mismatched function name tpm: return false from tpm_amd_is_rng_defective on non-x86 platforms keys: Fix linking a duplicate key to a keyring's assoc_array tpm: tis_i2c: Limit write bursts to I2C_SMBUS_BLOCK_MAX (32) bytes tpm: tis_i2c: Limit read bursts to I2C_SMBUS_BLOCK_MAX (32) bytes tpm_tis_spi: Release chip select when flow control fails tpm: tpm_tis: Disable interrupts *only* for AEON UPX-i11 tpm: tpm_vtpm_proxy: fix a race condition in /dev/vtpmx creation
Diffstat (limited to 'security/keys/request_key.c')
-rw-r--r--security/keys/request_key.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 07a0ef2baacd8..a7673ad86d18d 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -401,17 +401,21 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
if (dest_keyring) {
- ret = __key_link_lock(dest_keyring, &ctx->index_key);
+ ret = __key_link_lock(dest_keyring, &key->index_key);
if (ret < 0)
goto link_lock_failed;
- ret = __key_link_begin(dest_keyring, &ctx->index_key, &edit);
- if (ret < 0)
- goto link_prealloc_failed;
}
- /* attach the key to the destination keyring under lock, but we do need
+ /*
+ * Attach the key to the destination keyring under lock, but we do need
* to do another check just in case someone beat us to it whilst we
- * waited for locks */
+ * waited for locks.
+ *
+ * The caller might specify a comparison function which looks for keys
+ * that do not exactly match but are still equivalent from the caller's
+ * perspective. The __key_link_begin() operation must be done only after
+ * an actual key is determined.
+ */
mutex_lock(&key_construction_mutex);
rcu_read_lock();
@@ -420,12 +424,16 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
if (!IS_ERR(key_ref))
goto key_already_present;
- if (dest_keyring)
+ if (dest_keyring) {
+ ret = __key_link_begin(dest_keyring, &key->index_key, &edit);
+ if (ret < 0)
+ goto link_alloc_failed;
__key_link(dest_keyring, key, &edit);
+ }
mutex_unlock(&key_construction_mutex);
if (dest_keyring)
- __key_link_end(dest_keyring, &ctx->index_key, edit);
+ __key_link_end(dest_keyring, &key->index_key, edit);
mutex_unlock(&user->cons_lock);
*_key = key;
kleave(" = 0 [%d]", key_serial(key));
@@ -438,10 +446,13 @@ key_already_present:
mutex_unlock(&key_construction_mutex);
key = key_ref_to_ptr(key_ref);
if (dest_keyring) {
+ ret = __key_link_begin(dest_keyring, &key->index_key, &edit);
+ if (ret < 0)
+ goto link_alloc_failed_unlocked;
ret = __key_link_check_live_key(dest_keyring, key);
if (ret == 0)
__key_link(dest_keyring, key, &edit);
- __key_link_end(dest_keyring, &ctx->index_key, edit);
+ __key_link_end(dest_keyring, &key->index_key, edit);
if (ret < 0)
goto link_check_failed;
}
@@ -456,8 +467,10 @@ link_check_failed:
kleave(" = %d [linkcheck]", ret);
return ret;
-link_prealloc_failed:
- __key_link_end(dest_keyring, &ctx->index_key, edit);
+link_alloc_failed:
+ mutex_unlock(&key_construction_mutex);
+link_alloc_failed_unlocked:
+ __key_link_end(dest_keyring, &key->index_key, edit);
link_lock_failed:
mutex_unlock(&user->cons_lock);
key_put(key);