blob: 459b3cc347f2c4cf192df2655a01fa1ee89ceb77 [file] [log] [blame]
David Howells69664cf2008-04-29 01:01:31 -07001/* Keyring handling
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 *
David Howells69664cf2008-04-29 01:01:31 -07003 * Copyright (C) 2004-2005, 2008 Red Hat, Inc. All Rights Reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 * 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
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/sched.h>
15#include <linux/slab.h>
David Howells29db9192005-10-30 15:02:44 -080016#include <linux/security.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#include <linux/seq_file.h>
18#include <linux/err.h>
David Howellse9e349b2008-11-14 10:39:13 +110019#include <keys/keyring-type.h>
Chihau Chau512ea3b2010-03-08 20:11:34 -030020#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include "internal.h"
22
David Howellsf0641cb2010-04-30 14:32:18 +010023#define rcu_dereference_locked_keyring(keyring) \
24 (rcu_dereference_protected( \
25 (keyring)->payload.subscriptions, \
26 rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem)))
27
David Howells233e4732012-05-11 10:56:56 +010028#define rcu_deref_link_locked(klist, index, keyring) \
29 (rcu_dereference_protected( \
30 (klist)->keys[index], \
31 rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem)))
32
David Howellsceb73c12011-01-25 16:34:28 +000033#define KEY_LINK_FIXQUOTA 1UL
34
Linus Torvalds1da177e2005-04-16 15:20:36 -070035/*
David Howells973c9f42011-01-20 16:38:33 +000036 * When plumbing the depths of the key tree, this sets a hard limit
37 * set on how deep we're willing to go.
Linus Torvalds1da177e2005-04-16 15:20:36 -070038 */
39#define KEYRING_SEARCH_MAX_DEPTH 6
40
41/*
David Howells973c9f42011-01-20 16:38:33 +000042 * We keep all named keyrings in a hash to speed looking them up.
Linus Torvalds1da177e2005-04-16 15:20:36 -070043 */
44#define KEYRING_NAME_HASH_SIZE (1 << 5)
45
46static struct list_head keyring_name_hash[KEYRING_NAME_HASH_SIZE];
47static DEFINE_RWLOCK(keyring_name_lock);
48
49static inline unsigned keyring_hash(const char *desc)
50{
51 unsigned bucket = 0;
52
53 for (; *desc; desc++)
Justin P. Mattockc5b60b52010-04-21 00:02:11 -070054 bucket += (unsigned char)*desc;
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
56 return bucket & (KEYRING_NAME_HASH_SIZE - 1);
57}
58
59/*
David Howells973c9f42011-01-20 16:38:33 +000060 * The keyring key type definition. Keyrings are simply keys of this type and
61 * can be treated as ordinary keys in addition to having their own special
62 * operations.
Linus Torvalds1da177e2005-04-16 15:20:36 -070063 */
64static int keyring_instantiate(struct key *keyring,
65 const void *data, size_t datalen);
Linus Torvalds1da177e2005-04-16 15:20:36 -070066static int keyring_match(const struct key *keyring, const void *criterion);
David Howells31204ed2006-06-26 00:24:51 -070067static void keyring_revoke(struct key *keyring);
Linus Torvalds1da177e2005-04-16 15:20:36 -070068static void keyring_destroy(struct key *keyring);
69static void keyring_describe(const struct key *keyring, struct seq_file *m);
70static long keyring_read(const struct key *keyring,
71 char __user *buffer, size_t buflen);
72
73struct key_type key_type_keyring = {
74 .name = "keyring",
75 .def_datalen = sizeof(struct keyring_list),
76 .instantiate = keyring_instantiate,
Linus Torvalds1da177e2005-04-16 15:20:36 -070077 .match = keyring_match,
David Howells31204ed2006-06-26 00:24:51 -070078 .revoke = keyring_revoke,
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 .destroy = keyring_destroy,
80 .describe = keyring_describe,
81 .read = keyring_read,
82};
David Howells73182262007-04-26 15:46:23 -070083EXPORT_SYMBOL(key_type_keyring);
84
Linus Torvalds1da177e2005-04-16 15:20:36 -070085/*
David Howells973c9f42011-01-20 16:38:33 +000086 * Semaphore to serialise link/link calls to prevent two link calls in parallel
87 * introducing a cycle.
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 */
Adrian Bunk1ae8f402006-01-06 00:11:25 -080089static DECLARE_RWSEM(keyring_serialise_link_sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
Linus Torvalds1da177e2005-04-16 15:20:36 -070091/*
David Howells973c9f42011-01-20 16:38:33 +000092 * Publish the name of a keyring so that it can be found by name (if it has
93 * one).
Linus Torvalds1da177e2005-04-16 15:20:36 -070094 */
David Howells69664cf2008-04-29 01:01:31 -070095static void keyring_publish_name(struct key *keyring)
Linus Torvalds1da177e2005-04-16 15:20:36 -070096{
97 int bucket;
98
99 if (keyring->description) {
100 bucket = keyring_hash(keyring->description);
101
102 write_lock(&keyring_name_lock);
103
104 if (!keyring_name_hash[bucket].next)
105 INIT_LIST_HEAD(&keyring_name_hash[bucket]);
106
107 list_add_tail(&keyring->type_data.link,
108 &keyring_name_hash[bucket]);
109
110 write_unlock(&keyring_name_lock);
111 }
David Howellsa8b17ed2011-01-20 16:38:27 +0000112}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114/*
David Howells973c9f42011-01-20 16:38:33 +0000115 * Initialise a keyring.
116 *
117 * Returns 0 on success, -EINVAL if given any data.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 */
119static int keyring_instantiate(struct key *keyring,
120 const void *data, size_t datalen)
121{
122 int ret;
123
124 ret = -EINVAL;
125 if (datalen == 0) {
126 /* make the keyring available by name if it has one */
127 keyring_publish_name(keyring);
128 ret = 0;
129 }
130
131 return ret;
David Howellsa8b17ed2011-01-20 16:38:27 +0000132}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134/*
David Howells973c9f42011-01-20 16:38:33 +0000135 * Match keyrings on their name
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 */
137static int keyring_match(const struct key *keyring, const void *description)
138{
139 return keyring->description &&
140 strcmp(keyring->description, description) == 0;
David Howellsa8b17ed2011-01-20 16:38:27 +0000141}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143/*
David Howells973c9f42011-01-20 16:38:33 +0000144 * Clean up a keyring when it is destroyed. Unpublish its name if it had one
145 * and dispose of its data.
David Howells233e4732012-05-11 10:56:56 +0100146 *
147 * The garbage collector detects the final key_put(), removes the keyring from
148 * the serial number tree and then does RCU synchronisation before coming here,
149 * so we shouldn't need to worry about code poking around here with the RCU
150 * readlock held by this time.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151 */
152static void keyring_destroy(struct key *keyring)
153{
154 struct keyring_list *klist;
155 int loop;
156
157 if (keyring->description) {
158 write_lock(&keyring_name_lock);
David Howells94efe722005-08-04 13:07:07 -0700159
160 if (keyring->type_data.link.next != NULL &&
161 !list_empty(&keyring->type_data.link))
162 list_del(&keyring->type_data.link);
163
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 write_unlock(&keyring_name_lock);
165 }
166
David Howells233e4732012-05-11 10:56:56 +0100167 klist = rcu_access_pointer(keyring->payload.subscriptions);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168 if (klist) {
169 for (loop = klist->nkeys - 1; loop >= 0; loop--)
David Howells233e4732012-05-11 10:56:56 +0100170 key_put(rcu_access_pointer(klist->keys[loop]));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171 kfree(klist);
172 }
David Howellsa8b17ed2011-01-20 16:38:27 +0000173}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175/*
David Howells973c9f42011-01-20 16:38:33 +0000176 * Describe a keyring for /proc.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 */
178static void keyring_describe(const struct key *keyring, struct seq_file *m)
179{
180 struct keyring_list *klist;
181
wzt.wzt@gmail.comc8563472010-03-04 21:26:23 +0800182 if (keyring->description)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183 seq_puts(m, keyring->description);
wzt.wzt@gmail.comc8563472010-03-04 21:26:23 +0800184 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 seq_puts(m, "[anon]");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186
David Howells78b72802011-03-11 17:57:23 +0000187 if (key_is_instantiated(keyring)) {
188 rcu_read_lock();
189 klist = rcu_dereference(keyring->payload.subscriptions);
190 if (klist)
191 seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys);
192 else
193 seq_puts(m, ": empty");
194 rcu_read_unlock();
195 }
David Howellsa8b17ed2011-01-20 16:38:27 +0000196}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198/*
David Howells973c9f42011-01-20 16:38:33 +0000199 * Read a list of key IDs from the keyring's contents in binary form
200 *
201 * The keyring's semaphore is read-locked by the caller.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 */
203static long keyring_read(const struct key *keyring,
204 char __user *buffer, size_t buflen)
205{
206 struct keyring_list *klist;
207 struct key *key;
208 size_t qty, tmp;
209 int loop, ret;
210
211 ret = 0;
David Howellsf0641cb2010-04-30 14:32:18 +0100212 klist = rcu_dereference_locked_keyring(keyring);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 if (klist) {
214 /* calculate how much data we could return */
215 qty = klist->nkeys * sizeof(key_serial_t);
216
217 if (buffer && buflen > 0) {
218 if (buflen > qty)
219 buflen = qty;
220
221 /* copy the IDs of the subscribed keys into the
222 * buffer */
223 ret = -EFAULT;
224
225 for (loop = 0; loop < klist->nkeys; loop++) {
David Howells233e4732012-05-11 10:56:56 +0100226 key = rcu_deref_link_locked(klist, loop,
227 keyring);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
229 tmp = sizeof(key_serial_t);
230 if (tmp > buflen)
231 tmp = buflen;
232
233 if (copy_to_user(buffer,
234 &key->serial,
235 tmp) != 0)
236 goto error;
237
238 buflen -= tmp;
239 if (buflen == 0)
240 break;
241 buffer += tmp;
242 }
243 }
244
245 ret = qty;
246 }
247
Justin P. Mattockc5b60b52010-04-21 00:02:11 -0700248error:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249 return ret;
David Howellsa8b17ed2011-01-20 16:38:27 +0000250}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252/*
David Howells973c9f42011-01-20 16:38:33 +0000253 * Allocate a keyring and link into the destination keyring.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 */
255struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
David Howellsd84f4f92008-11-14 10:39:23 +1100256 const struct cred *cred, unsigned long flags,
Michael LeMayd7200242006-06-22 14:47:17 -0700257 struct key *dest)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258{
259 struct key *keyring;
260 int ret;
261
262 keyring = key_alloc(&key_type_keyring, description,
David Howellsd84f4f92008-11-14 10:39:23 +1100263 uid, gid, cred,
David Howells29db9192005-10-30 15:02:44 -0800264 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
David Howells7e047ef2006-06-26 00:24:50 -0700265 flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266
267 if (!IS_ERR(keyring)) {
David Howells3e301482005-06-23 22:00:56 -0700268 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269 if (ret < 0) {
270 key_put(keyring);
271 keyring = ERR_PTR(ret);
272 }
273 }
274
275 return keyring;
David Howellsa8b17ed2011-01-20 16:38:27 +0000276}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277
David Howells973c9f42011-01-20 16:38:33 +0000278/**
279 * keyring_search_aux - Search a keyring tree for a key matching some criteria
280 * @keyring_ref: A pointer to the keyring with possession indicator.
281 * @cred: The credentials to use for permissions checks.
282 * @type: The type of key to search for.
283 * @description: Parameter for @match.
284 * @match: Function to rule on whether or not a key is the one required.
David Howells78b72802011-03-11 17:57:23 +0000285 * @no_state_check: Don't check if a matching key is bad
David Howells973c9f42011-01-20 16:38:33 +0000286 *
287 * Search the supplied keyring tree for a key that matches the criteria given.
288 * The root keyring and any linked keyrings must grant Search permission to the
289 * caller to be searchable and keys can only be found if they too grant Search
290 * to the caller. The possession flag on the root keyring pointer controls use
291 * of the possessor bits in permissions checking of the entire tree. In
292 * addition, the LSM gets to forbid keyring searches and key matches.
293 *
294 * The search is performed as a breadth-then-depth search up to the prescribed
295 * limit (KEYRING_SEARCH_MAX_DEPTH).
296 *
297 * Keys are matched to the type provided and are then filtered by the match
298 * function, which is given the description to use in any way it sees fit. The
299 * match function may use any attributes of a key that it wishes to to
300 * determine the match. Normally the match function from the key type would be
301 * used.
302 *
303 * RCU is used to prevent the keyring key lists from disappearing without the
304 * need to take lots of locks.
305 *
306 * Returns a pointer to the found key and increments the key usage count if
307 * successful; -EAGAIN if no matching keys were found, or if expired or revoked
308 * keys were found; -ENOKEY if only negative keys were found; -ENOTDIR if the
309 * specified keyring wasn't a keyring.
310 *
311 * In the case of a successful return, the possession attribute from
312 * @keyring_ref is propagated to the returned key reference.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 */
David Howells664cceb2005-09-28 17:03:15 +0100314key_ref_t keyring_search_aux(key_ref_t keyring_ref,
David Howellsd84f4f92008-11-14 10:39:23 +1100315 const struct cred *cred,
David Howells664cceb2005-09-28 17:03:15 +0100316 struct key_type *type,
317 const void *description,
David Howells78b72802011-03-11 17:57:23 +0000318 key_match_func_t match,
319 bool no_state_check)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320{
321 struct {
David Howells76d8aea2005-06-23 22:00:49 -0700322 struct keyring_list *keylist;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 int kix;
324 } stack[KEYRING_SEARCH_MAX_DEPTH];
325
326 struct keyring_list *keylist;
327 struct timespec now;
Kevin Coffmandceba992008-04-29 01:01:22 -0700328 unsigned long possessed, kflags;
David Howells664cceb2005-09-28 17:03:15 +0100329 struct key *keyring, *key;
330 key_ref_t key_ref;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331 long err;
David Howellsefde8b62012-01-17 20:39:40 +0000332 int sp, nkeys, kix;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333
David Howells664cceb2005-09-28 17:03:15 +0100334 keyring = key_ref_to_ptr(keyring_ref);
335 possessed = is_key_possessed(keyring_ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 key_check(keyring);
337
338 /* top keyring must have search permission to begin the search */
Chihau Chau512ea3b2010-03-08 20:11:34 -0300339 err = key_task_permission(keyring_ref, cred, KEY_SEARCH);
David Howells29db9192005-10-30 15:02:44 -0800340 if (err < 0) {
341 key_ref = ERR_PTR(err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 goto error;
David Howells29db9192005-10-30 15:02:44 -0800343 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344
David Howells664cceb2005-09-28 17:03:15 +0100345 key_ref = ERR_PTR(-ENOTDIR);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 if (keyring->type != &key_type_keyring)
347 goto error;
348
David Howells664cceb2005-09-28 17:03:15 +0100349 rcu_read_lock();
350
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 now = current_kernel_time();
352 err = -EAGAIN;
353 sp = 0;
354
Kevin Coffmandceba992008-04-29 01:01:22 -0700355 /* firstly we should check to see if this top-level keyring is what we
356 * are looking for */
357 key_ref = ERR_PTR(-EAGAIN);
358 kflags = keyring->flags;
359 if (keyring->type == type && match(keyring, description)) {
360 key = keyring;
David Howells78b72802011-03-11 17:57:23 +0000361 if (no_state_check)
362 goto found;
Kevin Coffmandceba992008-04-29 01:01:22 -0700363
364 /* check it isn't negative and hasn't expired or been
365 * revoked */
366 if (kflags & (1 << KEY_FLAG_REVOKED))
367 goto error_2;
368 if (key->expiry && now.tv_sec >= key->expiry)
369 goto error_2;
David Howellsfdd1b942011-03-07 15:06:09 +0000370 key_ref = ERR_PTR(key->type_data.reject_error);
Kevin Coffmandceba992008-04-29 01:01:22 -0700371 if (kflags & (1 << KEY_FLAG_NEGATIVE))
372 goto error_2;
373 goto found;
374 }
375
376 /* otherwise, the top keyring must not be revoked, expired, or
377 * negatively instantiated if we are to search it */
378 key_ref = ERR_PTR(-EAGAIN);
379 if (kflags & ((1 << KEY_FLAG_REVOKED) | (1 << KEY_FLAG_NEGATIVE)) ||
380 (keyring->expiry && now.tv_sec >= keyring->expiry))
381 goto error_2;
382
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 /* start processing a new keyring */
David Howells664cceb2005-09-28 17:03:15 +0100384descend:
David Howells76d8aea2005-06-23 22:00:49 -0700385 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 goto not_this_keyring;
387
David Howells76d8aea2005-06-23 22:00:49 -0700388 keylist = rcu_dereference(keyring->payload.subscriptions);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 if (!keylist)
390 goto not_this_keyring;
391
392 /* iterate through the keys in this keyring first */
David Howellsefde8b62012-01-17 20:39:40 +0000393 nkeys = keylist->nkeys;
394 smp_rmb();
395 for (kix = 0; kix < nkeys; kix++) {
David Howells233e4732012-05-11 10:56:56 +0100396 key = rcu_dereference(keylist->keys[kix]);
Kevin Coffmandceba992008-04-29 01:01:22 -0700397 kflags = key->flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398
399 /* ignore keys not of this type */
400 if (key->type != type)
401 continue;
402
403 /* skip revoked keys and expired keys */
David Howells78b72802011-03-11 17:57:23 +0000404 if (!no_state_check) {
405 if (kflags & (1 << KEY_FLAG_REVOKED))
406 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
David Howells78b72802011-03-11 17:57:23 +0000408 if (key->expiry && now.tv_sec >= key->expiry)
409 continue;
410 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
412 /* keys that don't match */
413 if (!match(key, description))
414 continue;
415
416 /* key must have search permissions */
David Howells29db9192005-10-30 15:02:44 -0800417 if (key_task_permission(make_key_ref(key, possessed),
David Howellsd84f4f92008-11-14 10:39:23 +1100418 cred, KEY_SEARCH) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 continue;
420
David Howells78b72802011-03-11 17:57:23 +0000421 if (no_state_check)
422 goto found;
423
Kevin Coffmandceba992008-04-29 01:01:22 -0700424 /* we set a different error code if we pass a negative key */
425 if (kflags & (1 << KEY_FLAG_NEGATIVE)) {
David Howellsfdd1b942011-03-07 15:06:09 +0000426 err = key->type_data.reject_error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 continue;
428 }
429
430 goto found;
431 }
432
433 /* search through the keyrings nested in this one */
434 kix = 0;
David Howells664cceb2005-09-28 17:03:15 +0100435ascend:
David Howellsefde8b62012-01-17 20:39:40 +0000436 nkeys = keylist->nkeys;
437 smp_rmb();
438 for (; kix < nkeys; kix++) {
David Howells233e4732012-05-11 10:56:56 +0100439 key = rcu_dereference(keylist->keys[kix]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 if (key->type != &key_type_keyring)
David Howells76d8aea2005-06-23 22:00:49 -0700441 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442
443 /* recursively search nested keyrings
444 * - only search keyrings for which we have search permission
445 */
446 if (sp >= KEYRING_SEARCH_MAX_DEPTH)
David Howells76d8aea2005-06-23 22:00:49 -0700447 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448
David Howells0f6ed7c2005-11-07 00:59:30 -0800449 if (key_task_permission(make_key_ref(key, possessed),
David Howellsd84f4f92008-11-14 10:39:23 +1100450 cred, KEY_SEARCH) < 0)
David Howells76d8aea2005-06-23 22:00:49 -0700451 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452
453 /* stack the current position */
David Howells76d8aea2005-06-23 22:00:49 -0700454 stack[sp].keylist = keylist;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 stack[sp].kix = kix;
456 sp++;
457
458 /* begin again with the new keyring */
459 keyring = key;
460 goto descend;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 }
462
463 /* the keyring we're looking at was disqualified or didn't contain a
464 * matching key */
David Howells664cceb2005-09-28 17:03:15 +0100465not_this_keyring:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 if (sp > 0) {
467 /* resume the processing of a keyring higher up in the tree */
468 sp--;
David Howells76d8aea2005-06-23 22:00:49 -0700469 keylist = stack[sp].keylist;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 kix = stack[sp].kix + 1;
471 goto ascend;
472 }
473
David Howells664cceb2005-09-28 17:03:15 +0100474 key_ref = ERR_PTR(err);
475 goto error_2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476
477 /* we found a viable match */
David Howells664cceb2005-09-28 17:03:15 +0100478found:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 atomic_inc(&key->usage);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 key_check(key);
David Howells664cceb2005-09-28 17:03:15 +0100481 key_ref = make_key_ref(key, possessed);
482error_2:
David Howells76d8aea2005-06-23 22:00:49 -0700483 rcu_read_unlock();
David Howells664cceb2005-09-28 17:03:15 +0100484error:
485 return key_ref;
David Howellsa8b17ed2011-01-20 16:38:27 +0000486}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487
David Howells973c9f42011-01-20 16:38:33 +0000488/**
489 * keyring_search - Search the supplied keyring tree for a matching key
490 * @keyring: The root of the keyring tree to be searched.
491 * @type: The type of keyring we want to find.
492 * @description: The name of the keyring we want to find.
493 *
494 * As keyring_search_aux() above, but using the current task's credentials and
495 * type's default matching function.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 */
David Howells664cceb2005-09-28 17:03:15 +0100497key_ref_t keyring_search(key_ref_t keyring,
498 struct key_type *type,
499 const char *description)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500{
David Howells3e301482005-06-23 22:00:56 -0700501 if (!type->match)
502 return ERR_PTR(-ENOKEY);
503
David Howellsd84f4f92008-11-14 10:39:23 +1100504 return keyring_search_aux(keyring, current->cred,
David Howells78b72802011-03-11 17:57:23 +0000505 type, description, type->match, false);
David Howellsa8b17ed2011-01-20 16:38:27 +0000506}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507EXPORT_SYMBOL(keyring_search);
508
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509/*
David Howells973c9f42011-01-20 16:38:33 +0000510 * Search the given keyring only (no recursion).
511 *
512 * The caller must guarantee that the keyring is a keyring and that the
513 * permission is granted to search the keyring as no check is made here.
514 *
515 * RCU is used to make it unnecessary to lock the keyring key list here.
516 *
517 * Returns a pointer to the found key with usage count incremented if
518 * successful and returns -ENOKEY if not found. Revoked keys and keys not
519 * providing the requested permission are skipped over.
520 *
521 * If successful, the possession indicator is propagated from the keyring ref
522 * to the returned key reference.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 */
David Howells664cceb2005-09-28 17:03:15 +0100524key_ref_t __keyring_search_one(key_ref_t keyring_ref,
525 const struct key_type *ktype,
526 const char *description,
527 key_perm_t perm)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528{
529 struct keyring_list *klist;
David Howells664cceb2005-09-28 17:03:15 +0100530 unsigned long possessed;
531 struct key *keyring, *key;
David Howellsefde8b62012-01-17 20:39:40 +0000532 int nkeys, loop;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533
David Howells664cceb2005-09-28 17:03:15 +0100534 keyring = key_ref_to_ptr(keyring_ref);
535 possessed = is_key_possessed(keyring_ref);
536
David Howells76d8aea2005-06-23 22:00:49 -0700537 rcu_read_lock();
538
539 klist = rcu_dereference(keyring->payload.subscriptions);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 if (klist) {
David Howellsefde8b62012-01-17 20:39:40 +0000541 nkeys = klist->nkeys;
542 smp_rmb();
543 for (loop = 0; loop < nkeys ; loop++) {
David Howells233e4732012-05-11 10:56:56 +0100544 key = rcu_dereference(klist->keys[loop]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 if (key->type == ktype &&
David Howells3e301482005-06-23 22:00:56 -0700546 (!key->type->match ||
547 key->type->match(key, description)) &&
David Howells664cceb2005-09-28 17:03:15 +0100548 key_permission(make_key_ref(key, possessed),
David Howellsdb1d1d52005-12-01 00:51:18 -0800549 perm) == 0 &&
David Howells76d8aea2005-06-23 22:00:49 -0700550 !test_bit(KEY_FLAG_REVOKED, &key->flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 )
552 goto found;
553 }
554 }
555
David Howells664cceb2005-09-28 17:03:15 +0100556 rcu_read_unlock();
557 return ERR_PTR(-ENOKEY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
Justin P. Mattockc5b60b52010-04-21 00:02:11 -0700559found:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 atomic_inc(&key->usage);
David Howells76d8aea2005-06-23 22:00:49 -0700561 rcu_read_unlock();
David Howells664cceb2005-09-28 17:03:15 +0100562 return make_key_ref(key, possessed);
David Howellsa8b17ed2011-01-20 16:38:27 +0000563}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565/*
David Howells973c9f42011-01-20 16:38:33 +0000566 * Find a keyring with the specified name.
567 *
568 * All named keyrings in the current user namespace are searched, provided they
569 * grant Search permission directly to the caller (unless this check is
570 * skipped). Keyrings whose usage points have reached zero or who have been
571 * revoked are skipped.
572 *
573 * Returns a pointer to the keyring with the keyring's refcount having being
574 * incremented on success. -ENOKEY is returned if a key could not be found.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 */
David Howells69664cf2008-04-29 01:01:31 -0700576struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577{
578 struct key *keyring;
579 int bucket;
580
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 if (!name)
Toshiyuki Okajimacea7daa2010-04-30 14:32:13 +0100582 return ERR_PTR(-EINVAL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583
584 bucket = keyring_hash(name);
585
586 read_lock(&keyring_name_lock);
587
588 if (keyring_name_hash[bucket].next) {
589 /* search this hash bucket for a keyring with a matching name
590 * that's readable and that hasn't been revoked */
591 list_for_each_entry(keyring,
592 &keyring_name_hash[bucket],
593 type_data.link
594 ) {
Serge E. Hallyn2ea190d2009-02-26 18:27:55 -0600595 if (keyring->user->user_ns != current_user_ns())
596 continue;
597
David Howells76d8aea2005-06-23 22:00:49 -0700598 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 continue;
600
601 if (strcmp(keyring->description, name) != 0)
602 continue;
603
David Howells69664cf2008-04-29 01:01:31 -0700604 if (!skip_perm_check &&
605 key_permission(make_key_ref(keyring, 0),
David Howells0f6ed7c2005-11-07 00:59:30 -0800606 KEY_SEARCH) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 continue;
608
Toshiyuki Okajimacea7daa2010-04-30 14:32:13 +0100609 /* we've got a match but we might end up racing with
610 * key_cleanup() if the keyring is currently 'dead'
611 * (ie. it has a zero usage count) */
612 if (!atomic_inc_not_zero(&keyring->usage))
613 continue;
614 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 }
616 }
617
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 keyring = ERR_PTR(-ENOKEY);
Toshiyuki Okajimacea7daa2010-04-30 14:32:13 +0100619out:
620 read_unlock(&keyring_name_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 return keyring;
David Howellsa8b17ed2011-01-20 16:38:27 +0000622}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624/*
David Howells973c9f42011-01-20 16:38:33 +0000625 * See if a cycle will will be created by inserting acyclic tree B in acyclic
626 * tree A at the topmost level (ie: as a direct child of A).
627 *
628 * Since we are adding B to A at the top level, checking for cycles should just
629 * be a matter of seeing if node A is somewhere in tree B.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 */
631static int keyring_detect_cycle(struct key *A, struct key *B)
632{
633 struct {
David Howells76d8aea2005-06-23 22:00:49 -0700634 struct keyring_list *keylist;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 int kix;
636 } stack[KEYRING_SEARCH_MAX_DEPTH];
637
638 struct keyring_list *keylist;
639 struct key *subtree, *key;
David Howellsefde8b62012-01-17 20:39:40 +0000640 int sp, nkeys, kix, ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641
David Howells76d8aea2005-06-23 22:00:49 -0700642 rcu_read_lock();
643
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 ret = -EDEADLK;
645 if (A == B)
David Howells76d8aea2005-06-23 22:00:49 -0700646 goto cycle_detected;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647
648 subtree = B;
649 sp = 0;
650
651 /* start processing a new keyring */
Justin P. Mattockc5b60b52010-04-21 00:02:11 -0700652descend:
David Howells76d8aea2005-06-23 22:00:49 -0700653 if (test_bit(KEY_FLAG_REVOKED, &subtree->flags))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 goto not_this_keyring;
655
David Howells76d8aea2005-06-23 22:00:49 -0700656 keylist = rcu_dereference(subtree->payload.subscriptions);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 if (!keylist)
658 goto not_this_keyring;
659 kix = 0;
660
Justin P. Mattockc5b60b52010-04-21 00:02:11 -0700661ascend:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662 /* iterate through the remaining keys in this keyring */
David Howellsefde8b62012-01-17 20:39:40 +0000663 nkeys = keylist->nkeys;
664 smp_rmb();
665 for (; kix < nkeys; kix++) {
David Howells233e4732012-05-11 10:56:56 +0100666 key = rcu_dereference(keylist->keys[kix]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667
668 if (key == A)
669 goto cycle_detected;
670
671 /* recursively check nested keyrings */
672 if (key->type == &key_type_keyring) {
673 if (sp >= KEYRING_SEARCH_MAX_DEPTH)
674 goto too_deep;
675
676 /* stack the current position */
David Howells76d8aea2005-06-23 22:00:49 -0700677 stack[sp].keylist = keylist;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 stack[sp].kix = kix;
679 sp++;
680
681 /* begin again with the new keyring */
682 subtree = key;
683 goto descend;
684 }
685 }
686
687 /* the keyring we're looking at was disqualified or didn't contain a
688 * matching key */
Justin P. Mattockc5b60b52010-04-21 00:02:11 -0700689not_this_keyring:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 if (sp > 0) {
691 /* resume the checking of a keyring higher up in the tree */
692 sp--;
David Howells76d8aea2005-06-23 22:00:49 -0700693 keylist = stack[sp].keylist;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694 kix = stack[sp].kix + 1;
695 goto ascend;
696 }
697
698 ret = 0; /* no cycles detected */
699
Justin P. Mattockc5b60b52010-04-21 00:02:11 -0700700error:
David Howells76d8aea2005-06-23 22:00:49 -0700701 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702 return ret;
703
Justin P. Mattockc5b60b52010-04-21 00:02:11 -0700704too_deep:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705 ret = -ELOOP;
David Howells76d8aea2005-06-23 22:00:49 -0700706 goto error;
707
Justin P. Mattockc5b60b52010-04-21 00:02:11 -0700708cycle_detected:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 ret = -EDEADLK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710 goto error;
David Howellsa8b17ed2011-01-20 16:38:27 +0000711}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712
David Howells76d8aea2005-06-23 22:00:49 -0700713/*
David Howells973c9f42011-01-20 16:38:33 +0000714 * Dispose of a keyring list after the RCU grace period, freeing the unlinked
David Howellscab8eb52006-01-08 01:02:45 -0800715 * key
716 */
717static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
718{
719 struct keyring_list *klist =
720 container_of(rcu, struct keyring_list, rcu);
721
Alexey Dobriyan4be929b2010-05-24 14:33:03 -0700722 if (klist->delkey != USHRT_MAX)
David Howells233e4732012-05-11 10:56:56 +0100723 key_put(rcu_access_pointer(klist->keys[klist->delkey]));
David Howellscab8eb52006-01-08 01:02:45 -0800724 kfree(klist);
David Howellsf70e2e02010-04-30 14:32:39 +0100725}
David Howellscab8eb52006-01-08 01:02:45 -0800726
David Howellscab8eb52006-01-08 01:02:45 -0800727/*
David Howells973c9f42011-01-20 16:38:33 +0000728 * Preallocate memory so that a key can be linked into to a keyring.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 */
David Howellsf70e2e02010-04-30 14:32:39 +0100730int __key_link_begin(struct key *keyring, const struct key_type *type,
David Howellsceb73c12011-01-25 16:34:28 +0000731 const char *description, unsigned long *_prealloc)
David Howellsf70e2e02010-04-30 14:32:39 +0100732 __acquires(&keyring->sem)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733{
734 struct keyring_list *klist, *nklist;
David Howellsceb73c12011-01-25 16:34:28 +0000735 unsigned long prealloc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 unsigned max;
737 size_t size;
David Howellscab8eb52006-01-08 01:02:45 -0800738 int loop, ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739
David Howellsf70e2e02010-04-30 14:32:39 +0100740 kenter("%d,%s,%s,", key_serial(keyring), type->name, description);
741
742 if (keyring->type != &key_type_keyring)
743 return -ENOTDIR;
744
745 down_write(&keyring->sem);
746
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 ret = -EKEYREVOKED;
David Howells76d8aea2005-06-23 22:00:49 -0700748 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
David Howellsf70e2e02010-04-30 14:32:39 +0100749 goto error_krsem;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750
David Howellsf70e2e02010-04-30 14:32:39 +0100751 /* serialise link/link calls to prevent parallel calls causing a cycle
752 * when linking two keyring in opposite orders */
753 if (type == &key_type_keyring)
David Howells553d6032010-04-30 14:32:28 +0100754 down_write(&keyring_serialise_link_sem);
755
David Howellsf70e2e02010-04-30 14:32:39 +0100756 klist = rcu_dereference_locked_keyring(keyring);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757
David Howellscab8eb52006-01-08 01:02:45 -0800758 /* see if there's a matching key we can displace */
David Howellscab8eb52006-01-08 01:02:45 -0800759 if (klist && klist->nkeys > 0) {
David Howellscab8eb52006-01-08 01:02:45 -0800760 for (loop = klist->nkeys - 1; loop >= 0; loop--) {
David Howells233e4732012-05-11 10:56:56 +0100761 struct key *key = rcu_deref_link_locked(klist, loop,
762 keyring);
763 if (key->type == type &&
764 strcmp(key->description, description) == 0) {
765 /* Found a match - we'll replace the link with
766 * one to the new key. We record the slot
767 * position.
768 */
769 klist->delkey = loop;
770 prealloc = 0;
David Howellscab8eb52006-01-08 01:02:45 -0800771 goto done;
772 }
773 }
774 }
775
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 /* check that we aren't going to overrun the user's quota */
777 ret = key_payload_reserve(keyring,
778 keyring->datalen + KEYQUOTA_LINK_BYTES);
779 if (ret < 0)
David Howellsf70e2e02010-04-30 14:32:39 +0100780 goto error_sem;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 if (klist && klist->nkeys < klist->maxkeys) {
David Howellsf70e2e02010-04-30 14:32:39 +0100783 /* there's sufficient slack space to append directly */
David Howells233e4732012-05-11 10:56:56 +0100784 klist->delkey = klist->nkeys;
David Howellsceb73c12011-01-25 16:34:28 +0000785 prealloc = KEY_LINK_FIXQUOTA;
Chihau Chau512ea3b2010-03-08 20:11:34 -0300786 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 /* grow the key list */
788 max = 4;
789 if (klist)
790 max += klist->maxkeys;
791
792 ret = -ENFILE;
Alexey Dobriyan4be929b2010-05-24 14:33:03 -0700793 if (max > USHRT_MAX - 1)
David Howellsf70e2e02010-04-30 14:32:39 +0100794 goto error_quota;
David Howellsa4014d82005-07-07 17:57:03 -0700795 size = sizeof(*klist) + sizeof(struct key *) * max;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 if (size > PAGE_SIZE)
David Howellsf70e2e02010-04-30 14:32:39 +0100797 goto error_quota;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798
799 ret = -ENOMEM;
800 nklist = kmalloc(size, GFP_KERNEL);
801 if (!nklist)
David Howellsf70e2e02010-04-30 14:32:39 +0100802 goto error_quota;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803
David Howellsf70e2e02010-04-30 14:32:39 +0100804 nklist->maxkeys = max;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 if (klist) {
David Howellsf70e2e02010-04-30 14:32:39 +0100806 memcpy(nklist->keys, klist->keys,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 sizeof(struct key *) * klist->nkeys);
David Howellsf70e2e02010-04-30 14:32:39 +0100808 nklist->delkey = klist->nkeys;
809 nklist->nkeys = klist->nkeys + 1;
Alexey Dobriyan4be929b2010-05-24 14:33:03 -0700810 klist->delkey = USHRT_MAX;
David Howellsf70e2e02010-04-30 14:32:39 +0100811 } else {
812 nklist->nkeys = 1;
813 nklist->delkey = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 }
815
816 /* add the key into the new space */
David Howells233e4732012-05-11 10:56:56 +0100817 RCU_INIT_POINTER(nklist->keys[nklist->delkey], NULL);
818 prealloc = (unsigned long)nklist | KEY_LINK_FIXQUOTA;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 }
820
David Howellscab8eb52006-01-08 01:02:45 -0800821done:
David Howellsceb73c12011-01-25 16:34:28 +0000822 *_prealloc = prealloc;
David Howellsf70e2e02010-04-30 14:32:39 +0100823 kleave(" = 0");
824 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825
David Howellsf70e2e02010-04-30 14:32:39 +0100826error_quota:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827 /* undo the quota changes */
828 key_payload_reserve(keyring,
829 keyring->datalen - KEYQUOTA_LINK_BYTES);
David Howellsf70e2e02010-04-30 14:32:39 +0100830error_sem:
831 if (type == &key_type_keyring)
832 up_write(&keyring_serialise_link_sem);
833error_krsem:
834 up_write(&keyring->sem);
835 kleave(" = %d", ret);
836 return ret;
837}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838
David Howellsf70e2e02010-04-30 14:32:39 +0100839/*
David Howells973c9f42011-01-20 16:38:33 +0000840 * Check already instantiated keys aren't going to be a problem.
841 *
842 * The caller must have called __key_link_begin(). Don't need to call this for
843 * keys that were created since __key_link_begin() was called.
David Howellsf70e2e02010-04-30 14:32:39 +0100844 */
845int __key_link_check_live_key(struct key *keyring, struct key *key)
846{
847 if (key->type == &key_type_keyring)
848 /* check that we aren't going to create a cycle by linking one
849 * keyring to another */
850 return keyring_detect_cycle(keyring, key);
851 return 0;
852}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853
David Howellsf70e2e02010-04-30 14:32:39 +0100854/*
David Howells973c9f42011-01-20 16:38:33 +0000855 * Link a key into to a keyring.
856 *
857 * Must be called with __key_link_begin() having being called. Discards any
858 * already extant link to matching key if there is one, so that each keyring
859 * holds at most one link to any given key of a particular type+description
860 * combination.
David Howellsf70e2e02010-04-30 14:32:39 +0100861 */
862void __key_link(struct key *keyring, struct key *key,
David Howellsceb73c12011-01-25 16:34:28 +0000863 unsigned long *_prealloc)
David Howellsf70e2e02010-04-30 14:32:39 +0100864{
865 struct keyring_list *klist, *nklist;
David Howells233e4732012-05-11 10:56:56 +0100866 struct key *discard;
David Howellsf70e2e02010-04-30 14:32:39 +0100867
David Howellsceb73c12011-01-25 16:34:28 +0000868 nklist = (struct keyring_list *)(*_prealloc & ~KEY_LINK_FIXQUOTA);
869 *_prealloc = 0;
David Howellsf70e2e02010-04-30 14:32:39 +0100870
871 kenter("%d,%d,%p", keyring->serial, key->serial, nklist);
872
David Howells6d528b02011-08-22 14:08:51 +0100873 klist = rcu_dereference_locked_keyring(keyring);
David Howellsf70e2e02010-04-30 14:32:39 +0100874
875 atomic_inc(&key->usage);
876
877 /* there's a matching key we can displace or an empty slot in a newly
878 * allocated list we can fill */
879 if (nklist) {
David Howells233e4732012-05-11 10:56:56 +0100880 kdebug("reissue %hu/%hu/%hu",
David Howellsf70e2e02010-04-30 14:32:39 +0100881 nklist->delkey, nklist->nkeys, nklist->maxkeys);
882
David Howells233e4732012-05-11 10:56:56 +0100883 RCU_INIT_POINTER(nklist->keys[nklist->delkey], key);
David Howellsf70e2e02010-04-30 14:32:39 +0100884
885 rcu_assign_pointer(keyring->payload.subscriptions, nklist);
886
887 /* dispose of the old keyring list and, if there was one, the
888 * displaced key */
889 if (klist) {
890 kdebug("dispose %hu/%hu/%hu",
891 klist->delkey, klist->nkeys, klist->maxkeys);
892 call_rcu(&klist->rcu, keyring_unlink_rcu_disposal);
893 }
David Howells233e4732012-05-11 10:56:56 +0100894 } else if (klist->delkey < klist->nkeys) {
895 kdebug("replace %hu/%hu/%hu",
896 klist->delkey, klist->nkeys, klist->maxkeys);
897
898 discard = rcu_dereference_protected(
899 klist->keys[klist->delkey],
900 rwsem_is_locked(&keyring->sem));
901 rcu_assign_pointer(klist->keys[klist->delkey], key);
902 /* The garbage collector will take care of RCU
903 * synchronisation */
904 key_put(discard);
David Howellsf70e2e02010-04-30 14:32:39 +0100905 } else {
906 /* there's sufficient slack space to append directly */
David Howells233e4732012-05-11 10:56:56 +0100907 kdebug("append %hu/%hu/%hu",
908 klist->delkey, klist->nkeys, klist->maxkeys);
909
910 RCU_INIT_POINTER(klist->keys[klist->delkey], key);
David Howellsf70e2e02010-04-30 14:32:39 +0100911 smp_wmb();
912 klist->nkeys++;
913 }
914}
915
916/*
David Howells973c9f42011-01-20 16:38:33 +0000917 * Finish linking a key into to a keyring.
918 *
919 * Must be called with __key_link_begin() having being called.
David Howellsf70e2e02010-04-30 14:32:39 +0100920 */
921void __key_link_end(struct key *keyring, struct key_type *type,
David Howellsceb73c12011-01-25 16:34:28 +0000922 unsigned long prealloc)
David Howellsf70e2e02010-04-30 14:32:39 +0100923 __releases(&keyring->sem)
924{
925 BUG_ON(type == NULL);
926 BUG_ON(type->name == NULL);
David Howellsceb73c12011-01-25 16:34:28 +0000927 kenter("%d,%s,%lx", keyring->serial, type->name, prealloc);
David Howellsf70e2e02010-04-30 14:32:39 +0100928
929 if (type == &key_type_keyring)
930 up_write(&keyring_serialise_link_sem);
931
932 if (prealloc) {
David Howellsceb73c12011-01-25 16:34:28 +0000933 if (prealloc & KEY_LINK_FIXQUOTA)
934 key_payload_reserve(keyring,
935 keyring->datalen -
936 KEYQUOTA_LINK_BYTES);
937 kfree((struct keyring_list *)(prealloc & ~KEY_LINK_FIXQUOTA));
David Howellsf70e2e02010-04-30 14:32:39 +0100938 }
939 up_write(&keyring->sem);
940}
941
David Howells973c9f42011-01-20 16:38:33 +0000942/**
943 * key_link - Link a key to a keyring
944 * @keyring: The keyring to make the link in.
945 * @key: The key to link to.
946 *
947 * Make a link in a keyring to a key, such that the keyring holds a reference
948 * on that key and the key can potentially be found by searching that keyring.
949 *
950 * This function will write-lock the keyring's semaphore and will consume some
951 * of the user's key data quota to hold the link.
952 *
953 * Returns 0 if successful, -ENOTDIR if the keyring isn't a keyring,
954 * -EKEYREVOKED if the keyring has been revoked, -ENFILE if the keyring is
955 * full, -EDQUOT if there is insufficient key data quota remaining to add
956 * another link or -ENOMEM if there's insufficient memory.
957 *
958 * It is assumed that the caller has checked that it is permitted for a link to
959 * be made (the keyring should have Write permission and the key Link
960 * permission).
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961 */
962int key_link(struct key *keyring, struct key *key)
963{
David Howellsceb73c12011-01-25 16:34:28 +0000964 unsigned long prealloc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965 int ret;
966
967 key_check(keyring);
968 key_check(key);
969
David Howellsf70e2e02010-04-30 14:32:39 +0100970 ret = __key_link_begin(keyring, key->type, key->description, &prealloc);
971 if (ret == 0) {
972 ret = __key_link_check_live_key(keyring, key);
973 if (ret == 0)
974 __key_link(keyring, key, &prealloc);
975 __key_link_end(keyring, key->type, prealloc);
976 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977
978 return ret;
David Howellsf70e2e02010-04-30 14:32:39 +0100979}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980EXPORT_SYMBOL(key_link);
981
David Howells973c9f42011-01-20 16:38:33 +0000982/**
983 * key_unlink - Unlink the first link to a key from a keyring.
984 * @keyring: The keyring to remove the link from.
985 * @key: The key the link is to.
986 *
987 * Remove a link from a keyring to a key.
988 *
989 * This function will write-lock the keyring's semaphore.
990 *
991 * Returns 0 if successful, -ENOTDIR if the keyring isn't a keyring, -ENOENT if
992 * the key isn't linked to by the keyring or -ENOMEM if there's insufficient
993 * memory.
994 *
995 * It is assumed that the caller has checked that it is permitted for a link to
996 * be removed (the keyring should have Write permission; no permissions are
997 * required on the key).
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 */
999int key_unlink(struct key *keyring, struct key *key)
1000{
David Howells76d8aea2005-06-23 22:00:49 -07001001 struct keyring_list *klist, *nklist;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002 int loop, ret;
1003
1004 key_check(keyring);
1005 key_check(key);
1006
1007 ret = -ENOTDIR;
1008 if (keyring->type != &key_type_keyring)
1009 goto error;
1010
1011 down_write(&keyring->sem);
1012
David Howellsf0641cb2010-04-30 14:32:18 +01001013 klist = rcu_dereference_locked_keyring(keyring);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014 if (klist) {
1015 /* search the keyring for the key */
1016 for (loop = 0; loop < klist->nkeys; loop++)
David Howells233e4732012-05-11 10:56:56 +01001017 if (rcu_access_pointer(klist->keys[loop]) == key)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018 goto key_is_present;
1019 }
1020
1021 up_write(&keyring->sem);
1022 ret = -ENOENT;
1023 goto error;
1024
David Howells76d8aea2005-06-23 22:00:49 -07001025key_is_present:
1026 /* we need to copy the key list for RCU purposes */
David Howellsa4014d82005-07-07 17:57:03 -07001027 nklist = kmalloc(sizeof(*klist) +
1028 sizeof(struct key *) * klist->maxkeys,
David Howells76d8aea2005-06-23 22:00:49 -07001029 GFP_KERNEL);
1030 if (!nklist)
1031 goto nomem;
1032 nklist->maxkeys = klist->maxkeys;
1033 nklist->nkeys = klist->nkeys - 1;
1034
1035 if (loop > 0)
1036 memcpy(&nklist->keys[0],
1037 &klist->keys[0],
David Howellsa4014d82005-07-07 17:57:03 -07001038 loop * sizeof(struct key *));
David Howells76d8aea2005-06-23 22:00:49 -07001039
1040 if (loop < nklist->nkeys)
1041 memcpy(&nklist->keys[loop],
1042 &klist->keys[loop + 1],
David Howellsa4014d82005-07-07 17:57:03 -07001043 (nklist->nkeys - loop) * sizeof(struct key *));
David Howells76d8aea2005-06-23 22:00:49 -07001044
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 /* adjust the user's quota */
1046 key_payload_reserve(keyring,
1047 keyring->datalen - KEYQUOTA_LINK_BYTES);
1048
David Howells76d8aea2005-06-23 22:00:49 -07001049 rcu_assign_pointer(keyring->payload.subscriptions, nklist);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050
1051 up_write(&keyring->sem);
David Howells76d8aea2005-06-23 22:00:49 -07001052
1053 /* schedule for later cleanup */
1054 klist->delkey = loop;
1055 call_rcu(&klist->rcu, keyring_unlink_rcu_disposal);
1056
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 ret = 0;
1058
David Howells76d8aea2005-06-23 22:00:49 -07001059error:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 return ret;
David Howells76d8aea2005-06-23 22:00:49 -07001061nomem:
1062 ret = -ENOMEM;
1063 up_write(&keyring->sem);
1064 goto error;
David Howellsa8b17ed2011-01-20 16:38:27 +00001065}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066EXPORT_SYMBOL(key_unlink);
1067
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068/*
David Howells973c9f42011-01-20 16:38:33 +00001069 * Dispose of a keyring list after the RCU grace period, releasing the keys it
1070 * links to.
David Howells76d8aea2005-06-23 22:00:49 -07001071 */
1072static void keyring_clear_rcu_disposal(struct rcu_head *rcu)
1073{
1074 struct keyring_list *klist;
1075 int loop;
1076
1077 klist = container_of(rcu, struct keyring_list, rcu);
1078
1079 for (loop = klist->nkeys - 1; loop >= 0; loop--)
David Howells233e4732012-05-11 10:56:56 +01001080 key_put(rcu_access_pointer(klist->keys[loop]));
David Howells76d8aea2005-06-23 22:00:49 -07001081
1082 kfree(klist);
David Howellsa8b17ed2011-01-20 16:38:27 +00001083}
David Howells76d8aea2005-06-23 22:00:49 -07001084
David Howells973c9f42011-01-20 16:38:33 +00001085/**
1086 * keyring_clear - Clear a keyring
1087 * @keyring: The keyring to clear.
1088 *
1089 * Clear the contents of the specified keyring.
1090 *
1091 * Returns 0 if successful or -ENOTDIR if the keyring isn't a keyring.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092 */
1093int keyring_clear(struct key *keyring)
1094{
1095 struct keyring_list *klist;
David Howells76d8aea2005-06-23 22:00:49 -07001096 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097
1098 ret = -ENOTDIR;
1099 if (keyring->type == &key_type_keyring) {
1100 /* detach the pointer block with the locks held */
1101 down_write(&keyring->sem);
1102
David Howellsf0641cb2010-04-30 14:32:18 +01001103 klist = rcu_dereference_locked_keyring(keyring);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104 if (klist) {
1105 /* adjust the quota */
1106 key_payload_reserve(keyring,
1107 sizeof(struct keyring_list));
1108
David Howells76d8aea2005-06-23 22:00:49 -07001109 rcu_assign_pointer(keyring->payload.subscriptions,
1110 NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 }
1112
1113 up_write(&keyring->sem);
1114
1115 /* free the keys after the locks have been dropped */
David Howells76d8aea2005-06-23 22:00:49 -07001116 if (klist)
1117 call_rcu(&klist->rcu, keyring_clear_rcu_disposal);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118
1119 ret = 0;
1120 }
1121
1122 return ret;
David Howellsa8b17ed2011-01-20 16:38:27 +00001123}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124EXPORT_SYMBOL(keyring_clear);
David Howells31204ed2006-06-26 00:24:51 -07001125
David Howells31204ed2006-06-26 00:24:51 -07001126/*
David Howells973c9f42011-01-20 16:38:33 +00001127 * Dispose of the links from a revoked keyring.
1128 *
1129 * This is called with the key sem write-locked.
David Howells31204ed2006-06-26 00:24:51 -07001130 */
1131static void keyring_revoke(struct key *keyring)
1132{
David Howellsf0641cb2010-04-30 14:32:18 +01001133 struct keyring_list *klist;
1134
1135 klist = rcu_dereference_locked_keyring(keyring);
David Howells31204ed2006-06-26 00:24:51 -07001136
1137 /* adjust the quota */
1138 key_payload_reserve(keyring, 0);
1139
1140 if (klist) {
1141 rcu_assign_pointer(keyring->payload.subscriptions, NULL);
1142 call_rcu(&klist->rcu, keyring_clear_rcu_disposal);
1143 }
David Howellsa8b17ed2011-01-20 16:38:27 +00001144}
David Howells5d135442009-09-02 09:14:00 +01001145
1146/*
David Howells973c9f42011-01-20 16:38:33 +00001147 * Determine whether a key is dead.
David Howells5d135442009-09-02 09:14:00 +01001148 */
1149static bool key_is_dead(struct key *key, time_t limit)
1150{
1151 return test_bit(KEY_FLAG_DEAD, &key->flags) ||
1152 (key->expiry > 0 && key->expiry <= limit);
1153}
1154
1155/*
David Howells973c9f42011-01-20 16:38:33 +00001156 * Collect garbage from the contents of a keyring, replacing the old list with
1157 * a new one with the pointers all shuffled down.
1158 *
1159 * Dead keys are classed as oned that are flagged as being dead or are revoked,
1160 * expired or negative keys that were revoked or expired before the specified
1161 * limit.
David Howells5d135442009-09-02 09:14:00 +01001162 */
1163void keyring_gc(struct key *keyring, time_t limit)
1164{
1165 struct keyring_list *klist, *new;
1166 struct key *key;
1167 int loop, keep, max;
1168
David Howellsc08ef802009-09-14 17:26:13 +01001169 kenter("{%x,%s}", key_serial(keyring), keyring->description);
David Howells5d135442009-09-02 09:14:00 +01001170
1171 down_write(&keyring->sem);
1172
David Howellsf0641cb2010-04-30 14:32:18 +01001173 klist = rcu_dereference_locked_keyring(keyring);
David Howells5d135442009-09-02 09:14:00 +01001174 if (!klist)
David Howellsc08ef802009-09-14 17:26:13 +01001175 goto no_klist;
David Howells5d135442009-09-02 09:14:00 +01001176
1177 /* work out how many subscriptions we're keeping */
1178 keep = 0;
1179 for (loop = klist->nkeys - 1; loop >= 0; loop--)
David Howells233e4732012-05-11 10:56:56 +01001180 if (!key_is_dead(rcu_deref_link_locked(klist, loop, keyring),
1181 limit))
David Howells5d135442009-09-02 09:14:00 +01001182 keep++;
1183
1184 if (keep == klist->nkeys)
1185 goto just_return;
1186
1187 /* allocate a new keyring payload */
1188 max = roundup(keep, 4);
1189 new = kmalloc(sizeof(struct keyring_list) + max * sizeof(struct key *),
1190 GFP_KERNEL);
1191 if (!new)
David Howellsc08ef802009-09-14 17:26:13 +01001192 goto nomem;
David Howells5d135442009-09-02 09:14:00 +01001193 new->maxkeys = max;
1194 new->nkeys = 0;
1195 new->delkey = 0;
1196
1197 /* install the live keys
1198 * - must take care as expired keys may be updated back to life
1199 */
1200 keep = 0;
1201 for (loop = klist->nkeys - 1; loop >= 0; loop--) {
David Howells233e4732012-05-11 10:56:56 +01001202 key = rcu_deref_link_locked(klist, loop, keyring);
David Howells5d135442009-09-02 09:14:00 +01001203 if (!key_is_dead(key, limit)) {
1204 if (keep >= max)
1205 goto discard_new;
David Howells233e4732012-05-11 10:56:56 +01001206 RCU_INIT_POINTER(new->keys[keep++], key_get(key));
David Howells5d135442009-09-02 09:14:00 +01001207 }
1208 }
1209 new->nkeys = keep;
1210
1211 /* adjust the quota */
1212 key_payload_reserve(keyring,
1213 sizeof(struct keyring_list) +
1214 KEYQUOTA_LINK_BYTES * keep);
1215
1216 if (keep == 0) {
1217 rcu_assign_pointer(keyring->payload.subscriptions, NULL);
1218 kfree(new);
1219 } else {
1220 rcu_assign_pointer(keyring->payload.subscriptions, new);
1221 }
1222
1223 up_write(&keyring->sem);
1224
1225 call_rcu(&klist->rcu, keyring_clear_rcu_disposal);
1226 kleave(" [yes]");
1227 return;
1228
1229discard_new:
1230 new->nkeys = keep;
1231 keyring_clear_rcu_disposal(&new->rcu);
David Howellsc08ef802009-09-14 17:26:13 +01001232 up_write(&keyring->sem);
1233 kleave(" [discard]");
1234 return;
1235
David Howells5d135442009-09-02 09:14:00 +01001236just_return:
1237 up_write(&keyring->sem);
David Howellsc08ef802009-09-14 17:26:13 +01001238 kleave(" [no dead]");
1239 return;
1240
1241no_klist:
1242 up_write(&keyring->sem);
1243 kleave(" [no_klist]");
1244 return;
1245
1246nomem:
1247 up_write(&keyring->sem);
1248 kleave(" [oom]");
David Howells5d135442009-09-02 09:14:00 +01001249}