linux/security/keys/request_key_auth.c
<<
>>
Prefs
   1/* Request key authorisation token key definition.
   2 *
   3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Howells (dhowells@redhat.com)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 *
  11 * See Documentation/security/keys/request-key.rst
  12 */
  13
  14#include <linux/module.h>
  15#include <linux/sched.h>
  16#include <linux/err.h>
  17#include <linux/seq_file.h>
  18#include <linux/slab.h>
  19#include <linux/uaccess.h>
  20#include "internal.h"
  21#include <keys/user-type.h>
  22
  23static int request_key_auth_preparse(struct key_preparsed_payload *);
  24static void request_key_auth_free_preparse(struct key_preparsed_payload *);
  25static int request_key_auth_instantiate(struct key *,
  26                                        struct key_preparsed_payload *);
  27static void request_key_auth_describe(const struct key *, struct seq_file *);
  28static void request_key_auth_revoke(struct key *);
  29static void request_key_auth_destroy(struct key *);
  30static long request_key_auth_read(const struct key *, char __user *, size_t);
  31
  32/*
  33 * The request-key authorisation key type definition.
  34 */
  35struct key_type key_type_request_key_auth = {
  36        .name           = ".request_key_auth",
  37        .def_datalen    = sizeof(struct request_key_auth),
  38        .preparse       = request_key_auth_preparse,
  39        .free_preparse  = request_key_auth_free_preparse,
  40        .instantiate    = request_key_auth_instantiate,
  41        .describe       = request_key_auth_describe,
  42        .revoke         = request_key_auth_revoke,
  43        .destroy        = request_key_auth_destroy,
  44        .read           = request_key_auth_read,
  45};
  46
  47static int request_key_auth_preparse(struct key_preparsed_payload *prep)
  48{
  49        return 0;
  50}
  51
  52static void request_key_auth_free_preparse(struct key_preparsed_payload *prep)
  53{
  54}
  55
  56/*
  57 * Instantiate a request-key authorisation key.
  58 */
  59static int request_key_auth_instantiate(struct key *key,
  60                                        struct key_preparsed_payload *prep)
  61{
  62        key->payload.data[0] = (struct request_key_auth *)prep->data;
  63        return 0;
  64}
  65
  66/*
  67 * Describe an authorisation token.
  68 */
  69static void request_key_auth_describe(const struct key *key,
  70                                      struct seq_file *m)
  71{
  72        struct request_key_auth *rka = key->payload.data[0];
  73
  74        seq_puts(m, "key:");
  75        seq_puts(m, key->description);
  76        if (key_is_instantiated(key))
  77                seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
  78}
  79
  80/*
  81 * Read the callout_info data (retrieves the callout information).
  82 * - the key's semaphore is read-locked
  83 */
  84static long request_key_auth_read(const struct key *key,
  85                                  char __user *buffer, size_t buflen)
  86{
  87        struct request_key_auth *rka = key->payload.data[0];
  88        size_t datalen;
  89        long ret;
  90
  91        datalen = rka->callout_len;
  92        ret = datalen;
  93
  94        /* we can return the data as is */
  95        if (buffer && buflen > 0) {
  96                if (buflen > datalen)
  97                        buflen = datalen;
  98
  99                if (copy_to_user(buffer, rka->callout_info, buflen) != 0)
 100                        ret = -EFAULT;
 101        }
 102
 103        return ret;
 104}
 105
 106/*
 107 * Handle revocation of an authorisation token key.
 108 *
 109 * Called with the key sem write-locked.
 110 */
 111static void request_key_auth_revoke(struct key *key)
 112{
 113        struct request_key_auth *rka = key->payload.data[0];
 114
 115        kenter("{%d}", key->serial);
 116
 117        if (rka->cred) {
 118                put_cred(rka->cred);
 119                rka->cred = NULL;
 120        }
 121}
 122
 123/*
 124 * Destroy an instantiation authorisation token key.
 125 */
 126static void request_key_auth_destroy(struct key *key)
 127{
 128        struct request_key_auth *rka = key->payload.data[0];
 129
 130        kenter("{%d}", key->serial);
 131
 132        if (rka->cred) {
 133                put_cred(rka->cred);
 134                rka->cred = NULL;
 135        }
 136
 137        key_put(rka->target_key);
 138        key_put(rka->dest_keyring);
 139        kfree(rka->callout_info);
 140        kfree(rka);
 141}
 142
 143/*
 144 * Create an authorisation token for /sbin/request-key or whoever to gain
 145 * access to the caller's security data.
 146 */
 147struct key *request_key_auth_new(struct key *target, const void *callout_info,
 148                                 size_t callout_len, struct key *dest_keyring)
 149{
 150        struct request_key_auth *rka, *irka;
 151        const struct cred *cred = current->cred;
 152        struct key *authkey = NULL;
 153        char desc[20];
 154        int ret;
 155
 156        kenter("%d,", target->serial);
 157
 158        /* allocate a auth record */
 159        rka = kmalloc(sizeof(*rka), GFP_KERNEL);
 160        if (!rka) {
 161                kleave(" = -ENOMEM");
 162                return ERR_PTR(-ENOMEM);
 163        }
 164        rka->callout_info = kmalloc(callout_len, GFP_KERNEL);
 165        if (!rka->callout_info) {
 166                kleave(" = -ENOMEM");
 167                kfree(rka);
 168                return ERR_PTR(-ENOMEM);
 169        }
 170
 171        /* see if the calling process is already servicing the key request of
 172         * another process */
 173        if (cred->request_key_auth) {
 174                /* it is - use that instantiation context here too */
 175                down_read(&cred->request_key_auth->sem);
 176
 177                /* if the auth key has been revoked, then the key we're
 178                 * servicing is already instantiated */
 179                if (test_bit(KEY_FLAG_REVOKED, &cred->request_key_auth->flags))
 180                        goto auth_key_revoked;
 181
 182                irka = cred->request_key_auth->payload.data[0];
 183                rka->cred = get_cred(irka->cred);
 184                rka->pid = irka->pid;
 185
 186                up_read(&cred->request_key_auth->sem);
 187        }
 188        else {
 189                /* it isn't - use this process as the context */
 190                rka->cred = get_cred(cred);
 191                rka->pid = current->pid;
 192        }
 193
 194        rka->target_key = key_get(target);
 195        rka->dest_keyring = key_get(dest_keyring);
 196        memcpy(rka->callout_info, callout_info, callout_len);
 197        rka->callout_len = callout_len;
 198
 199        /* allocate the auth key */
 200        sprintf(desc, "%x", target->serial);
 201
 202        authkey = key_alloc(&key_type_request_key_auth, desc,
 203                            cred->fsuid, cred->fsgid, cred,
 204                            KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
 205                            KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL);
 206        if (IS_ERR(authkey)) {
 207                ret = PTR_ERR(authkey);
 208                goto error_alloc;
 209        }
 210
 211        /* construct the auth key */
 212        ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
 213        if (ret < 0)
 214                goto error_inst;
 215
 216        kleave(" = {%d,%d}", authkey->serial, refcount_read(&authkey->usage));
 217        return authkey;
 218
 219auth_key_revoked:
 220        up_read(&cred->request_key_auth->sem);
 221        kfree(rka->callout_info);
 222        kfree(rka);
 223        kleave("= -EKEYREVOKED");
 224        return ERR_PTR(-EKEYREVOKED);
 225
 226error_inst:
 227        key_revoke(authkey);
 228        key_put(authkey);
 229error_alloc:
 230        key_put(rka->target_key);
 231        key_put(rka->dest_keyring);
 232        kfree(rka->callout_info);
 233        kfree(rka);
 234        kleave("= %d", ret);
 235        return ERR_PTR(ret);
 236}
 237
 238/*
 239 * Search the current process's keyrings for the authorisation key for
 240 * instantiation of a key.
 241 */
 242struct key *key_get_instantiation_authkey(key_serial_t target_id)
 243{
 244        char description[16];
 245        struct keyring_search_context ctx = {
 246                .index_key.type         = &key_type_request_key_auth,
 247                .index_key.description  = description,
 248                .cred                   = current_cred(),
 249                .match_data.cmp         = key_default_cmp,
 250                .match_data.raw_data    = description,
 251                .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
 252                .flags                  = KEYRING_SEARCH_DO_STATE_CHECK,
 253        };
 254        struct key *authkey;
 255        key_ref_t authkey_ref;
 256
 257        sprintf(description, "%x", target_id);
 258
 259        authkey_ref = search_process_keyrings(&ctx);
 260
 261        if (IS_ERR(authkey_ref)) {
 262                authkey = ERR_CAST(authkey_ref);
 263                if (authkey == ERR_PTR(-EAGAIN))
 264                        authkey = ERR_PTR(-ENOKEY);
 265                goto error;
 266        }
 267
 268        authkey = key_ref_to_ptr(authkey_ref);
 269        if (test_bit(KEY_FLAG_REVOKED, &authkey->flags)) {
 270                key_put(authkey);
 271                authkey = ERR_PTR(-EKEYREVOKED);
 272        }
 273
 274error:
 275        return authkey;
 276}
 277