169664cf1SDavid Howells /* Keyring handling 21da177e4SLinus Torvalds * 369664cf1SDavid Howells * Copyright (C) 2004-2005, 2008 Red Hat, Inc. All Rights Reserved. 41da177e4SLinus Torvalds * Written by David Howells (dhowells@redhat.com) 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or 71da177e4SLinus Torvalds * modify it under the terms of the GNU General Public License 81da177e4SLinus Torvalds * as published by the Free Software Foundation; either version 91da177e4SLinus Torvalds * 2 of the License, or (at your option) any later version. 101da177e4SLinus Torvalds */ 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds #include <linux/module.h> 131da177e4SLinus Torvalds #include <linux/init.h> 141da177e4SLinus Torvalds #include <linux/sched.h> 151da177e4SLinus Torvalds #include <linux/slab.h> 1629db9190SDavid Howells #include <linux/security.h> 171da177e4SLinus Torvalds #include <linux/seq_file.h> 181da177e4SLinus Torvalds #include <linux/err.h> 19e9e349b0SDavid Howells #include <keys/keyring-type.h> 20512ea3bcSChihau Chau #include <linux/uaccess.h> 211da177e4SLinus Torvalds #include "internal.h" 221da177e4SLinus Torvalds 23f0641cbaSDavid Howells #define rcu_dereference_locked_keyring(keyring) \ 24f0641cbaSDavid Howells (rcu_dereference_protected( \ 25f0641cbaSDavid Howells (keyring)->payload.subscriptions, \ 26f0641cbaSDavid Howells rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem))) 27f0641cbaSDavid Howells 281da177e4SLinus Torvalds /* 29*973c9f4fSDavid Howells * When plumbing the depths of the key tree, this sets a hard limit 30*973c9f4fSDavid Howells * set on how deep we're willing to go. 311da177e4SLinus Torvalds */ 321da177e4SLinus Torvalds #define KEYRING_SEARCH_MAX_DEPTH 6 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds /* 35*973c9f4fSDavid Howells * We keep all named keyrings in a hash to speed looking them up. 361da177e4SLinus Torvalds */ 371da177e4SLinus Torvalds #define KEYRING_NAME_HASH_SIZE (1 << 5) 381da177e4SLinus Torvalds 391da177e4SLinus Torvalds static struct list_head keyring_name_hash[KEYRING_NAME_HASH_SIZE]; 401da177e4SLinus Torvalds static DEFINE_RWLOCK(keyring_name_lock); 411da177e4SLinus Torvalds 421da177e4SLinus Torvalds static inline unsigned keyring_hash(const char *desc) 431da177e4SLinus Torvalds { 441da177e4SLinus Torvalds unsigned bucket = 0; 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds for (; *desc; desc++) 471da177e4SLinus Torvalds bucket += (unsigned char)*desc; 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds return bucket & (KEYRING_NAME_HASH_SIZE - 1); 501da177e4SLinus Torvalds } 511da177e4SLinus Torvalds 521da177e4SLinus Torvalds /* 53*973c9f4fSDavid Howells * The keyring key type definition. Keyrings are simply keys of this type and 54*973c9f4fSDavid Howells * can be treated as ordinary keys in addition to having their own special 55*973c9f4fSDavid Howells * operations. 561da177e4SLinus Torvalds */ 571da177e4SLinus Torvalds static int keyring_instantiate(struct key *keyring, 581da177e4SLinus Torvalds const void *data, size_t datalen); 591da177e4SLinus Torvalds static int keyring_match(const struct key *keyring, const void *criterion); 6031204ed9SDavid Howells static void keyring_revoke(struct key *keyring); 611da177e4SLinus Torvalds static void keyring_destroy(struct key *keyring); 621da177e4SLinus Torvalds static void keyring_describe(const struct key *keyring, struct seq_file *m); 631da177e4SLinus Torvalds static long keyring_read(const struct key *keyring, 641da177e4SLinus Torvalds char __user *buffer, size_t buflen); 651da177e4SLinus Torvalds 661da177e4SLinus Torvalds struct key_type key_type_keyring = { 671da177e4SLinus Torvalds .name = "keyring", 681da177e4SLinus Torvalds .def_datalen = sizeof(struct keyring_list), 691da177e4SLinus Torvalds .instantiate = keyring_instantiate, 701da177e4SLinus Torvalds .match = keyring_match, 7131204ed9SDavid Howells .revoke = keyring_revoke, 721da177e4SLinus Torvalds .destroy = keyring_destroy, 731da177e4SLinus Torvalds .describe = keyring_describe, 741da177e4SLinus Torvalds .read = keyring_read, 751da177e4SLinus Torvalds }; 767318226eSDavid Howells EXPORT_SYMBOL(key_type_keyring); 777318226eSDavid Howells 781da177e4SLinus Torvalds /* 79*973c9f4fSDavid Howells * Semaphore to serialise link/link calls to prevent two link calls in parallel 80*973c9f4fSDavid Howells * introducing a cycle. 811da177e4SLinus Torvalds */ 821ae8f407SAdrian Bunk static DECLARE_RWSEM(keyring_serialise_link_sem); 831da177e4SLinus Torvalds 841da177e4SLinus Torvalds /* 85*973c9f4fSDavid Howells * Publish the name of a keyring so that it can be found by name (if it has 86*973c9f4fSDavid Howells * one). 871da177e4SLinus Torvalds */ 8869664cf1SDavid Howells static void keyring_publish_name(struct key *keyring) 891da177e4SLinus Torvalds { 901da177e4SLinus Torvalds int bucket; 911da177e4SLinus Torvalds 921da177e4SLinus Torvalds if (keyring->description) { 931da177e4SLinus Torvalds bucket = keyring_hash(keyring->description); 941da177e4SLinus Torvalds 951da177e4SLinus Torvalds write_lock(&keyring_name_lock); 961da177e4SLinus Torvalds 971da177e4SLinus Torvalds if (!keyring_name_hash[bucket].next) 981da177e4SLinus Torvalds INIT_LIST_HEAD(&keyring_name_hash[bucket]); 991da177e4SLinus Torvalds 1001da177e4SLinus Torvalds list_add_tail(&keyring->type_data.link, 1011da177e4SLinus Torvalds &keyring_name_hash[bucket]); 1021da177e4SLinus Torvalds 1031da177e4SLinus Torvalds write_unlock(&keyring_name_lock); 1041da177e4SLinus Torvalds } 105a8b17ed0SDavid Howells } 1061da177e4SLinus Torvalds 1071da177e4SLinus Torvalds /* 108*973c9f4fSDavid Howells * Initialise a keyring. 109*973c9f4fSDavid Howells * 110*973c9f4fSDavid Howells * Returns 0 on success, -EINVAL if given any data. 1111da177e4SLinus Torvalds */ 1121da177e4SLinus Torvalds static int keyring_instantiate(struct key *keyring, 1131da177e4SLinus Torvalds const void *data, size_t datalen) 1141da177e4SLinus Torvalds { 1151da177e4SLinus Torvalds int ret; 1161da177e4SLinus Torvalds 1171da177e4SLinus Torvalds ret = -EINVAL; 1181da177e4SLinus Torvalds if (datalen == 0) { 1191da177e4SLinus Torvalds /* make the keyring available by name if it has one */ 1201da177e4SLinus Torvalds keyring_publish_name(keyring); 1211da177e4SLinus Torvalds ret = 0; 1221da177e4SLinus Torvalds } 1231da177e4SLinus Torvalds 1241da177e4SLinus Torvalds return ret; 125a8b17ed0SDavid Howells } 1261da177e4SLinus Torvalds 1271da177e4SLinus Torvalds /* 128*973c9f4fSDavid Howells * Match keyrings on their name 1291da177e4SLinus Torvalds */ 1301da177e4SLinus Torvalds static int keyring_match(const struct key *keyring, const void *description) 1311da177e4SLinus Torvalds { 1321da177e4SLinus Torvalds return keyring->description && 1331da177e4SLinus Torvalds strcmp(keyring->description, description) == 0; 134a8b17ed0SDavid Howells } 1351da177e4SLinus Torvalds 1361da177e4SLinus Torvalds /* 137*973c9f4fSDavid Howells * Clean up a keyring when it is destroyed. Unpublish its name if it had one 138*973c9f4fSDavid Howells * and dispose of its data. 1391da177e4SLinus Torvalds */ 1401da177e4SLinus Torvalds static void keyring_destroy(struct key *keyring) 1411da177e4SLinus Torvalds { 1421da177e4SLinus Torvalds struct keyring_list *klist; 1431da177e4SLinus Torvalds int loop; 1441da177e4SLinus Torvalds 1451da177e4SLinus Torvalds if (keyring->description) { 1461da177e4SLinus Torvalds write_lock(&keyring_name_lock); 14794efe72fSDavid Howells 14894efe72fSDavid Howells if (keyring->type_data.link.next != NULL && 14994efe72fSDavid Howells !list_empty(&keyring->type_data.link)) 1501da177e4SLinus Torvalds list_del(&keyring->type_data.link); 15194efe72fSDavid Howells 1521da177e4SLinus Torvalds write_unlock(&keyring_name_lock); 1531da177e4SLinus Torvalds } 1541da177e4SLinus Torvalds 155e7b0a61bSPaul E. McKenney klist = rcu_dereference_check(keyring->payload.subscriptions, 156e7b0a61bSPaul E. McKenney rcu_read_lock_held() || 157e7b0a61bSPaul E. McKenney atomic_read(&keyring->usage) == 0); 1581da177e4SLinus Torvalds if (klist) { 1591da177e4SLinus Torvalds for (loop = klist->nkeys - 1; loop >= 0; loop--) 1601da177e4SLinus Torvalds key_put(klist->keys[loop]); 1611da177e4SLinus Torvalds kfree(klist); 1621da177e4SLinus Torvalds } 163a8b17ed0SDavid Howells } 1641da177e4SLinus Torvalds 1651da177e4SLinus Torvalds /* 166*973c9f4fSDavid Howells * Describe a keyring for /proc. 1671da177e4SLinus Torvalds */ 1681da177e4SLinus Torvalds static void keyring_describe(const struct key *keyring, struct seq_file *m) 1691da177e4SLinus Torvalds { 1701da177e4SLinus Torvalds struct keyring_list *klist; 1711da177e4SLinus Torvalds 172c8563473Swzt.wzt@gmail.com if (keyring->description) 1731da177e4SLinus Torvalds seq_puts(m, keyring->description); 174c8563473Swzt.wzt@gmail.com else 1751da177e4SLinus Torvalds seq_puts(m, "[anon]"); 1761da177e4SLinus Torvalds 17776d8aeabSDavid Howells rcu_read_lock(); 17876d8aeabSDavid Howells klist = rcu_dereference(keyring->payload.subscriptions); 1791da177e4SLinus Torvalds if (klist) 1801da177e4SLinus Torvalds seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys); 1811da177e4SLinus Torvalds else 1821da177e4SLinus Torvalds seq_puts(m, ": empty"); 18376d8aeabSDavid Howells rcu_read_unlock(); 184a8b17ed0SDavid Howells } 1851da177e4SLinus Torvalds 1861da177e4SLinus Torvalds /* 187*973c9f4fSDavid Howells * Read a list of key IDs from the keyring's contents in binary form 188*973c9f4fSDavid Howells * 189*973c9f4fSDavid Howells * The keyring's semaphore is read-locked by the caller. 1901da177e4SLinus Torvalds */ 1911da177e4SLinus Torvalds static long keyring_read(const struct key *keyring, 1921da177e4SLinus Torvalds char __user *buffer, size_t buflen) 1931da177e4SLinus Torvalds { 1941da177e4SLinus Torvalds struct keyring_list *klist; 1951da177e4SLinus Torvalds struct key *key; 1961da177e4SLinus Torvalds size_t qty, tmp; 1971da177e4SLinus Torvalds int loop, ret; 1981da177e4SLinus Torvalds 1991da177e4SLinus Torvalds ret = 0; 200f0641cbaSDavid Howells klist = rcu_dereference_locked_keyring(keyring); 2011da177e4SLinus Torvalds if (klist) { 2021da177e4SLinus Torvalds /* calculate how much data we could return */ 2031da177e4SLinus Torvalds qty = klist->nkeys * sizeof(key_serial_t); 2041da177e4SLinus Torvalds 2051da177e4SLinus Torvalds if (buffer && buflen > 0) { 2061da177e4SLinus Torvalds if (buflen > qty) 2071da177e4SLinus Torvalds buflen = qty; 2081da177e4SLinus Torvalds 2091da177e4SLinus Torvalds /* copy the IDs of the subscribed keys into the 2101da177e4SLinus Torvalds * buffer */ 2111da177e4SLinus Torvalds ret = -EFAULT; 2121da177e4SLinus Torvalds 2131da177e4SLinus Torvalds for (loop = 0; loop < klist->nkeys; loop++) { 2141da177e4SLinus Torvalds key = klist->keys[loop]; 2151da177e4SLinus Torvalds 2161da177e4SLinus Torvalds tmp = sizeof(key_serial_t); 2171da177e4SLinus Torvalds if (tmp > buflen) 2181da177e4SLinus Torvalds tmp = buflen; 2191da177e4SLinus Torvalds 2201da177e4SLinus Torvalds if (copy_to_user(buffer, 2211da177e4SLinus Torvalds &key->serial, 2221da177e4SLinus Torvalds tmp) != 0) 2231da177e4SLinus Torvalds goto error; 2241da177e4SLinus Torvalds 2251da177e4SLinus Torvalds buflen -= tmp; 2261da177e4SLinus Torvalds if (buflen == 0) 2271da177e4SLinus Torvalds break; 2281da177e4SLinus Torvalds buffer += tmp; 2291da177e4SLinus Torvalds } 2301da177e4SLinus Torvalds } 2311da177e4SLinus Torvalds 2321da177e4SLinus Torvalds ret = qty; 2331da177e4SLinus Torvalds } 2341da177e4SLinus Torvalds 2351da177e4SLinus Torvalds error: 2361da177e4SLinus Torvalds return ret; 237a8b17ed0SDavid Howells } 2381da177e4SLinus Torvalds 2391da177e4SLinus Torvalds /* 240*973c9f4fSDavid Howells * Allocate a keyring and link into the destination keyring. 2411da177e4SLinus Torvalds */ 2421da177e4SLinus Torvalds struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, 243d84f4f99SDavid Howells const struct cred *cred, unsigned long flags, 244d720024eSMichael LeMay struct key *dest) 2451da177e4SLinus Torvalds { 2461da177e4SLinus Torvalds struct key *keyring; 2471da177e4SLinus Torvalds int ret; 2481da177e4SLinus Torvalds 2491da177e4SLinus Torvalds keyring = key_alloc(&key_type_keyring, description, 250d84f4f99SDavid Howells uid, gid, cred, 25129db9190SDavid Howells (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, 2527e047ef5SDavid Howells flags); 2531da177e4SLinus Torvalds 2541da177e4SLinus Torvalds if (!IS_ERR(keyring)) { 2553e30148cSDavid Howells ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL); 2561da177e4SLinus Torvalds if (ret < 0) { 2571da177e4SLinus Torvalds key_put(keyring); 2581da177e4SLinus Torvalds keyring = ERR_PTR(ret); 2591da177e4SLinus Torvalds } 2601da177e4SLinus Torvalds } 2611da177e4SLinus Torvalds 2621da177e4SLinus Torvalds return keyring; 263a8b17ed0SDavid Howells } 2641da177e4SLinus Torvalds 265*973c9f4fSDavid Howells /** 266*973c9f4fSDavid Howells * keyring_search_aux - Search a keyring tree for a key matching some criteria 267*973c9f4fSDavid Howells * @keyring_ref: A pointer to the keyring with possession indicator. 268*973c9f4fSDavid Howells * @cred: The credentials to use for permissions checks. 269*973c9f4fSDavid Howells * @type: The type of key to search for. 270*973c9f4fSDavid Howells * @description: Parameter for @match. 271*973c9f4fSDavid Howells * @match: Function to rule on whether or not a key is the one required. 272*973c9f4fSDavid Howells * 273*973c9f4fSDavid Howells * Search the supplied keyring tree for a key that matches the criteria given. 274*973c9f4fSDavid Howells * The root keyring and any linked keyrings must grant Search permission to the 275*973c9f4fSDavid Howells * caller to be searchable and keys can only be found if they too grant Search 276*973c9f4fSDavid Howells * to the caller. The possession flag on the root keyring pointer controls use 277*973c9f4fSDavid Howells * of the possessor bits in permissions checking of the entire tree. In 278*973c9f4fSDavid Howells * addition, the LSM gets to forbid keyring searches and key matches. 279*973c9f4fSDavid Howells * 280*973c9f4fSDavid Howells * The search is performed as a breadth-then-depth search up to the prescribed 281*973c9f4fSDavid Howells * limit (KEYRING_SEARCH_MAX_DEPTH). 282*973c9f4fSDavid Howells * 283*973c9f4fSDavid Howells * Keys are matched to the type provided and are then filtered by the match 284*973c9f4fSDavid Howells * function, which is given the description to use in any way it sees fit. The 285*973c9f4fSDavid Howells * match function may use any attributes of a key that it wishes to to 286*973c9f4fSDavid Howells * determine the match. Normally the match function from the key type would be 287*973c9f4fSDavid Howells * used. 288*973c9f4fSDavid Howells * 289*973c9f4fSDavid Howells * RCU is used to prevent the keyring key lists from disappearing without the 290*973c9f4fSDavid Howells * need to take lots of locks. 291*973c9f4fSDavid Howells * 292*973c9f4fSDavid Howells * Returns a pointer to the found key and increments the key usage count if 293*973c9f4fSDavid Howells * successful; -EAGAIN if no matching keys were found, or if expired or revoked 294*973c9f4fSDavid Howells * keys were found; -ENOKEY if only negative keys were found; -ENOTDIR if the 295*973c9f4fSDavid Howells * specified keyring wasn't a keyring. 296*973c9f4fSDavid Howells * 297*973c9f4fSDavid Howells * In the case of a successful return, the possession attribute from 298*973c9f4fSDavid Howells * @keyring_ref is propagated to the returned key reference. 2991da177e4SLinus Torvalds */ 300664cceb0SDavid Howells key_ref_t keyring_search_aux(key_ref_t keyring_ref, 301d84f4f99SDavid Howells const struct cred *cred, 3021da177e4SLinus Torvalds struct key_type *type, 3031da177e4SLinus Torvalds const void *description, 3041da177e4SLinus Torvalds key_match_func_t match) 3051da177e4SLinus Torvalds { 3061da177e4SLinus Torvalds struct { 30776d8aeabSDavid Howells struct keyring_list *keylist; 3081da177e4SLinus Torvalds int kix; 3091da177e4SLinus Torvalds } stack[KEYRING_SEARCH_MAX_DEPTH]; 3101da177e4SLinus Torvalds 3111da177e4SLinus Torvalds struct keyring_list *keylist; 3121da177e4SLinus Torvalds struct timespec now; 313dceba994SKevin Coffman unsigned long possessed, kflags; 314664cceb0SDavid Howells struct key *keyring, *key; 315664cceb0SDavid Howells key_ref_t key_ref; 3161da177e4SLinus Torvalds long err; 31776d8aeabSDavid Howells int sp, kix; 3181da177e4SLinus Torvalds 319664cceb0SDavid Howells keyring = key_ref_to_ptr(keyring_ref); 320664cceb0SDavid Howells possessed = is_key_possessed(keyring_ref); 3211da177e4SLinus Torvalds key_check(keyring); 3221da177e4SLinus Torvalds 3231da177e4SLinus Torvalds /* top keyring must have search permission to begin the search */ 324d84f4f99SDavid Howells err = key_task_permission(keyring_ref, cred, KEY_SEARCH); 32529db9190SDavid Howells if (err < 0) { 32629db9190SDavid Howells key_ref = ERR_PTR(err); 3271da177e4SLinus Torvalds goto error; 32829db9190SDavid Howells } 3291da177e4SLinus Torvalds 330664cceb0SDavid Howells key_ref = ERR_PTR(-ENOTDIR); 3311da177e4SLinus Torvalds if (keyring->type != &key_type_keyring) 3321da177e4SLinus Torvalds goto error; 3331da177e4SLinus Torvalds 334664cceb0SDavid Howells rcu_read_lock(); 335664cceb0SDavid Howells 3361da177e4SLinus Torvalds now = current_kernel_time(); 3371da177e4SLinus Torvalds err = -EAGAIN; 3381da177e4SLinus Torvalds sp = 0; 3391da177e4SLinus Torvalds 340dceba994SKevin Coffman /* firstly we should check to see if this top-level keyring is what we 341dceba994SKevin Coffman * are looking for */ 342dceba994SKevin Coffman key_ref = ERR_PTR(-EAGAIN); 343dceba994SKevin Coffman kflags = keyring->flags; 344dceba994SKevin Coffman if (keyring->type == type && match(keyring, description)) { 345dceba994SKevin Coffman key = keyring; 346dceba994SKevin Coffman 347dceba994SKevin Coffman /* check it isn't negative and hasn't expired or been 348dceba994SKevin Coffman * revoked */ 349dceba994SKevin Coffman if (kflags & (1 << KEY_FLAG_REVOKED)) 350dceba994SKevin Coffman goto error_2; 351dceba994SKevin Coffman if (key->expiry && now.tv_sec >= key->expiry) 352dceba994SKevin Coffman goto error_2; 353dceba994SKevin Coffman key_ref = ERR_PTR(-ENOKEY); 354dceba994SKevin Coffman if (kflags & (1 << KEY_FLAG_NEGATIVE)) 355dceba994SKevin Coffman goto error_2; 356dceba994SKevin Coffman goto found; 357dceba994SKevin Coffman } 358dceba994SKevin Coffman 359dceba994SKevin Coffman /* otherwise, the top keyring must not be revoked, expired, or 360dceba994SKevin Coffman * negatively instantiated if we are to search it */ 361dceba994SKevin Coffman key_ref = ERR_PTR(-EAGAIN); 362dceba994SKevin Coffman if (kflags & ((1 << KEY_FLAG_REVOKED) | (1 << KEY_FLAG_NEGATIVE)) || 363dceba994SKevin Coffman (keyring->expiry && now.tv_sec >= keyring->expiry)) 364dceba994SKevin Coffman goto error_2; 365dceba994SKevin Coffman 3661da177e4SLinus Torvalds /* start processing a new keyring */ 3671da177e4SLinus Torvalds descend: 36876d8aeabSDavid Howells if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) 3691da177e4SLinus Torvalds goto not_this_keyring; 3701da177e4SLinus Torvalds 37176d8aeabSDavid Howells keylist = rcu_dereference(keyring->payload.subscriptions); 3721da177e4SLinus Torvalds if (!keylist) 3731da177e4SLinus Torvalds goto not_this_keyring; 3741da177e4SLinus Torvalds 3751da177e4SLinus Torvalds /* iterate through the keys in this keyring first */ 3761da177e4SLinus Torvalds for (kix = 0; kix < keylist->nkeys; kix++) { 3771da177e4SLinus Torvalds key = keylist->keys[kix]; 378dceba994SKevin Coffman kflags = key->flags; 3791da177e4SLinus Torvalds 3801da177e4SLinus Torvalds /* ignore keys not of this type */ 3811da177e4SLinus Torvalds if (key->type != type) 3821da177e4SLinus Torvalds continue; 3831da177e4SLinus Torvalds 3841da177e4SLinus Torvalds /* skip revoked keys and expired keys */ 385dceba994SKevin Coffman if (kflags & (1 << KEY_FLAG_REVOKED)) 3861da177e4SLinus Torvalds continue; 3871da177e4SLinus Torvalds 3881da177e4SLinus Torvalds if (key->expiry && now.tv_sec >= key->expiry) 3891da177e4SLinus Torvalds continue; 3901da177e4SLinus Torvalds 3911da177e4SLinus Torvalds /* keys that don't match */ 3921da177e4SLinus Torvalds if (!match(key, description)) 3931da177e4SLinus Torvalds continue; 3941da177e4SLinus Torvalds 3951da177e4SLinus Torvalds /* key must have search permissions */ 39629db9190SDavid Howells if (key_task_permission(make_key_ref(key, possessed), 397d84f4f99SDavid Howells cred, KEY_SEARCH) < 0) 3981da177e4SLinus Torvalds continue; 3991da177e4SLinus Torvalds 400dceba994SKevin Coffman /* we set a different error code if we pass a negative key */ 401dceba994SKevin Coffman if (kflags & (1 << KEY_FLAG_NEGATIVE)) { 4021da177e4SLinus Torvalds err = -ENOKEY; 4031da177e4SLinus Torvalds continue; 4041da177e4SLinus Torvalds } 4051da177e4SLinus Torvalds 4061da177e4SLinus Torvalds goto found; 4071da177e4SLinus Torvalds } 4081da177e4SLinus Torvalds 4091da177e4SLinus Torvalds /* search through the keyrings nested in this one */ 4101da177e4SLinus Torvalds kix = 0; 4111da177e4SLinus Torvalds ascend: 41276d8aeabSDavid Howells for (; kix < keylist->nkeys; kix++) { 4131da177e4SLinus Torvalds key = keylist->keys[kix]; 4141da177e4SLinus Torvalds if (key->type != &key_type_keyring) 41576d8aeabSDavid Howells continue; 4161da177e4SLinus Torvalds 4171da177e4SLinus Torvalds /* recursively search nested keyrings 4181da177e4SLinus Torvalds * - only search keyrings for which we have search permission 4191da177e4SLinus Torvalds */ 4201da177e4SLinus Torvalds if (sp >= KEYRING_SEARCH_MAX_DEPTH) 42176d8aeabSDavid Howells continue; 4221da177e4SLinus Torvalds 4230f6ed7c2SDavid Howells if (key_task_permission(make_key_ref(key, possessed), 424d84f4f99SDavid Howells cred, KEY_SEARCH) < 0) 42576d8aeabSDavid Howells continue; 4261da177e4SLinus Torvalds 4271da177e4SLinus Torvalds /* stack the current position */ 42876d8aeabSDavid Howells stack[sp].keylist = keylist; 4291da177e4SLinus Torvalds stack[sp].kix = kix; 4301da177e4SLinus Torvalds sp++; 4311da177e4SLinus Torvalds 4321da177e4SLinus Torvalds /* begin again with the new keyring */ 4331da177e4SLinus Torvalds keyring = key; 4341da177e4SLinus Torvalds goto descend; 4351da177e4SLinus Torvalds } 4361da177e4SLinus Torvalds 4371da177e4SLinus Torvalds /* the keyring we're looking at was disqualified or didn't contain a 4381da177e4SLinus Torvalds * matching key */ 4391da177e4SLinus Torvalds not_this_keyring: 4401da177e4SLinus Torvalds if (sp > 0) { 4411da177e4SLinus Torvalds /* resume the processing of a keyring higher up in the tree */ 4421da177e4SLinus Torvalds sp--; 44376d8aeabSDavid Howells keylist = stack[sp].keylist; 4441da177e4SLinus Torvalds kix = stack[sp].kix + 1; 4451da177e4SLinus Torvalds goto ascend; 4461da177e4SLinus Torvalds } 4471da177e4SLinus Torvalds 448664cceb0SDavid Howells key_ref = ERR_PTR(err); 449664cceb0SDavid Howells goto error_2; 4501da177e4SLinus Torvalds 4511da177e4SLinus Torvalds /* we found a viable match */ 4521da177e4SLinus Torvalds found: 4531da177e4SLinus Torvalds atomic_inc(&key->usage); 4541da177e4SLinus Torvalds key_check(key); 455664cceb0SDavid Howells key_ref = make_key_ref(key, possessed); 456664cceb0SDavid Howells error_2: 45776d8aeabSDavid Howells rcu_read_unlock(); 458664cceb0SDavid Howells error: 459664cceb0SDavid Howells return key_ref; 460a8b17ed0SDavid Howells } 4611da177e4SLinus Torvalds 462*973c9f4fSDavid Howells /** 463*973c9f4fSDavid Howells * keyring_search - Search the supplied keyring tree for a matching key 464*973c9f4fSDavid Howells * @keyring: The root of the keyring tree to be searched. 465*973c9f4fSDavid Howells * @type: The type of keyring we want to find. 466*973c9f4fSDavid Howells * @description: The name of the keyring we want to find. 467*973c9f4fSDavid Howells * 468*973c9f4fSDavid Howells * As keyring_search_aux() above, but using the current task's credentials and 469*973c9f4fSDavid Howells * type's default matching function. 4701da177e4SLinus Torvalds */ 471664cceb0SDavid Howells key_ref_t keyring_search(key_ref_t keyring, 4721da177e4SLinus Torvalds struct key_type *type, 4731da177e4SLinus Torvalds const char *description) 4741da177e4SLinus Torvalds { 4753e30148cSDavid Howells if (!type->match) 4763e30148cSDavid Howells return ERR_PTR(-ENOKEY); 4773e30148cSDavid Howells 478d84f4f99SDavid Howells return keyring_search_aux(keyring, current->cred, 4793e30148cSDavid Howells type, description, type->match); 480a8b17ed0SDavid Howells } 4811da177e4SLinus Torvalds EXPORT_SYMBOL(keyring_search); 4821da177e4SLinus Torvalds 4831da177e4SLinus Torvalds /* 484*973c9f4fSDavid Howells * Search the given keyring only (no recursion). 485*973c9f4fSDavid Howells * 486*973c9f4fSDavid Howells * The caller must guarantee that the keyring is a keyring and that the 487*973c9f4fSDavid Howells * permission is granted to search the keyring as no check is made here. 488*973c9f4fSDavid Howells * 489*973c9f4fSDavid Howells * RCU is used to make it unnecessary to lock the keyring key list here. 490*973c9f4fSDavid Howells * 491*973c9f4fSDavid Howells * Returns a pointer to the found key with usage count incremented if 492*973c9f4fSDavid Howells * successful and returns -ENOKEY if not found. Revoked keys and keys not 493*973c9f4fSDavid Howells * providing the requested permission are skipped over. 494*973c9f4fSDavid Howells * 495*973c9f4fSDavid Howells * If successful, the possession indicator is propagated from the keyring ref 496*973c9f4fSDavid Howells * to the returned key reference. 4971da177e4SLinus Torvalds */ 498664cceb0SDavid Howells key_ref_t __keyring_search_one(key_ref_t keyring_ref, 4991da177e4SLinus Torvalds const struct key_type *ktype, 5001da177e4SLinus Torvalds const char *description, 5011da177e4SLinus Torvalds key_perm_t perm) 5021da177e4SLinus Torvalds { 5031da177e4SLinus Torvalds struct keyring_list *klist; 504664cceb0SDavid Howells unsigned long possessed; 505664cceb0SDavid Howells struct key *keyring, *key; 5061da177e4SLinus Torvalds int loop; 5071da177e4SLinus Torvalds 508664cceb0SDavid Howells keyring = key_ref_to_ptr(keyring_ref); 509664cceb0SDavid Howells possessed = is_key_possessed(keyring_ref); 510664cceb0SDavid Howells 51176d8aeabSDavid Howells rcu_read_lock(); 51276d8aeabSDavid Howells 51376d8aeabSDavid Howells klist = rcu_dereference(keyring->payload.subscriptions); 5141da177e4SLinus Torvalds if (klist) { 5151da177e4SLinus Torvalds for (loop = 0; loop < klist->nkeys; loop++) { 5161da177e4SLinus Torvalds key = klist->keys[loop]; 5171da177e4SLinus Torvalds 5181da177e4SLinus Torvalds if (key->type == ktype && 5193e30148cSDavid Howells (!key->type->match || 5203e30148cSDavid Howells key->type->match(key, description)) && 521664cceb0SDavid Howells key_permission(make_key_ref(key, possessed), 522db1d1d57SDavid Howells perm) == 0 && 52376d8aeabSDavid Howells !test_bit(KEY_FLAG_REVOKED, &key->flags) 5241da177e4SLinus Torvalds ) 5251da177e4SLinus Torvalds goto found; 5261da177e4SLinus Torvalds } 5271da177e4SLinus Torvalds } 5281da177e4SLinus Torvalds 529664cceb0SDavid Howells rcu_read_unlock(); 530664cceb0SDavid Howells return ERR_PTR(-ENOKEY); 5311da177e4SLinus Torvalds 5321da177e4SLinus Torvalds found: 5331da177e4SLinus Torvalds atomic_inc(&key->usage); 53476d8aeabSDavid Howells rcu_read_unlock(); 535664cceb0SDavid Howells return make_key_ref(key, possessed); 536a8b17ed0SDavid Howells } 5371da177e4SLinus Torvalds 5381da177e4SLinus Torvalds /* 539*973c9f4fSDavid Howells * Find a keyring with the specified name. 540*973c9f4fSDavid Howells * 541*973c9f4fSDavid Howells * All named keyrings in the current user namespace are searched, provided they 542*973c9f4fSDavid Howells * grant Search permission directly to the caller (unless this check is 543*973c9f4fSDavid Howells * skipped). Keyrings whose usage points have reached zero or who have been 544*973c9f4fSDavid Howells * revoked are skipped. 545*973c9f4fSDavid Howells * 546*973c9f4fSDavid Howells * Returns a pointer to the keyring with the keyring's refcount having being 547*973c9f4fSDavid Howells * incremented on success. -ENOKEY is returned if a key could not be found. 5481da177e4SLinus Torvalds */ 54969664cf1SDavid Howells struct key *find_keyring_by_name(const char *name, bool skip_perm_check) 5501da177e4SLinus Torvalds { 5511da177e4SLinus Torvalds struct key *keyring; 5521da177e4SLinus Torvalds int bucket; 5531da177e4SLinus Torvalds 5541da177e4SLinus Torvalds if (!name) 555cea7daa3SToshiyuki Okajima return ERR_PTR(-EINVAL); 5561da177e4SLinus Torvalds 5571da177e4SLinus Torvalds bucket = keyring_hash(name); 5581da177e4SLinus Torvalds 5591da177e4SLinus Torvalds read_lock(&keyring_name_lock); 5601da177e4SLinus Torvalds 5611da177e4SLinus Torvalds if (keyring_name_hash[bucket].next) { 5621da177e4SLinus Torvalds /* search this hash bucket for a keyring with a matching name 5631da177e4SLinus Torvalds * that's readable and that hasn't been revoked */ 5641da177e4SLinus Torvalds list_for_each_entry(keyring, 5651da177e4SLinus Torvalds &keyring_name_hash[bucket], 5661da177e4SLinus Torvalds type_data.link 5671da177e4SLinus Torvalds ) { 5682ea190d0SSerge E. Hallyn if (keyring->user->user_ns != current_user_ns()) 5692ea190d0SSerge E. Hallyn continue; 5702ea190d0SSerge E. Hallyn 57176d8aeabSDavid Howells if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) 5721da177e4SLinus Torvalds continue; 5731da177e4SLinus Torvalds 5741da177e4SLinus Torvalds if (strcmp(keyring->description, name) != 0) 5751da177e4SLinus Torvalds continue; 5761da177e4SLinus Torvalds 57769664cf1SDavid Howells if (!skip_perm_check && 57869664cf1SDavid Howells key_permission(make_key_ref(keyring, 0), 57929db9190SDavid Howells KEY_SEARCH) < 0) 5801da177e4SLinus Torvalds continue; 5811da177e4SLinus Torvalds 582cea7daa3SToshiyuki Okajima /* we've got a match but we might end up racing with 583cea7daa3SToshiyuki Okajima * key_cleanup() if the keyring is currently 'dead' 584cea7daa3SToshiyuki Okajima * (ie. it has a zero usage count) */ 585cea7daa3SToshiyuki Okajima if (!atomic_inc_not_zero(&keyring->usage)) 586cea7daa3SToshiyuki Okajima continue; 587cea7daa3SToshiyuki Okajima goto out; 5881da177e4SLinus Torvalds } 5891da177e4SLinus Torvalds } 5901da177e4SLinus Torvalds 5911da177e4SLinus Torvalds keyring = ERR_PTR(-ENOKEY); 592cea7daa3SToshiyuki Okajima out: 593cea7daa3SToshiyuki Okajima read_unlock(&keyring_name_lock); 5941da177e4SLinus Torvalds return keyring; 595a8b17ed0SDavid Howells } 5961da177e4SLinus Torvalds 5971da177e4SLinus Torvalds /* 598*973c9f4fSDavid Howells * See if a cycle will will be created by inserting acyclic tree B in acyclic 599*973c9f4fSDavid Howells * tree A at the topmost level (ie: as a direct child of A). 600*973c9f4fSDavid Howells * 601*973c9f4fSDavid Howells * Since we are adding B to A at the top level, checking for cycles should just 602*973c9f4fSDavid Howells * be a matter of seeing if node A is somewhere in tree B. 6031da177e4SLinus Torvalds */ 6041da177e4SLinus Torvalds static int keyring_detect_cycle(struct key *A, struct key *B) 6051da177e4SLinus Torvalds { 6061da177e4SLinus Torvalds struct { 60776d8aeabSDavid Howells struct keyring_list *keylist; 6081da177e4SLinus Torvalds int kix; 6091da177e4SLinus Torvalds } stack[KEYRING_SEARCH_MAX_DEPTH]; 6101da177e4SLinus Torvalds 6111da177e4SLinus Torvalds struct keyring_list *keylist; 6121da177e4SLinus Torvalds struct key *subtree, *key; 6131da177e4SLinus Torvalds int sp, kix, ret; 6141da177e4SLinus Torvalds 61576d8aeabSDavid Howells rcu_read_lock(); 61676d8aeabSDavid Howells 6171da177e4SLinus Torvalds ret = -EDEADLK; 6181da177e4SLinus Torvalds if (A == B) 61976d8aeabSDavid Howells goto cycle_detected; 6201da177e4SLinus Torvalds 6211da177e4SLinus Torvalds subtree = B; 6221da177e4SLinus Torvalds sp = 0; 6231da177e4SLinus Torvalds 6241da177e4SLinus Torvalds /* start processing a new keyring */ 6251da177e4SLinus Torvalds descend: 62676d8aeabSDavid Howells if (test_bit(KEY_FLAG_REVOKED, &subtree->flags)) 6271da177e4SLinus Torvalds goto not_this_keyring; 6281da177e4SLinus Torvalds 62976d8aeabSDavid Howells keylist = rcu_dereference(subtree->payload.subscriptions); 6301da177e4SLinus Torvalds if (!keylist) 6311da177e4SLinus Torvalds goto not_this_keyring; 6321da177e4SLinus Torvalds kix = 0; 6331da177e4SLinus Torvalds 6341da177e4SLinus Torvalds ascend: 6351da177e4SLinus Torvalds /* iterate through the remaining keys in this keyring */ 6361da177e4SLinus Torvalds for (; kix < keylist->nkeys; kix++) { 6371da177e4SLinus Torvalds key = keylist->keys[kix]; 6381da177e4SLinus Torvalds 6391da177e4SLinus Torvalds if (key == A) 6401da177e4SLinus Torvalds goto cycle_detected; 6411da177e4SLinus Torvalds 6421da177e4SLinus Torvalds /* recursively check nested keyrings */ 6431da177e4SLinus Torvalds if (key->type == &key_type_keyring) { 6441da177e4SLinus Torvalds if (sp >= KEYRING_SEARCH_MAX_DEPTH) 6451da177e4SLinus Torvalds goto too_deep; 6461da177e4SLinus Torvalds 6471da177e4SLinus Torvalds /* stack the current position */ 64876d8aeabSDavid Howells stack[sp].keylist = keylist; 6491da177e4SLinus Torvalds stack[sp].kix = kix; 6501da177e4SLinus Torvalds sp++; 6511da177e4SLinus Torvalds 6521da177e4SLinus Torvalds /* begin again with the new keyring */ 6531da177e4SLinus Torvalds subtree = key; 6541da177e4SLinus Torvalds goto descend; 6551da177e4SLinus Torvalds } 6561da177e4SLinus Torvalds } 6571da177e4SLinus Torvalds 6581da177e4SLinus Torvalds /* the keyring we're looking at was disqualified or didn't contain a 6591da177e4SLinus Torvalds * matching key */ 6601da177e4SLinus Torvalds not_this_keyring: 6611da177e4SLinus Torvalds if (sp > 0) { 6621da177e4SLinus Torvalds /* resume the checking of a keyring higher up in the tree */ 6631da177e4SLinus Torvalds sp--; 66476d8aeabSDavid Howells keylist = stack[sp].keylist; 6651da177e4SLinus Torvalds kix = stack[sp].kix + 1; 6661da177e4SLinus Torvalds goto ascend; 6671da177e4SLinus Torvalds } 6681da177e4SLinus Torvalds 6691da177e4SLinus Torvalds ret = 0; /* no cycles detected */ 6701da177e4SLinus Torvalds 6711da177e4SLinus Torvalds error: 67276d8aeabSDavid Howells rcu_read_unlock(); 6731da177e4SLinus Torvalds return ret; 6741da177e4SLinus Torvalds 6751da177e4SLinus Torvalds too_deep: 6761da177e4SLinus Torvalds ret = -ELOOP; 67776d8aeabSDavid Howells goto error; 67876d8aeabSDavid Howells 6791da177e4SLinus Torvalds cycle_detected: 6801da177e4SLinus Torvalds ret = -EDEADLK; 6811da177e4SLinus Torvalds goto error; 682a8b17ed0SDavid Howells } 6831da177e4SLinus Torvalds 68476d8aeabSDavid Howells /* 685*973c9f4fSDavid Howells * Dispose of a keyring list after the RCU grace period, freeing the unlinked 686cab8eb59SDavid Howells * key 687cab8eb59SDavid Howells */ 688cab8eb59SDavid Howells static void keyring_unlink_rcu_disposal(struct rcu_head *rcu) 689cab8eb59SDavid Howells { 690cab8eb59SDavid Howells struct keyring_list *klist = 691cab8eb59SDavid Howells container_of(rcu, struct keyring_list, rcu); 692cab8eb59SDavid Howells 6934be929beSAlexey Dobriyan if (klist->delkey != USHRT_MAX) 694cab8eb59SDavid Howells key_put(klist->keys[klist->delkey]); 695cab8eb59SDavid Howells kfree(klist); 696f70e2e06SDavid Howells } 697cab8eb59SDavid Howells 698cab8eb59SDavid Howells /* 699*973c9f4fSDavid Howells * Preallocate memory so that a key can be linked into to a keyring. 7001da177e4SLinus Torvalds */ 701f70e2e06SDavid Howells int __key_link_begin(struct key *keyring, const struct key_type *type, 702f70e2e06SDavid Howells const char *description, 703f70e2e06SDavid Howells struct keyring_list **_prealloc) 704f70e2e06SDavid Howells __acquires(&keyring->sem) 7051da177e4SLinus Torvalds { 7061da177e4SLinus Torvalds struct keyring_list *klist, *nklist; 7071da177e4SLinus Torvalds unsigned max; 7081da177e4SLinus Torvalds size_t size; 709cab8eb59SDavid Howells int loop, ret; 7101da177e4SLinus Torvalds 711f70e2e06SDavid Howells kenter("%d,%s,%s,", key_serial(keyring), type->name, description); 712f70e2e06SDavid Howells 713f70e2e06SDavid Howells if (keyring->type != &key_type_keyring) 714f70e2e06SDavid Howells return -ENOTDIR; 715f70e2e06SDavid Howells 716f70e2e06SDavid Howells down_write(&keyring->sem); 717f70e2e06SDavid Howells 7181da177e4SLinus Torvalds ret = -EKEYREVOKED; 71976d8aeabSDavid Howells if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) 720f70e2e06SDavid Howells goto error_krsem; 7211da177e4SLinus Torvalds 722f70e2e06SDavid Howells /* serialise link/link calls to prevent parallel calls causing a cycle 723f70e2e06SDavid Howells * when linking two keyring in opposite orders */ 724f70e2e06SDavid Howells if (type == &key_type_keyring) 7251da177e4SLinus Torvalds down_write(&keyring_serialise_link_sem); 7261da177e4SLinus Torvalds 727f70e2e06SDavid Howells klist = rcu_dereference_locked_keyring(keyring); 7281da177e4SLinus Torvalds 729cab8eb59SDavid Howells /* see if there's a matching key we can displace */ 730cab8eb59SDavid Howells if (klist && klist->nkeys > 0) { 731cab8eb59SDavid Howells for (loop = klist->nkeys - 1; loop >= 0; loop--) { 732cab8eb59SDavid Howells if (klist->keys[loop]->type == type && 733cab8eb59SDavid Howells strcmp(klist->keys[loop]->description, 734f70e2e06SDavid Howells description) == 0 735cab8eb59SDavid Howells ) { 736f70e2e06SDavid Howells /* found a match - we'll replace this one with 737f70e2e06SDavid Howells * the new key */ 738cab8eb59SDavid Howells size = sizeof(struct key *) * klist->maxkeys; 739cab8eb59SDavid Howells size += sizeof(*klist); 740cab8eb59SDavid Howells BUG_ON(size > PAGE_SIZE); 741cab8eb59SDavid Howells 742cab8eb59SDavid Howells ret = -ENOMEM; 74348ad504eSEric Sesterhenn nklist = kmemdup(klist, size, GFP_KERNEL); 744cab8eb59SDavid Howells if (!nklist) 745f70e2e06SDavid Howells goto error_sem; 746cab8eb59SDavid Howells 747f70e2e06SDavid Howells /* note replacement slot */ 748f70e2e06SDavid Howells klist->delkey = nklist->delkey = loop; 749cab8eb59SDavid Howells goto done; 750cab8eb59SDavid Howells } 751cab8eb59SDavid Howells } 752cab8eb59SDavid Howells } 753cab8eb59SDavid Howells 7541da177e4SLinus Torvalds /* check that we aren't going to overrun the user's quota */ 7551da177e4SLinus Torvalds ret = key_payload_reserve(keyring, 7561da177e4SLinus Torvalds keyring->datalen + KEYQUOTA_LINK_BYTES); 7571da177e4SLinus Torvalds if (ret < 0) 758f70e2e06SDavid Howells goto error_sem; 7591da177e4SLinus Torvalds 7601da177e4SLinus Torvalds if (klist && klist->nkeys < klist->maxkeys) { 761f70e2e06SDavid Howells /* there's sufficient slack space to append directly */ 762f70e2e06SDavid Howells nklist = NULL; 763512ea3bcSChihau Chau } else { 7641da177e4SLinus Torvalds /* grow the key list */ 7651da177e4SLinus Torvalds max = 4; 7661da177e4SLinus Torvalds if (klist) 7671da177e4SLinus Torvalds max += klist->maxkeys; 7681da177e4SLinus Torvalds 7691da177e4SLinus Torvalds ret = -ENFILE; 7704be929beSAlexey Dobriyan if (max > USHRT_MAX - 1) 771f70e2e06SDavid Howells goto error_quota; 772a4014d8fSDavid Howells size = sizeof(*klist) + sizeof(struct key *) * max; 7731da177e4SLinus Torvalds if (size > PAGE_SIZE) 774f70e2e06SDavid Howells goto error_quota; 7751da177e4SLinus Torvalds 7761da177e4SLinus Torvalds ret = -ENOMEM; 7771da177e4SLinus Torvalds nklist = kmalloc(size, GFP_KERNEL); 7781da177e4SLinus Torvalds if (!nklist) 779f70e2e06SDavid Howells goto error_quota; 7801da177e4SLinus Torvalds 781f70e2e06SDavid Howells nklist->maxkeys = max; 7821da177e4SLinus Torvalds if (klist) { 783f70e2e06SDavid Howells memcpy(nklist->keys, klist->keys, 7841da177e4SLinus Torvalds sizeof(struct key *) * klist->nkeys); 785f70e2e06SDavid Howells nklist->delkey = klist->nkeys; 786f70e2e06SDavid Howells nklist->nkeys = klist->nkeys + 1; 7874be929beSAlexey Dobriyan klist->delkey = USHRT_MAX; 788f70e2e06SDavid Howells } else { 789f70e2e06SDavid Howells nklist->nkeys = 1; 790f70e2e06SDavid Howells nklist->delkey = 0; 7911da177e4SLinus Torvalds } 7921da177e4SLinus Torvalds 7931da177e4SLinus Torvalds /* add the key into the new space */ 794f70e2e06SDavid Howells nklist->keys[nklist->delkey] = NULL; 7951da177e4SLinus Torvalds } 7961da177e4SLinus Torvalds 797cab8eb59SDavid Howells done: 798f70e2e06SDavid Howells *_prealloc = nklist; 799f70e2e06SDavid Howells kleave(" = 0"); 800f70e2e06SDavid Howells return 0; 8011da177e4SLinus Torvalds 802f70e2e06SDavid Howells error_quota: 8031da177e4SLinus Torvalds /* undo the quota changes */ 8041da177e4SLinus Torvalds key_payload_reserve(keyring, 8051da177e4SLinus Torvalds keyring->datalen - KEYQUOTA_LINK_BYTES); 806f70e2e06SDavid Howells error_sem: 807f70e2e06SDavid Howells if (type == &key_type_keyring) 808f70e2e06SDavid Howells up_write(&keyring_serialise_link_sem); 809f70e2e06SDavid Howells error_krsem: 810f70e2e06SDavid Howells up_write(&keyring->sem); 811f70e2e06SDavid Howells kleave(" = %d", ret); 812f70e2e06SDavid Howells return ret; 813f70e2e06SDavid Howells } 8141da177e4SLinus Torvalds 815f70e2e06SDavid Howells /* 816*973c9f4fSDavid Howells * Check already instantiated keys aren't going to be a problem. 817*973c9f4fSDavid Howells * 818*973c9f4fSDavid Howells * The caller must have called __key_link_begin(). Don't need to call this for 819*973c9f4fSDavid Howells * keys that were created since __key_link_begin() was called. 820f70e2e06SDavid Howells */ 821f70e2e06SDavid Howells int __key_link_check_live_key(struct key *keyring, struct key *key) 822f70e2e06SDavid Howells { 823f70e2e06SDavid Howells if (key->type == &key_type_keyring) 824f70e2e06SDavid Howells /* check that we aren't going to create a cycle by linking one 825f70e2e06SDavid Howells * keyring to another */ 826f70e2e06SDavid Howells return keyring_detect_cycle(keyring, key); 827f70e2e06SDavid Howells return 0; 828f70e2e06SDavid Howells } 8291da177e4SLinus Torvalds 830f70e2e06SDavid Howells /* 831*973c9f4fSDavid Howells * Link a key into to a keyring. 832*973c9f4fSDavid Howells * 833*973c9f4fSDavid Howells * Must be called with __key_link_begin() having being called. Discards any 834*973c9f4fSDavid Howells * already extant link to matching key if there is one, so that each keyring 835*973c9f4fSDavid Howells * holds at most one link to any given key of a particular type+description 836*973c9f4fSDavid Howells * combination. 837f70e2e06SDavid Howells */ 838f70e2e06SDavid Howells void __key_link(struct key *keyring, struct key *key, 839f70e2e06SDavid Howells struct keyring_list **_prealloc) 840f70e2e06SDavid Howells { 841f70e2e06SDavid Howells struct keyring_list *klist, *nklist; 842f70e2e06SDavid Howells 843f70e2e06SDavid Howells nklist = *_prealloc; 844f70e2e06SDavid Howells *_prealloc = NULL; 845f70e2e06SDavid Howells 846f70e2e06SDavid Howells kenter("%d,%d,%p", keyring->serial, key->serial, nklist); 847f70e2e06SDavid Howells 848f70e2e06SDavid Howells klist = rcu_dereference_protected(keyring->payload.subscriptions, 849f70e2e06SDavid Howells rwsem_is_locked(&keyring->sem)); 850f70e2e06SDavid Howells 851f70e2e06SDavid Howells atomic_inc(&key->usage); 852f70e2e06SDavid Howells 853f70e2e06SDavid Howells /* there's a matching key we can displace or an empty slot in a newly 854f70e2e06SDavid Howells * allocated list we can fill */ 855f70e2e06SDavid Howells if (nklist) { 856f70e2e06SDavid Howells kdebug("replace %hu/%hu/%hu", 857f70e2e06SDavid Howells nklist->delkey, nklist->nkeys, nklist->maxkeys); 858f70e2e06SDavid Howells 859f70e2e06SDavid Howells nklist->keys[nklist->delkey] = key; 860f70e2e06SDavid Howells 861f70e2e06SDavid Howells rcu_assign_pointer(keyring->payload.subscriptions, nklist); 862f70e2e06SDavid Howells 863f70e2e06SDavid Howells /* dispose of the old keyring list and, if there was one, the 864f70e2e06SDavid Howells * displaced key */ 865f70e2e06SDavid Howells if (klist) { 866f70e2e06SDavid Howells kdebug("dispose %hu/%hu/%hu", 867f70e2e06SDavid Howells klist->delkey, klist->nkeys, klist->maxkeys); 868f70e2e06SDavid Howells call_rcu(&klist->rcu, keyring_unlink_rcu_disposal); 869f70e2e06SDavid Howells } 870f70e2e06SDavid Howells } else { 871f70e2e06SDavid Howells /* there's sufficient slack space to append directly */ 872f70e2e06SDavid Howells klist->keys[klist->nkeys] = key; 873f70e2e06SDavid Howells smp_wmb(); 874f70e2e06SDavid Howells klist->nkeys++; 875f70e2e06SDavid Howells } 876f70e2e06SDavid Howells } 877f70e2e06SDavid Howells 878f70e2e06SDavid Howells /* 879*973c9f4fSDavid Howells * Finish linking a key into to a keyring. 880*973c9f4fSDavid Howells * 881*973c9f4fSDavid Howells * Must be called with __key_link_begin() having being called. 882f70e2e06SDavid Howells */ 883f70e2e06SDavid Howells void __key_link_end(struct key *keyring, struct key_type *type, 884f70e2e06SDavid Howells struct keyring_list *prealloc) 885f70e2e06SDavid Howells __releases(&keyring->sem) 886f70e2e06SDavid Howells { 887f70e2e06SDavid Howells BUG_ON(type == NULL); 888f70e2e06SDavid Howells BUG_ON(type->name == NULL); 889f70e2e06SDavid Howells kenter("%d,%s,%p", keyring->serial, type->name, prealloc); 890f70e2e06SDavid Howells 891f70e2e06SDavid Howells if (type == &key_type_keyring) 892f70e2e06SDavid Howells up_write(&keyring_serialise_link_sem); 893f70e2e06SDavid Howells 894f70e2e06SDavid Howells if (prealloc) { 895f70e2e06SDavid Howells kfree(prealloc); 896f70e2e06SDavid Howells key_payload_reserve(keyring, 897f70e2e06SDavid Howells keyring->datalen - KEYQUOTA_LINK_BYTES); 898f70e2e06SDavid Howells } 899f70e2e06SDavid Howells up_write(&keyring->sem); 900f70e2e06SDavid Howells } 901f70e2e06SDavid Howells 902*973c9f4fSDavid Howells /** 903*973c9f4fSDavid Howells * key_link - Link a key to a keyring 904*973c9f4fSDavid Howells * @keyring: The keyring to make the link in. 905*973c9f4fSDavid Howells * @key: The key to link to. 906*973c9f4fSDavid Howells * 907*973c9f4fSDavid Howells * Make a link in a keyring to a key, such that the keyring holds a reference 908*973c9f4fSDavid Howells * on that key and the key can potentially be found by searching that keyring. 909*973c9f4fSDavid Howells * 910*973c9f4fSDavid Howells * This function will write-lock the keyring's semaphore and will consume some 911*973c9f4fSDavid Howells * of the user's key data quota to hold the link. 912*973c9f4fSDavid Howells * 913*973c9f4fSDavid Howells * Returns 0 if successful, -ENOTDIR if the keyring isn't a keyring, 914*973c9f4fSDavid Howells * -EKEYREVOKED if the keyring has been revoked, -ENFILE if the keyring is 915*973c9f4fSDavid Howells * full, -EDQUOT if there is insufficient key data quota remaining to add 916*973c9f4fSDavid Howells * another link or -ENOMEM if there's insufficient memory. 917*973c9f4fSDavid Howells * 918*973c9f4fSDavid Howells * It is assumed that the caller has checked that it is permitted for a link to 919*973c9f4fSDavid Howells * be made (the keyring should have Write permission and the key Link 920*973c9f4fSDavid Howells * permission). 9211da177e4SLinus Torvalds */ 9221da177e4SLinus Torvalds int key_link(struct key *keyring, struct key *key) 9231da177e4SLinus Torvalds { 924f70e2e06SDavid Howells struct keyring_list *prealloc; 9251da177e4SLinus Torvalds int ret; 9261da177e4SLinus Torvalds 9271da177e4SLinus Torvalds key_check(keyring); 9281da177e4SLinus Torvalds key_check(key); 9291da177e4SLinus Torvalds 930f70e2e06SDavid Howells ret = __key_link_begin(keyring, key->type, key->description, &prealloc); 931f70e2e06SDavid Howells if (ret == 0) { 932f70e2e06SDavid Howells ret = __key_link_check_live_key(keyring, key); 933f70e2e06SDavid Howells if (ret == 0) 934f70e2e06SDavid Howells __key_link(keyring, key, &prealloc); 935f70e2e06SDavid Howells __key_link_end(keyring, key->type, prealloc); 936f70e2e06SDavid Howells } 9371da177e4SLinus Torvalds 9381da177e4SLinus Torvalds return ret; 939f70e2e06SDavid Howells } 9401da177e4SLinus Torvalds EXPORT_SYMBOL(key_link); 9411da177e4SLinus Torvalds 942*973c9f4fSDavid Howells /** 943*973c9f4fSDavid Howells * key_unlink - Unlink the first link to a key from a keyring. 944*973c9f4fSDavid Howells * @keyring: The keyring to remove the link from. 945*973c9f4fSDavid Howells * @key: The key the link is to. 946*973c9f4fSDavid Howells * 947*973c9f4fSDavid Howells * Remove a link from a keyring to a key. 948*973c9f4fSDavid Howells * 949*973c9f4fSDavid Howells * This function will write-lock the keyring's semaphore. 950*973c9f4fSDavid Howells * 951*973c9f4fSDavid Howells * Returns 0 if successful, -ENOTDIR if the keyring isn't a keyring, -ENOENT if 952*973c9f4fSDavid Howells * the key isn't linked to by the keyring or -ENOMEM if there's insufficient 953*973c9f4fSDavid Howells * memory. 954*973c9f4fSDavid Howells * 955*973c9f4fSDavid Howells * It is assumed that the caller has checked that it is permitted for a link to 956*973c9f4fSDavid Howells * be removed (the keyring should have Write permission; no permissions are 957*973c9f4fSDavid Howells * required on the key). 9581da177e4SLinus Torvalds */ 9591da177e4SLinus Torvalds int key_unlink(struct key *keyring, struct key *key) 9601da177e4SLinus Torvalds { 96176d8aeabSDavid Howells struct keyring_list *klist, *nklist; 9621da177e4SLinus Torvalds int loop, ret; 9631da177e4SLinus Torvalds 9641da177e4SLinus Torvalds key_check(keyring); 9651da177e4SLinus Torvalds key_check(key); 9661da177e4SLinus Torvalds 9671da177e4SLinus Torvalds ret = -ENOTDIR; 9681da177e4SLinus Torvalds if (keyring->type != &key_type_keyring) 9691da177e4SLinus Torvalds goto error; 9701da177e4SLinus Torvalds 9711da177e4SLinus Torvalds down_write(&keyring->sem); 9721da177e4SLinus Torvalds 973f0641cbaSDavid Howells klist = rcu_dereference_locked_keyring(keyring); 9741da177e4SLinus Torvalds if (klist) { 9751da177e4SLinus Torvalds /* search the keyring for the key */ 9761da177e4SLinus Torvalds for (loop = 0; loop < klist->nkeys; loop++) 9771da177e4SLinus Torvalds if (klist->keys[loop] == key) 9781da177e4SLinus Torvalds goto key_is_present; 9791da177e4SLinus Torvalds } 9801da177e4SLinus Torvalds 9811da177e4SLinus Torvalds up_write(&keyring->sem); 9821da177e4SLinus Torvalds ret = -ENOENT; 9831da177e4SLinus Torvalds goto error; 9841da177e4SLinus Torvalds 9851da177e4SLinus Torvalds key_is_present: 98676d8aeabSDavid Howells /* we need to copy the key list for RCU purposes */ 987a4014d8fSDavid Howells nklist = kmalloc(sizeof(*klist) + 988a4014d8fSDavid Howells sizeof(struct key *) * klist->maxkeys, 98976d8aeabSDavid Howells GFP_KERNEL); 99076d8aeabSDavid Howells if (!nklist) 99176d8aeabSDavid Howells goto nomem; 99276d8aeabSDavid Howells nklist->maxkeys = klist->maxkeys; 99376d8aeabSDavid Howells nklist->nkeys = klist->nkeys - 1; 99476d8aeabSDavid Howells 99576d8aeabSDavid Howells if (loop > 0) 99676d8aeabSDavid Howells memcpy(&nklist->keys[0], 99776d8aeabSDavid Howells &klist->keys[0], 998a4014d8fSDavid Howells loop * sizeof(struct key *)); 99976d8aeabSDavid Howells 100076d8aeabSDavid Howells if (loop < nklist->nkeys) 100176d8aeabSDavid Howells memcpy(&nklist->keys[loop], 100276d8aeabSDavid Howells &klist->keys[loop + 1], 1003a4014d8fSDavid Howells (nklist->nkeys - loop) * sizeof(struct key *)); 100476d8aeabSDavid Howells 10051da177e4SLinus Torvalds /* adjust the user's quota */ 10061da177e4SLinus Torvalds key_payload_reserve(keyring, 10071da177e4SLinus Torvalds keyring->datalen - KEYQUOTA_LINK_BYTES); 10081da177e4SLinus Torvalds 100976d8aeabSDavid Howells rcu_assign_pointer(keyring->payload.subscriptions, nklist); 10101da177e4SLinus Torvalds 10111da177e4SLinus Torvalds up_write(&keyring->sem); 101276d8aeabSDavid Howells 101376d8aeabSDavid Howells /* schedule for later cleanup */ 101476d8aeabSDavid Howells klist->delkey = loop; 101576d8aeabSDavid Howells call_rcu(&klist->rcu, keyring_unlink_rcu_disposal); 101676d8aeabSDavid Howells 10171da177e4SLinus Torvalds ret = 0; 10181da177e4SLinus Torvalds 10191da177e4SLinus Torvalds error: 10201da177e4SLinus Torvalds return ret; 102176d8aeabSDavid Howells nomem: 102276d8aeabSDavid Howells ret = -ENOMEM; 102376d8aeabSDavid Howells up_write(&keyring->sem); 102476d8aeabSDavid Howells goto error; 1025a8b17ed0SDavid Howells } 10261da177e4SLinus Torvalds EXPORT_SYMBOL(key_unlink); 10271da177e4SLinus Torvalds 10281da177e4SLinus Torvalds /* 1029*973c9f4fSDavid Howells * Dispose of a keyring list after the RCU grace period, releasing the keys it 1030*973c9f4fSDavid Howells * links to. 103176d8aeabSDavid Howells */ 103276d8aeabSDavid Howells static void keyring_clear_rcu_disposal(struct rcu_head *rcu) 103376d8aeabSDavid Howells { 103476d8aeabSDavid Howells struct keyring_list *klist; 103576d8aeabSDavid Howells int loop; 103676d8aeabSDavid Howells 103776d8aeabSDavid Howells klist = container_of(rcu, struct keyring_list, rcu); 103876d8aeabSDavid Howells 103976d8aeabSDavid Howells for (loop = klist->nkeys - 1; loop >= 0; loop--) 104076d8aeabSDavid Howells key_put(klist->keys[loop]); 104176d8aeabSDavid Howells 104276d8aeabSDavid Howells kfree(klist); 1043a8b17ed0SDavid Howells } 104476d8aeabSDavid Howells 1045*973c9f4fSDavid Howells /** 1046*973c9f4fSDavid Howells * keyring_clear - Clear a keyring 1047*973c9f4fSDavid Howells * @keyring: The keyring to clear. 1048*973c9f4fSDavid Howells * 1049*973c9f4fSDavid Howells * Clear the contents of the specified keyring. 1050*973c9f4fSDavid Howells * 1051*973c9f4fSDavid Howells * Returns 0 if successful or -ENOTDIR if the keyring isn't a keyring. 10521da177e4SLinus Torvalds */ 10531da177e4SLinus Torvalds int keyring_clear(struct key *keyring) 10541da177e4SLinus Torvalds { 10551da177e4SLinus Torvalds struct keyring_list *klist; 105676d8aeabSDavid Howells int ret; 10571da177e4SLinus Torvalds 10581da177e4SLinus Torvalds ret = -ENOTDIR; 10591da177e4SLinus Torvalds if (keyring->type == &key_type_keyring) { 10601da177e4SLinus Torvalds /* detach the pointer block with the locks held */ 10611da177e4SLinus Torvalds down_write(&keyring->sem); 10621da177e4SLinus Torvalds 1063f0641cbaSDavid Howells klist = rcu_dereference_locked_keyring(keyring); 10641da177e4SLinus Torvalds if (klist) { 10651da177e4SLinus Torvalds /* adjust the quota */ 10661da177e4SLinus Torvalds key_payload_reserve(keyring, 10671da177e4SLinus Torvalds sizeof(struct keyring_list)); 10681da177e4SLinus Torvalds 106976d8aeabSDavid Howells rcu_assign_pointer(keyring->payload.subscriptions, 107076d8aeabSDavid Howells NULL); 10711da177e4SLinus Torvalds } 10721da177e4SLinus Torvalds 10731da177e4SLinus Torvalds up_write(&keyring->sem); 10741da177e4SLinus Torvalds 10751da177e4SLinus Torvalds /* free the keys after the locks have been dropped */ 107676d8aeabSDavid Howells if (klist) 107776d8aeabSDavid Howells call_rcu(&klist->rcu, keyring_clear_rcu_disposal); 10781da177e4SLinus Torvalds 10791da177e4SLinus Torvalds ret = 0; 10801da177e4SLinus Torvalds } 10811da177e4SLinus Torvalds 10821da177e4SLinus Torvalds return ret; 1083a8b17ed0SDavid Howells } 10841da177e4SLinus Torvalds EXPORT_SYMBOL(keyring_clear); 108531204ed9SDavid Howells 108631204ed9SDavid Howells /* 1087*973c9f4fSDavid Howells * Dispose of the links from a revoked keyring. 1088*973c9f4fSDavid Howells * 1089*973c9f4fSDavid Howells * This is called with the key sem write-locked. 109031204ed9SDavid Howells */ 109131204ed9SDavid Howells static void keyring_revoke(struct key *keyring) 109231204ed9SDavid Howells { 1093f0641cbaSDavid Howells struct keyring_list *klist; 1094f0641cbaSDavid Howells 1095f0641cbaSDavid Howells klist = rcu_dereference_locked_keyring(keyring); 109631204ed9SDavid Howells 109731204ed9SDavid Howells /* adjust the quota */ 109831204ed9SDavid Howells key_payload_reserve(keyring, 0); 109931204ed9SDavid Howells 110031204ed9SDavid Howells if (klist) { 110131204ed9SDavid Howells rcu_assign_pointer(keyring->payload.subscriptions, NULL); 110231204ed9SDavid Howells call_rcu(&klist->rcu, keyring_clear_rcu_disposal); 110331204ed9SDavid Howells } 1104a8b17ed0SDavid Howells } 11055d135440SDavid Howells 11065d135440SDavid Howells /* 1107*973c9f4fSDavid Howells * Determine whether a key is dead. 11085d135440SDavid Howells */ 11095d135440SDavid Howells static bool key_is_dead(struct key *key, time_t limit) 11105d135440SDavid Howells { 11115d135440SDavid Howells return test_bit(KEY_FLAG_DEAD, &key->flags) || 11125d135440SDavid Howells (key->expiry > 0 && key->expiry <= limit); 11135d135440SDavid Howells } 11145d135440SDavid Howells 11155d135440SDavid Howells /* 1116*973c9f4fSDavid Howells * Collect garbage from the contents of a keyring, replacing the old list with 1117*973c9f4fSDavid Howells * a new one with the pointers all shuffled down. 1118*973c9f4fSDavid Howells * 1119*973c9f4fSDavid Howells * Dead keys are classed as oned that are flagged as being dead or are revoked, 1120*973c9f4fSDavid Howells * expired or negative keys that were revoked or expired before the specified 1121*973c9f4fSDavid Howells * limit. 11225d135440SDavid Howells */ 11235d135440SDavid Howells void keyring_gc(struct key *keyring, time_t limit) 11245d135440SDavid Howells { 11255d135440SDavid Howells struct keyring_list *klist, *new; 11265d135440SDavid Howells struct key *key; 11275d135440SDavid Howells int loop, keep, max; 11285d135440SDavid Howells 1129c08ef808SDavid Howells kenter("{%x,%s}", key_serial(keyring), keyring->description); 11305d135440SDavid Howells 11315d135440SDavid Howells down_write(&keyring->sem); 11325d135440SDavid Howells 1133f0641cbaSDavid Howells klist = rcu_dereference_locked_keyring(keyring); 11345d135440SDavid Howells if (!klist) 1135c08ef808SDavid Howells goto no_klist; 11365d135440SDavid Howells 11375d135440SDavid Howells /* work out how many subscriptions we're keeping */ 11385d135440SDavid Howells keep = 0; 11395d135440SDavid Howells for (loop = klist->nkeys - 1; loop >= 0; loop--) 1140c08ef808SDavid Howells if (!key_is_dead(klist->keys[loop], limit)) 11415d135440SDavid Howells keep++; 11425d135440SDavid Howells 11435d135440SDavid Howells if (keep == klist->nkeys) 11445d135440SDavid Howells goto just_return; 11455d135440SDavid Howells 11465d135440SDavid Howells /* allocate a new keyring payload */ 11475d135440SDavid Howells max = roundup(keep, 4); 11485d135440SDavid Howells new = kmalloc(sizeof(struct keyring_list) + max * sizeof(struct key *), 11495d135440SDavid Howells GFP_KERNEL); 11505d135440SDavid Howells if (!new) 1151c08ef808SDavid Howells goto nomem; 11525d135440SDavid Howells new->maxkeys = max; 11535d135440SDavid Howells new->nkeys = 0; 11545d135440SDavid Howells new->delkey = 0; 11555d135440SDavid Howells 11565d135440SDavid Howells /* install the live keys 11575d135440SDavid Howells * - must take care as expired keys may be updated back to life 11585d135440SDavid Howells */ 11595d135440SDavid Howells keep = 0; 11605d135440SDavid Howells for (loop = klist->nkeys - 1; loop >= 0; loop--) { 11615d135440SDavid Howells key = klist->keys[loop]; 11625d135440SDavid Howells if (!key_is_dead(key, limit)) { 11635d135440SDavid Howells if (keep >= max) 11645d135440SDavid Howells goto discard_new; 11655d135440SDavid Howells new->keys[keep++] = key_get(key); 11665d135440SDavid Howells } 11675d135440SDavid Howells } 11685d135440SDavid Howells new->nkeys = keep; 11695d135440SDavid Howells 11705d135440SDavid Howells /* adjust the quota */ 11715d135440SDavid Howells key_payload_reserve(keyring, 11725d135440SDavid Howells sizeof(struct keyring_list) + 11735d135440SDavid Howells KEYQUOTA_LINK_BYTES * keep); 11745d135440SDavid Howells 11755d135440SDavid Howells if (keep == 0) { 11765d135440SDavid Howells rcu_assign_pointer(keyring->payload.subscriptions, NULL); 11775d135440SDavid Howells kfree(new); 11785d135440SDavid Howells } else { 11795d135440SDavid Howells rcu_assign_pointer(keyring->payload.subscriptions, new); 11805d135440SDavid Howells } 11815d135440SDavid Howells 11825d135440SDavid Howells up_write(&keyring->sem); 11835d135440SDavid Howells 11845d135440SDavid Howells call_rcu(&klist->rcu, keyring_clear_rcu_disposal); 11855d135440SDavid Howells kleave(" [yes]"); 11865d135440SDavid Howells return; 11875d135440SDavid Howells 11885d135440SDavid Howells discard_new: 11895d135440SDavid Howells new->nkeys = keep; 11905d135440SDavid Howells keyring_clear_rcu_disposal(&new->rcu); 1191c08ef808SDavid Howells up_write(&keyring->sem); 1192c08ef808SDavid Howells kleave(" [discard]"); 1193c08ef808SDavid Howells return; 1194c08ef808SDavid Howells 11955d135440SDavid Howells just_return: 11965d135440SDavid Howells up_write(&keyring->sem); 1197c08ef808SDavid Howells kleave(" [no dead]"); 1198c08ef808SDavid Howells return; 1199c08ef808SDavid Howells 1200c08ef808SDavid Howells no_klist: 1201c08ef808SDavid Howells up_write(&keyring->sem); 1202c08ef808SDavid Howells kleave(" [no_klist]"); 1203c08ef808SDavid Howells return; 1204c08ef808SDavid Howells 1205c08ef808SDavid Howells nomem: 1206c08ef808SDavid Howells up_write(&keyring->sem); 1207c08ef808SDavid Howells kleave(" [oom]"); 12085d135440SDavid Howells } 1209