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