KEYS: Add new function key_create()
key_create() works like key_create_or_update() but does not allow updating an existing key, instead returning ERR_PTR(-EEXIST). key_create() will be used by the blacklist keyring which should not create duplicate entries or update existing entries. Instead a dedicated message with appropriate severity will be logged. Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
This commit is contained in:
parent
06b53b0294
commit
6c1976addf
|
@ -386,6 +386,14 @@ extern int wait_for_key_construction(struct key *key, bool intr);
|
|||
|
||||
extern int key_validate(const struct key *key);
|
||||
|
||||
extern key_ref_t key_create(key_ref_t keyring,
|
||||
const char *type,
|
||||
const char *description,
|
||||
const void *payload,
|
||||
size_t plen,
|
||||
key_perm_t perm,
|
||||
unsigned long flags);
|
||||
|
||||
extern key_ref_t key_create_or_update(key_ref_t keyring,
|
||||
const char *type,
|
||||
const char *description,
|
||||
|
|
|
@ -788,38 +788,18 @@ error:
|
|||
goto out;
|
||||
}
|
||||
|
||||
/**
|
||||
* key_create_or_update - Update or create and instantiate a key.
|
||||
* @keyring_ref: A pointer to the destination keyring with possession flag.
|
||||
* @type: The type of key.
|
||||
* @description: The searchable description for the key.
|
||||
* @payload: The data to use to instantiate or update the key.
|
||||
* @plen: The length of @payload.
|
||||
* @perm: The permissions mask for a new key.
|
||||
* @flags: The quota flags for a new key.
|
||||
*
|
||||
* Search the destination keyring for a key of the same description and if one
|
||||
* is found, update it, otherwise create and instantiate a new one and create a
|
||||
* link to it from that keyring.
|
||||
*
|
||||
* If perm is KEY_PERM_UNDEF then an appropriate key permissions mask will be
|
||||
* concocted.
|
||||
*
|
||||
* Returns a pointer to the new key if successful, -ENODEV if the key type
|
||||
* wasn't available, -ENOTDIR if the keyring wasn't a keyring, -EACCES if the
|
||||
* caller isn't permitted to modify the keyring or the LSM did not permit
|
||||
* creation of the key.
|
||||
*
|
||||
* On success, the possession flag from the keyring ref will be tacked on to
|
||||
* the key ref before it is returned.
|
||||
/*
|
||||
* Create or potentially update a key. The combined logic behind
|
||||
* key_create_or_update() and key_create()
|
||||
*/
|
||||
key_ref_t key_create_or_update(key_ref_t keyring_ref,
|
||||
const char *type,
|
||||
const char *description,
|
||||
const void *payload,
|
||||
size_t plen,
|
||||
key_perm_t perm,
|
||||
unsigned long flags)
|
||||
static key_ref_t __key_create_or_update(key_ref_t keyring_ref,
|
||||
const char *type,
|
||||
const char *description,
|
||||
const void *payload,
|
||||
size_t plen,
|
||||
key_perm_t perm,
|
||||
unsigned long flags,
|
||||
bool allow_update)
|
||||
{
|
||||
struct keyring_index_key index_key = {
|
||||
.description = description,
|
||||
|
@ -906,14 +886,23 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
|
|||
goto error_link_end;
|
||||
}
|
||||
|
||||
/* if it's possible to update this type of key, search for an existing
|
||||
* key of the same type and description in the destination keyring and
|
||||
* update that instead if possible
|
||||
/* if it's requested and possible to update this type of key, search
|
||||
* for an existing key of the same type and description in the
|
||||
* destination keyring and update that instead if possible
|
||||
*/
|
||||
if (index_key.type->update) {
|
||||
if (allow_update) {
|
||||
if (index_key.type->update) {
|
||||
key_ref = find_key_to_update(keyring_ref, &index_key);
|
||||
if (key_ref)
|
||||
goto found_matching_key;
|
||||
}
|
||||
} else {
|
||||
key_ref = find_key_to_update(keyring_ref, &index_key);
|
||||
if (key_ref)
|
||||
goto found_matching_key;
|
||||
if (key_ref) {
|
||||
key_ref_put(key_ref);
|
||||
key_ref = ERR_PTR(-EEXIST);
|
||||
goto error_link_end;
|
||||
}
|
||||
}
|
||||
|
||||
/* if the client doesn't provide, decide on the permissions we want */
|
||||
|
@ -985,8 +974,82 @@ error:
|
|||
|
||||
goto error_free_prep;
|
||||
}
|
||||
|
||||
/**
|
||||
* key_create_or_update - Update or create and instantiate a key.
|
||||
* @keyring_ref: A pointer to the destination keyring with possession flag.
|
||||
* @type: The type of key.
|
||||
* @description: The searchable description for the key.
|
||||
* @payload: The data to use to instantiate or update the key.
|
||||
* @plen: The length of @payload.
|
||||
* @perm: The permissions mask for a new key.
|
||||
* @flags: The quota flags for a new key.
|
||||
*
|
||||
* Search the destination keyring for a key of the same description and if one
|
||||
* is found, update it, otherwise create and instantiate a new one and create a
|
||||
* link to it from that keyring.
|
||||
*
|
||||
* If perm is KEY_PERM_UNDEF then an appropriate key permissions mask will be
|
||||
* concocted.
|
||||
*
|
||||
* Returns a pointer to the new key if successful, -ENODEV if the key type
|
||||
* wasn't available, -ENOTDIR if the keyring wasn't a keyring, -EACCES if the
|
||||
* caller isn't permitted to modify the keyring or the LSM did not permit
|
||||
* creation of the key.
|
||||
*
|
||||
* On success, the possession flag from the keyring ref will be tacked on to
|
||||
* the key ref before it is returned.
|
||||
*/
|
||||
key_ref_t key_create_or_update(key_ref_t keyring_ref,
|
||||
const char *type,
|
||||
const char *description,
|
||||
const void *payload,
|
||||
size_t plen,
|
||||
key_perm_t perm,
|
||||
unsigned long flags)
|
||||
{
|
||||
return __key_create_or_update(keyring_ref, type, description, payload,
|
||||
plen, perm, flags, true);
|
||||
}
|
||||
EXPORT_SYMBOL(key_create_or_update);
|
||||
|
||||
/**
|
||||
* key_create - Create and instantiate a key.
|
||||
* @keyring_ref: A pointer to the destination keyring with possession flag.
|
||||
* @type: The type of key.
|
||||
* @description: The searchable description for the key.
|
||||
* @payload: The data to use to instantiate or update the key.
|
||||
* @plen: The length of @payload.
|
||||
* @perm: The permissions mask for a new key.
|
||||
* @flags: The quota flags for a new key.
|
||||
*
|
||||
* Create and instantiate a new key and link to it from the destination keyring.
|
||||
*
|
||||
* If perm is KEY_PERM_UNDEF then an appropriate key permissions mask will be
|
||||
* concocted.
|
||||
*
|
||||
* Returns a pointer to the new key if successful, -EEXIST if a key with the
|
||||
* same description already exists, -ENODEV if the key type wasn't available,
|
||||
* -ENOTDIR if the keyring wasn't a keyring, -EACCES if the caller isn't
|
||||
* permitted to modify the keyring or the LSM did not permit creation of the
|
||||
* key.
|
||||
*
|
||||
* On success, the possession flag from the keyring ref will be tacked on to
|
||||
* the key ref before it is returned.
|
||||
*/
|
||||
key_ref_t key_create(key_ref_t keyring_ref,
|
||||
const char *type,
|
||||
const char *description,
|
||||
const void *payload,
|
||||
size_t plen,
|
||||
key_perm_t perm,
|
||||
unsigned long flags)
|
||||
{
|
||||
return __key_create_or_update(keyring_ref, type, description, payload,
|
||||
plen, perm, flags, false);
|
||||
}
|
||||
EXPORT_SYMBOL(key_create);
|
||||
|
||||
/**
|
||||
* key_update - Update a key's contents.
|
||||
* @key_ref: The pointer (plus possession flag) to the key.
|
||||
|
|
Loading…
Reference in New Issue