Skip to content

Commit

Permalink
KEYS: Consistent ordering for __key_link_begin and restrict check
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
mjmartineau committed Apr 4, 2017
1 parent efba797 commit 4a42089
Showing 1 changed file with 13 additions and 11 deletions.
24 changes: 13 additions & 11 deletions security/keys/key.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 4a42089

Please sign in to comment.