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_positive(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
 123static void free_request_key_auth(struct request_key_auth *rka)
 124{
 125        if (!rka)
 126                return;
 127        key_put(rka->target_key);
 128        key_put(rka->dest_keyring);
 129        if (rka->cred)
 130                put_cred(rka->cred);
 131        kfree(rka->callout_info);
 132        kfree(rka);
 133}
 134
 135/*
 136 * Destroy an instantiation authorisation token key.
 137 */
 138static void request_key_auth_destroy(struct key *key)
 139{
 140        struct request_key_auth *rka = key->payload.data[0];
 141
 142        kenter("{%d}", key->serial);
 143
 144        free_request_key_auth(rka);
 145}
 146
 147/*
 148 * Create an authorisation token for /sbin/request-key or whoever to gain
 149 * access to the caller's security data.
 150 */
 151struct key *request_key_auth_new(struct key *target, const void *callout_info,
 152                                 size_t callout_len, struct key *dest_keyring)
 153{
 154        struct request_key_auth *rka, *irka;
 155        const struct cred *cred = current->cred;
 156        struct key *authkey = NULL;
 157        char desc[20];
 158        int ret = -ENOMEM;
 159
 160        kenter("%d,", target->serial);
 161
 162        /* allocate a auth record */
 163        rka = kzalloc(sizeof(*rka), GFP_KERNEL);
 164        if (!rka)
 165                goto error;
 166        rka->callout_info = kmemdup(callout_info, callout_len, GFP_KERNEL);
 167        if (!rka->callout_info)
 168                goto error_free_rka;
 169        rka->callout_len = callout_len;
 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,
 180                             &cred->request_key_auth->flags)) {
 181                        up_read(&cred->request_key_auth->sem);
 182                        ret = -EKEYREVOKED;
 183                        goto error_free_rka;
 184                }
 185
 186                irka = cred->request_key_auth->payload.data[0];
 187                rka->cred = get_cred(irka->cred);
 188                rka->pid = irka->pid;
 189
 190                up_read(&cred->request_key_auth->sem);
 191        }
 192        else {
 193                /* it isn't - use this process as the context */
 194                rka->cred = get_cred(cred);
 195                rka->pid = current->pid;
 196        }
 197
 198        rka->target_key = key_get(target);
 199        rka->dest_keyring = key_get(dest_keyring);
 200
 201        /* allocate the auth key */
 202        sprintf(desc, "%x", target->serial);
 203
 204        authkey = key_alloc(&key_type_request_key_auth, desc,
 205                            cred->fsuid, cred->fsgid, cred,
 206                            KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
 207                            KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL);
 208        if (IS_ERR(authkey)) {
 209                ret = PTR_ERR(authkey);
 210                goto error_free_rka;
 211        }
 212
 213        /* construct the auth key */
 214        ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
 215        if (ret < 0)
 216                goto error_put_authkey;
 217
 218        kleave(" = {%d,%d}", authkey->serial, refcount_read(&authkey->usage));
 219        return authkey;
 220
 221error_put_authkey:
 222        key_put(authkey);
 223error_free_rka:
 224        free_request_key_auth(rka);
 225error:
 226        kleave("= %d", ret);
 227        return ERR_PTR(ret);
 228}
 229
 230/*
 231 * Search the current process's keyrings for the authorisation key for
 232 * instantiation of a key.
 233 */
 234struct key *key_get_instantiation_authkey(key_serial_t target_id)
 235{
 236        char description[16];
 237        struct keyring_search_context ctx = {
 238                .index_key.type         = &key_type_request_key_auth,
 239                .index_key.description  = description,
 240                .cred                   = current_cred(),
 241                .match_data.cmp         = key_default_cmp,
 242                .match_data.raw_data    = description,
 243                .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
 244                .flags                  = KEYRING_SEARCH_DO_STATE_CHECK,
 245        };
 246        struct key *authkey;
 247        key_ref_t authkey_ref;
 248
 249        sprintf(description, "%x", target_id);
 250
 251        authkey_ref = search_process_keyrings(&ctx);
 252
 253        if (IS_ERR(authkey_ref)) {
 254                authkey = ERR_CAST(authkey_ref);
 255                if (authkey == ERR_PTR(-EAGAIN))
 256                        authkey = ERR_PTR(-ENOKEY);
 257                goto error;
 258        }
 259
 260        authkey = key_ref_to_ptr(authkey_ref);
 261        if (test_bit(KEY_FLAG_REVOKED, &authkey->flags)) {
 262                key_put(authkey);
 263                authkey = ERR_PTR(-EKEYREVOKED);
 264        }
 265
 266error:
 267        return authkey;
 268}
 269