summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMat Martineau <mathew.j.martineau@linux.intel.com>2016-10-04 16:27:32 -0700
committerMat Martineau <mathew.j.martineau@linux.intel.com>2017-04-04 14:10:11 -0700
commit4a420896f12d2d043602f134ae18ad6be5b9d9dd (patch)
treee94fefe0dd32c3bbe3a3585277305ce8b270201f
parentefba797b977c99bc6e0c301299272c80fb8b287f (diff)
downloadlinux-4a420896f12d2d043602f134ae18ad6be5b9d9dd.tar.gz
linux-4a420896f12d2d043602f134ae18ad6be5b9d9dd.tar.bz2
linux-4a420896f12d2d043602f134ae18ad6be5b9d9dd.zip
KEYS: Consistent ordering for __key_link_begin and restrict check
The keyring restrict callback was sometimes called before __key_link_begin and sometimes after, which meant that the keyring semaphores were not always held during the restrict callback. If the semaphores are consistently acquired before checking link restrictions, keyring contents cannot be changed after the restrict check is complete but before the evaluated key is linked to the keyring. Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
-rw-r--r--security/keys/key.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/security/keys/key.c b/security/keys/key.c
index 2ea5967121de..455c04d80bbb 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -500,21 +500,23 @@ int key_instantiate_and_link(struct key *key,
}
if (keyring) {
+ ret = __key_link_begin(keyring, &key->index_key, &edit);
+ if (ret < 0)
+ goto error;
+
if (keyring->restrict_link && keyring->restrict_link->check) {
struct key_restriction *keyres = keyring->restrict_link;
ret = keyres->check(keyring, key->type, &prep.payload,
keyres->key);
if (ret < 0)
- goto error;
+ goto error_link_end;
}
- ret = __key_link_begin(keyring, &key->index_key, &edit);
- if (ret < 0)
- goto error;
}
ret = __key_instantiate_and_link(key, &prep, keyring, authkey, &edit);
+error_link_end:
if (keyring)
__key_link_end(keyring, &key->index_key, edit);
@@ -855,21 +857,21 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
}
index_key.desc_len = strlen(index_key.description);
+ ret = __key_link_begin(keyring, &index_key, &edit);
+ if (ret < 0) {
+ key_ref = ERR_PTR(ret);
+ goto error_free_prep;
+ }
+
if (restrict_link && restrict_link->check) {
ret = restrict_link->check(keyring, index_key.type,
&prep.payload, restrict_link->key);
if (ret < 0) {
key_ref = ERR_PTR(ret);
- goto error_free_prep;
+ goto error_link_end;
}
}
- ret = __key_link_begin(keyring, &index_key, &edit);
- if (ret < 0) {
- key_ref = ERR_PTR(ret);
- goto error_free_prep;
- }
-
/* if we're going to allocate a new key, we're going to have
* to modify the keyring */
ret = key_permission(keyring_ref, KEY_NEED_WRITE);