lkml.org 
[lkml]   [2013]   [Nov]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH 8/9] KEYS: Implement keyctl control for encrypted keys
    From
    Date
    Implement "keyctl control" for encrypted keys rather than trying to do this
    with the update method (which won't function correctly when add_key() tries to
    update an existing key).

    Provide a command to change the master key:

    keyctl control <keyid> "encrypted change-master-key <m-key-id>"

    Signed-off-by: David Howells <dhowells@redhat.com>
    ---

    security/keys/encrypted-keys/encrypted.c | 56 ++++++++++++++++++++++++++++++
    1 file changed, 56 insertions(+)

    diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
    index 9e1e005c7596..f9e7b808fa47 100644
    --- a/security/keys/encrypted-keys/encrypted.c
    +++ b/security/keys/encrypted-keys/encrypted.c
    @@ -884,6 +884,61 @@ out:
    }

    /*
    + * encrypted_control - control an encrypted key in a type-specific way
    + */
    +static long encrypted_control(struct key *key, char *command,
    + char *reply, size_t reply_size)
    +{
    + static const char expected_command[] = "encrypted change-master-key ";
    + struct encrypted_key_payload *epayload, *new_epayload;
    + char *new_master_desc = NULL;
    + const char *format = NULL;
    + size_t datalen;
    + int ret;
    +
    + if (memcmp(command, expected_command, sizeof(expected_command) - 1) != 0)
    + return -EINVAL;
    + command += sizeof(expected_command) - 1;
    + datalen = strlen(command);
    +
    + if (datalen <= 0 || datalen > 32767)
    + return -EINVAL;
    +
    + ret = datablob_parse(command, &format, &new_master_desc, NULL, NULL);
    + if (ret < 0)
    + return ret;
    +
    + down_write(&key->sem);
    + epayload = rcu_dereference_protected(key->payload.rcudata, &key->sem);
    +
    + ret = valid_master_desc(new_master_desc, epayload->master_desc);
    + if (ret < 0) {
    + up_write(&key->sem);
    + return ret;
    + }
    +
    + new_epayload = encrypted_key_alloc(key, epayload->format,
    + new_master_desc, epayload->datalen);
    + if (IS_ERR(new_epayload)) {
    + up_write(&key->sem);
    + return PTR_ERR(new_epayload);
    + }
    +
    + __ekey_init(new_epayload, epayload->format, new_master_desc,
    + epayload->datalen);
    +
    + memcpy(new_epayload->iv, epayload->iv, ivsize);
    + memcpy(new_epayload->payload_data, epayload->payload_data,
    + epayload->payload_datalen);
    +
    + rcu_assign_keypointer(key, new_epayload);
    +
    + up_write(&key->sem);
    + call_rcu(&epayload->rcu, encrypted_rcu_free);
    + return 0;
    +}
    +
    +/*
    * encrypted_read - format and copy the encrypted data to userspace
    *
    * The resulting datablob format is:
    @@ -974,6 +1029,7 @@ struct key_type key_type_encrypted = {
    .destroy = encrypted_destroy,
    .describe = user_describe,
    .read = encrypted_read,
    + .control = encrypted_control,
    };
    EXPORT_SYMBOL_GPL(key_type_encrypted);



    \
     
     \ /
      Last update: 2013-11-04 19:41    [W:2.815 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site