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 __user *, 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        key->payload.data[0] = (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 = get_request_key_auth(key);
  68
  69        seq_puts(m, "key:");
  70        seq_puts(m, key->description);
  71        if (key_is_positive(key))
  72                seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
  73}
  74
  75/*
  76 * Read the callout_info data (retrieves the callout information).
  77 * - the key's semaphore is read-locked
  78 */
  79static long request_key_auth_read(const struct key *key,
  80                                  char __user *buffer, size_t buflen)
  81{
  82        struct request_key_auth *rka = get_request_key_auth(key);
  83        size_t datalen;
  84        long ret;
  85
  86        datalen = rka->callout_len;
  87        ret = datalen;
  88
  89        /* we can return the data as is */
  90        if (buffer && buflen > 0) {
  91                if (buflen > datalen)
  92                        buflen = datalen;
  93
  94                if (copy_to_user(buffer, rka->callout_info, buflen) != 0)
  95                        ret = -EFAULT;
  96        }
  97
  98        return ret;
  99}
 100
 101/*
 102 * Handle revocation of an authorisation token key.
 103 *
 104 * Called with the key sem write-locked.
 105 */
 106static void request_key_auth_revoke(struct key *key)
 107{
 108        struct request_key_auth *rka = get_request_key_auth(key);
 109
 110        kenter("{%d}", key->serial);
 111
 112        if (rka->cred) {
 113                put_cred(rka->cred);
 114                rka->cred = NULL;
 115        }
 116}
 117
 118static void free_request_key_auth(struct request_key_auth *rka)
 119{
 120        if (!rka)
 121                return;
 122        key_put(rka->target_key);
 123        key_put(rka->dest_keyring);
 124        if (rka->cred)
 125                put_cred(rka->cred);
 126        kfree(rka->callout_info);
 127        kfree(rka);
 128}
 129
 130/*
 131 * Destroy an instantiation authorisation token key.
 132 */
 133static void request_key_auth_destroy(struct key *key)
 134{
 135        struct request_key_auth *rka = get_request_key_auth(key);
 136
 137        kenter("{%d}", key->serial);
 138
 139        free_request_key_auth(rka);
 140}
 141
 142/*
 143 * Create an authorisation token for /sbin/request-key or whoever to gain
 144 * access to the caller's security data.
 145 */
 146struct key *request_key_auth_new(struct key *target, const char *op,
 147                                 const void *callout_info, size_t callout_len,
 148                                 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 = -ENOMEM;
 155
 156        kenter("%d,", target->serial);
 157
 158        /* allocate a auth record */
 159        rka = kzalloc(sizeof(*rka), GFP_KERNEL);
 160        if (!rka)
 161                goto error;
 162        rka->callout_info = kmemdup(callout_info, callout_len, GFP_KERNEL);
 163        if (!rka->callout_info)
 164                goto error_free_rka;
 165        rka->callout_len = callout_len;
 166        strlcpy(rka->op, op, sizeof(rka->op));
 167
 168        /* see if the calling process is already servicing the key request of
 169         * another process */
 170        if (cred->request_key_auth) {
 171                /* it is - use that instantiation context here too */
 172                down_read(&cred->request_key_auth->sem);
 173
 174                /* if the auth key has been revoked, then the key we're
 175                 * servicing is already instantiated */
 176                if (test_bit(KEY_FLAG_REVOKED,
 177                             &cred->request_key_auth->flags)) {
 178                        up_read(&cred->request_key_auth->sem);
 179                        ret = -EKEYREVOKED;
 180                        goto error_free_rka;
 181                }
 182
 183                irka = cred->request_key_auth->payload.data[0];
 184                rka->cred = get_cred(irka->cred);
 185                rka->pid = irka->pid;
 186
 187                up_read(&cred->request_key_auth->sem);
 188        }
 189        else {
 190                /* it isn't - use this process as the context */
 191                rka->cred = get_cred(cred);
 192                rka->pid = current->pid;
 193        }
 194
 195        rka->target_key = key_get(target);
 196        rka->dest_keyring = key_get(dest_keyring);
 197
 198        /* allocate the auth key */
 199        sprintf(desc, "%x", target->serial);
 200
 201        authkey = key_alloc(&key_type_request_key_auth, desc,
 202                            cred->fsuid, cred->fsgid, cred,
 203                            KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
 204                            KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL);
 205        if (IS_ERR(authkey)) {
 206                ret = PTR_ERR(authkey);
 207                goto error_free_rka;
 208        }
 209
 210        /* construct the auth key */
 211        ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
 212        if (ret < 0)
 213                goto error_put_authkey;
 214
 215        kleave(" = {%d,%d}", authkey->serial, refcount_read(&authkey->usage));
 216        return authkey;
 217
 218error_put_authkey:
 219        key_put(authkey);
 220error_free_rka:
 221        free_request_key_auth(rka);
 222error:
 223        kleave("= %d", ret);
 224        return ERR_PTR(ret);
 225}
 226
 227/*
 228 * Search the current process's keyrings for the authorisation key for
 229 * instantiation of a key.
 230 */
 231struct key *key_get_instantiation_authkey(key_serial_t target_id)
 232{
 233        char description[16];
 234        struct keyring_search_context ctx = {
 235                .index_key.type         = &key_type_request_key_auth,
 236                .index_key.description  = description,
 237                .cred                   = current_cred(),
 238                .match_data.cmp         = key_default_cmp,
 239                .match_data.raw_data    = description,
 240                .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
 241                .flags                  = KEYRING_SEARCH_DO_STATE_CHECK,
 242        };
 243        struct key *authkey;
 244        key_ref_t authkey_ref;
 245
 246        ctx.index_key.desc_len = sprintf(description, "%x", target_id);
 247
 248        authkey_ref = search_process_keyrings(&ctx);
 249
 250        if (IS_ERR(authkey_ref)) {
 251                authkey = ERR_CAST(authkey_ref);
 252                if (authkey == ERR_PTR(-EAGAIN))
 253                        authkey = ERR_PTR(-ENOKEY);
 254                goto error;
 255        }
 256
 257        authkey = key_ref_to_ptr(authkey_ref);
 258        if (test_bit(KEY_FLAG_REVOKED, &authkey->flags)) {
 259                key_put(authkey);
 260                authkey = ERR_PTR(-EKEYREVOKED);
 261        }
 262
 263error:
 264        return authkey;
 265}
 266