aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /security/keys
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/Makefile14
-rw-r--r--security/keys/compat.c78
-rw-r--r--security/keys/internal.h123
-rw-r--r--security/keys/key.c1040
-rw-r--r--security/keys/keyctl.c987
-rw-r--r--security/keys/keyring.c895
-rw-r--r--security/keys/proc.c251
-rw-r--r--security/keys/process_keys.c665
-rw-r--r--security/keys/request_key.c359
-rw-r--r--security/keys/user_defined.c191
10 files changed, 4603 insertions, 0 deletions
diff --git a/security/keys/Makefile b/security/keys/Makefile
new file mode 100644
index 000000000000..ddb495d65062
--- /dev/null
+++ b/security/keys/Makefile
@@ -0,0 +1,14 @@
1#
2# Makefile for key management
3#
4
5obj-y := \
6 key.o \
7 keyring.o \
8 keyctl.o \
9 process_keys.o \
10 user_defined.o \
11 request_key.o
12
13obj-$(CONFIG_KEYS_COMPAT) += compat.o
14obj-$(CONFIG_PROC_FS) += proc.o
diff --git a/security/keys/compat.c b/security/keys/compat.c
new file mode 100644
index 000000000000..aff8b22dcb5c
--- /dev/null
+++ b/security/keys/compat.c
@@ -0,0 +1,78 @@
1/* compat.c: 32-bit compatibility syscall for 64-bit systems
2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/sched.h>
13#include <linux/syscalls.h>
14#include <linux/keyctl.h>
15#include <linux/compat.h>
16#include "internal.h"
17
18/*****************************************************************************/
19/*
20 * the key control system call, 32-bit compatibility version for 64-bit archs
21 * - this should only be called if the 64-bit arch uses weird pointers in
22 * 32-bit mode or doesn't guarantee that the top 32-bits of the argument
23 * registers on taking a 32-bit syscall are zero
24 * - if you can, you should call sys_keyctl directly
25 */
26asmlinkage long compat_sys_keyctl(u32 option,
27 u32 arg2, u32 arg3, u32 arg4, u32 arg5)
28{
29 switch (option) {
30 case KEYCTL_GET_KEYRING_ID:
31 return keyctl_get_keyring_ID(arg2, arg3);
32
33 case KEYCTL_JOIN_SESSION_KEYRING:
34 return keyctl_join_session_keyring(compat_ptr(arg2));
35
36 case KEYCTL_UPDATE:
37 return keyctl_update_key(arg2, compat_ptr(arg3), arg4);
38
39 case KEYCTL_REVOKE:
40 return keyctl_revoke_key(arg2);
41
42 case KEYCTL_DESCRIBE:
43 return keyctl_describe_key(arg2, compat_ptr(arg3), arg4);
44
45 case KEYCTL_CLEAR:
46 return keyctl_keyring_clear(arg2);
47
48 case KEYCTL_LINK:
49 return keyctl_keyring_link(arg2, arg3);
50
51 case KEYCTL_UNLINK:
52 return keyctl_keyring_unlink(arg2, arg3);
53
54 case KEYCTL_SEARCH:
55 return keyctl_keyring_search(arg2, compat_ptr(arg3),
56 compat_ptr(arg4), arg5);
57
58 case KEYCTL_READ:
59 return keyctl_read_key(arg2, compat_ptr(arg3), arg4);
60
61 case KEYCTL_CHOWN:
62 return keyctl_chown_key(arg2, arg3, arg4);
63
64 case KEYCTL_SETPERM:
65 return keyctl_setperm_key(arg2, arg3);
66
67 case KEYCTL_INSTANTIATE:
68 return keyctl_instantiate_key(arg2, compat_ptr(arg3), arg4,
69 arg5);
70
71 case KEYCTL_NEGATE:
72 return keyctl_negate_key(arg2, arg3, arg4);
73
74 default:
75 return -EOPNOTSUPP;
76 }
77
78} /* end compat_sys_keyctl() */
diff --git a/security/keys/internal.h b/security/keys/internal.h
new file mode 100644
index 000000000000..67b2b93a7489
--- /dev/null
+++ b/security/keys/internal.h
@@ -0,0 +1,123 @@
1/* internal.h: authentication token and access key management internal defs
2 *
3 * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#ifndef _INTERNAL_H
13#define _INTERNAL_H
14
15#include <linux/key.h>
16#include <linux/key-ui.h>
17
18extern struct key_type key_type_dead;
19extern struct key_type key_type_user;
20
21/*****************************************************************************/
22/*
23 * keep track of keys for a user
24 * - this needs to be separate to user_struct to avoid a refcount-loop
25 * (user_struct pins some keyrings which pin this struct)
26 * - this also keeps track of keys under request from userspace for this UID
27 */
28struct key_user {
29 struct rb_node node;
30 struct list_head consq; /* construction queue */
31 spinlock_t lock;
32 atomic_t usage; /* for accessing qnkeys & qnbytes */
33 atomic_t nkeys; /* number of keys */
34 atomic_t nikeys; /* number of instantiated keys */
35 uid_t uid;
36 int qnkeys; /* number of keys allocated to this user */
37 int qnbytes; /* number of bytes allocated to this user */
38};
39
40#define KEYQUOTA_MAX_KEYS 100
41#define KEYQUOTA_MAX_BYTES 10000
42#define KEYQUOTA_LINK_BYTES 4 /* a link in a keyring is worth 4 bytes */
43
44extern struct rb_root key_user_tree;
45extern spinlock_t key_user_lock;
46extern struct key_user root_key_user;
47
48extern struct key_user *key_user_lookup(uid_t uid);
49extern void key_user_put(struct key_user *user);
50
51
52
53extern struct rb_root key_serial_tree;
54extern spinlock_t key_serial_lock;
55extern struct semaphore key_alloc_sem;
56extern struct rw_semaphore key_construction_sem;
57extern wait_queue_head_t request_key_conswq;
58
59
60extern void keyring_publish_name(struct key *keyring);
61
62extern int __key_link(struct key *keyring, struct key *key);
63
64extern struct key *__keyring_search_one(struct key *keyring,
65 const struct key_type *type,
66 const char *description,
67 key_perm_t perm);
68
69typedef int (*key_match_func_t)(const struct key *, const void *);
70
71extern struct key *keyring_search_aux(struct key *keyring,
72 struct key_type *type,
73 const void *description,
74 key_match_func_t match);
75
76extern struct key *search_process_keyrings_aux(struct key_type *type,
77 const void *description,
78 key_match_func_t match);
79
80extern struct key *find_keyring_by_name(const char *name, key_serial_t bound);
81
82extern int install_thread_keyring(struct task_struct *tsk);
83
84/*
85 * keyctl functions
86 */
87extern long keyctl_get_keyring_ID(key_serial_t, int);
88extern long keyctl_join_session_keyring(const char __user *);
89extern long keyctl_update_key(key_serial_t, const void __user *, size_t);
90extern long keyctl_revoke_key(key_serial_t);
91extern long keyctl_keyring_clear(key_serial_t);
92extern long keyctl_keyring_link(key_serial_t, key_serial_t);
93extern long keyctl_keyring_unlink(key_serial_t, key_serial_t);
94extern long keyctl_describe_key(key_serial_t, char __user *, size_t);
95extern long keyctl_keyring_search(key_serial_t, const char __user *,
96 const char __user *, key_serial_t);
97extern long keyctl_read_key(key_serial_t, char __user *, size_t);
98extern long keyctl_chown_key(key_serial_t, uid_t, gid_t);
99extern long keyctl_setperm_key(key_serial_t, key_perm_t);
100extern long keyctl_instantiate_key(key_serial_t, const void __user *,
101 size_t, key_serial_t);
102extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t);
103
104
105/*
106 * debugging key validation
107 */
108#ifdef KEY_DEBUGGING
109extern void __key_check(const struct key *);
110
111static inline void key_check(const struct key *key)
112{
113 if (key && (IS_ERR(key) || key->magic != KEY_DEBUG_MAGIC))
114 __key_check(key);
115}
116
117#else
118
119#define key_check(key) do {} while(0)
120
121#endif
122
123#endif /* _INTERNAL_H */
diff --git a/security/keys/key.c b/security/keys/key.c
new file mode 100644
index 000000000000..59402c843203
--- /dev/null
+++ b/security/keys/key.c
@@ -0,0 +1,1040 @@
1/* key.c: basic authentication token and access key management
2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/sched.h>
15#include <linux/slab.h>
16#include <linux/workqueue.h>
17#include <linux/err.h>
18#include "internal.h"
19
20static kmem_cache_t *key_jar;
21static key_serial_t key_serial_next = 3;
22struct rb_root key_serial_tree; /* tree of keys indexed by serial */
23DEFINE_SPINLOCK(key_serial_lock);
24
25struct rb_root key_user_tree; /* tree of quota records indexed by UID */
26DEFINE_SPINLOCK(key_user_lock);
27
28static LIST_HEAD(key_types_list);
29static DECLARE_RWSEM(key_types_sem);
30
31static void key_cleanup(void *data);
32static DECLARE_WORK(key_cleanup_task, key_cleanup, NULL);
33
34/* we serialise key instantiation and link */
35DECLARE_RWSEM(key_construction_sem);
36
37/* any key who's type gets unegistered will be re-typed to this */
38struct key_type key_type_dead = {
39 .name = "dead",
40};
41
42#ifdef KEY_DEBUGGING
43void __key_check(const struct key *key)
44{
45 printk("__key_check: key %p {%08x} should be {%08x}\n",
46 key, key->magic, KEY_DEBUG_MAGIC);
47 BUG();
48}
49#endif
50
51/*****************************************************************************/
52/*
53 * get the key quota record for a user, allocating a new record if one doesn't
54 * already exist
55 */
56struct key_user *key_user_lookup(uid_t uid)
57{
58 struct key_user *candidate = NULL, *user;
59 struct rb_node *parent = NULL;
60 struct rb_node **p;
61
62 try_again:
63 p = &key_user_tree.rb_node;
64 spin_lock(&key_user_lock);
65
66 /* search the tree for a user record with a matching UID */
67 while (*p) {
68 parent = *p;
69 user = rb_entry(parent, struct key_user, node);
70
71 if (uid < user->uid)
72 p = &(*p)->rb_left;
73 else if (uid > user->uid)
74 p = &(*p)->rb_right;
75 else
76 goto found;
77 }
78
79 /* if we get here, we failed to find a match in the tree */
80 if (!candidate) {
81 /* allocate a candidate user record if we don't already have
82 * one */
83 spin_unlock(&key_user_lock);
84
85 user = NULL;
86 candidate = kmalloc(sizeof(struct key_user), GFP_KERNEL);
87 if (unlikely(!candidate))
88 goto out;
89
90 /* the allocation may have scheduled, so we need to repeat the
91 * search lest someone else added the record whilst we were
92 * asleep */
93 goto try_again;
94 }
95
96 /* if we get here, then the user record still hadn't appeared on the
97 * second pass - so we use the candidate record */
98 atomic_set(&candidate->usage, 1);
99 atomic_set(&candidate->nkeys, 0);
100 atomic_set(&candidate->nikeys, 0);
101 candidate->uid = uid;
102 candidate->qnkeys = 0;
103 candidate->qnbytes = 0;
104 spin_lock_init(&candidate->lock);
105 INIT_LIST_HEAD(&candidate->consq);
106
107 rb_link_node(&candidate->node, parent, p);
108 rb_insert_color(&candidate->node, &key_user_tree);
109 spin_unlock(&key_user_lock);
110 user = candidate;
111 goto out;
112
113 /* okay - we found a user record for this UID */
114 found:
115 atomic_inc(&user->usage);
116 spin_unlock(&key_user_lock);
117 if (candidate)
118 kfree(candidate);
119 out:
120 return user;
121
122} /* end key_user_lookup() */
123
124/*****************************************************************************/
125/*
126 * dispose of a user structure
127 */
128void key_user_put(struct key_user *user)
129{
130 if (atomic_dec_and_lock(&user->usage, &key_user_lock)) {
131 rb_erase(&user->node, &key_user_tree);
132 spin_unlock(&key_user_lock);
133
134 kfree(user);
135 }
136
137} /* end key_user_put() */
138
139/*****************************************************************************/
140/*
141 * insert a key with a fixed serial number
142 */
143static void __init __key_insert_serial(struct key *key)
144{
145 struct rb_node *parent, **p;
146 struct key *xkey;
147
148 parent = NULL;
149 p = &key_serial_tree.rb_node;
150
151 while (*p) {
152 parent = *p;
153 xkey = rb_entry(parent, struct key, serial_node);
154
155 if (key->serial < xkey->serial)
156 p = &(*p)->rb_left;
157 else if (key->serial > xkey->serial)
158 p = &(*p)->rb_right;
159 else
160 BUG();
161 }
162
163 /* we've found a suitable hole - arrange for this key to occupy it */
164 rb_link_node(&key->serial_node, parent, p);
165 rb_insert_color(&key->serial_node, &key_serial_tree);
166
167} /* end __key_insert_serial() */
168
169/*****************************************************************************/
170/*
171 * assign a key the next unique serial number
172 * - we work through all the serial numbers between 2 and 2^31-1 in turn and
173 * then wrap
174 */
175static inline void key_alloc_serial(struct key *key)
176{
177 struct rb_node *parent, **p;
178 struct key *xkey;
179
180 spin_lock(&key_serial_lock);
181
182 /* propose a likely serial number and look for a hole for it in the
183 * serial number tree */
184 key->serial = key_serial_next;
185 if (key->serial < 3)
186 key->serial = 3;
187 key_serial_next = key->serial + 1;
188
189 parent = NULL;
190 p = &key_serial_tree.rb_node;
191
192 while (*p) {
193 parent = *p;
194 xkey = rb_entry(parent, struct key, serial_node);
195
196 if (key->serial < xkey->serial)
197 p = &(*p)->rb_left;
198 else if (key->serial > xkey->serial)
199 p = &(*p)->rb_right;
200 else
201 goto serial_exists;
202 }
203 goto insert_here;
204
205 /* we found a key with the proposed serial number - walk the tree from
206 * that point looking for the next unused serial number */
207 serial_exists:
208 for (;;) {
209 key->serial = key_serial_next;
210 if (key->serial < 2)
211 key->serial = 2;
212 key_serial_next = key->serial + 1;
213
214 if (!parent->rb_parent)
215 p = &key_serial_tree.rb_node;
216 else if (parent->rb_parent->rb_left == parent)
217 p = &parent->rb_parent->rb_left;
218 else
219 p = &parent->rb_parent->rb_right;
220
221 parent = rb_next(parent);
222 if (!parent)
223 break;
224
225 xkey = rb_entry(parent, struct key, serial_node);
226 if (key->serial < xkey->serial)
227 goto insert_here;
228 }
229
230 /* we've found a suitable hole - arrange for this key to occupy it */
231 insert_here:
232 rb_link_node(&key->serial_node, parent, p);
233 rb_insert_color(&key->serial_node, &key_serial_tree);
234
235 spin_unlock(&key_serial_lock);
236
237} /* end key_alloc_serial() */
238
239/*****************************************************************************/
240/*
241 * allocate a key of the specified type
242 * - update the user's quota to reflect the existence of the key
243 * - called from a key-type operation with key_types_sem read-locked by either
244 * key_create_or_update() or by key_duplicate(); this prevents unregistration
245 * of the key type
246 * - upon return the key is as yet uninstantiated; the caller needs to either
247 * instantiate the key or discard it before returning
248 */
249struct key *key_alloc(struct key_type *type, const char *desc,
250 uid_t uid, gid_t gid, key_perm_t perm,
251 int not_in_quota)
252{
253 struct key_user *user = NULL;
254 struct key *key;
255 size_t desclen, quotalen;
256
257 key = ERR_PTR(-EINVAL);
258 if (!desc || !*desc)
259 goto error;
260
261 desclen = strlen(desc) + 1;
262 quotalen = desclen + type->def_datalen;
263
264 /* get hold of the key tracking for this user */
265 user = key_user_lookup(uid);
266 if (!user)
267 goto no_memory_1;
268
269 /* check that the user's quota permits allocation of another key and
270 * its description */
271 if (!not_in_quota) {
272 spin_lock(&user->lock);
273 if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS &&
274 user->qnbytes + quotalen >= KEYQUOTA_MAX_BYTES
275 )
276 goto no_quota;
277
278 user->qnkeys++;
279 user->qnbytes += quotalen;
280 spin_unlock(&user->lock);
281 }
282
283 /* allocate and initialise the key and its description */
284 key = kmem_cache_alloc(key_jar, SLAB_KERNEL);
285 if (!key)
286 goto no_memory_2;
287
288 if (desc) {
289 key->description = kmalloc(desclen, GFP_KERNEL);
290 if (!key->description)
291 goto no_memory_3;
292
293 memcpy(key->description, desc, desclen);
294 }
295
296 atomic_set(&key->usage, 1);
297 rwlock_init(&key->lock);
298 init_rwsem(&key->sem);
299 key->type = type;
300 key->user = user;
301 key->quotalen = quotalen;
302 key->datalen = type->def_datalen;
303 key->uid = uid;
304 key->gid = gid;
305 key->perm = perm;
306 key->flags = 0;
307 key->expiry = 0;
308 key->payload.data = NULL;
309
310 if (!not_in_quota)
311 key->flags |= KEY_FLAG_IN_QUOTA;
312
313 memset(&key->type_data, 0, sizeof(key->type_data));
314
315#ifdef KEY_DEBUGGING
316 key->magic = KEY_DEBUG_MAGIC;
317#endif
318
319 /* publish the key by giving it a serial number */
320 atomic_inc(&user->nkeys);
321 key_alloc_serial(key);
322
323 error:
324 return key;
325
326 no_memory_3:
327 kmem_cache_free(key_jar, key);
328 no_memory_2:
329 if (!not_in_quota) {
330 spin_lock(&user->lock);
331 user->qnkeys--;
332 user->qnbytes -= quotalen;
333 spin_unlock(&user->lock);
334 }
335 key_user_put(user);
336 no_memory_1:
337 key = ERR_PTR(-ENOMEM);
338 goto error;
339
340 no_quota:
341 spin_unlock(&user->lock);
342 key_user_put(user);
343 key = ERR_PTR(-EDQUOT);
344 goto error;
345
346} /* end key_alloc() */
347
348EXPORT_SYMBOL(key_alloc);
349
350/*****************************************************************************/
351/*
352 * reserve an amount of quota for the key's payload
353 */
354int key_payload_reserve(struct key *key, size_t datalen)
355{
356 int delta = (int) datalen - key->datalen;
357 int ret = 0;
358
359 key_check(key);
360
361 /* contemplate the quota adjustment */
362 if (delta != 0 && key->flags & KEY_FLAG_IN_QUOTA) {
363 spin_lock(&key->user->lock);
364
365 if (delta > 0 &&
366 key->user->qnbytes + delta > KEYQUOTA_MAX_BYTES
367 ) {
368 ret = -EDQUOT;
369 }
370 else {
371 key->user->qnbytes += delta;
372 key->quotalen += delta;
373 }
374 spin_unlock(&key->user->lock);
375 }
376
377 /* change the recorded data length if that didn't generate an error */
378 if (ret == 0)
379 key->datalen = datalen;
380
381 return ret;
382
383} /* end key_payload_reserve() */
384
385EXPORT_SYMBOL(key_payload_reserve);
386
387/*****************************************************************************/
388/*
389 * instantiate a key and link it into the target keyring atomically
390 * - called with the target keyring's semaphore writelocked
391 */
392static int __key_instantiate_and_link(struct key *key,
393 const void *data,
394 size_t datalen,
395 struct key *keyring)
396{
397 int ret, awaken;
398
399 key_check(key);
400 key_check(keyring);
401
402 awaken = 0;
403 ret = -EBUSY;
404
405 down_write(&key_construction_sem);
406
407 /* can't instantiate twice */
408 if (!(key->flags & KEY_FLAG_INSTANTIATED)) {
409 /* instantiate the key */
410 ret = key->type->instantiate(key, data, datalen);
411
412 if (ret == 0) {
413 /* mark the key as being instantiated */
414 write_lock(&key->lock);
415
416 atomic_inc(&key->user->nikeys);
417 key->flags |= KEY_FLAG_INSTANTIATED;
418
419 if (key->flags & KEY_FLAG_USER_CONSTRUCT) {
420 key->flags &= ~KEY_FLAG_USER_CONSTRUCT;
421 awaken = 1;
422 }
423
424 write_unlock(&key->lock);
425
426 /* and link it into the destination keyring */
427 if (keyring)
428 ret = __key_link(keyring, key);
429 }
430 }
431
432 up_write(&key_construction_sem);
433
434 /* wake up anyone waiting for a key to be constructed */
435 if (awaken)
436 wake_up_all(&request_key_conswq);
437
438 return ret;
439
440} /* end __key_instantiate_and_link() */
441
442/*****************************************************************************/
443/*
444 * instantiate a key and link it into the target keyring atomically
445 */
446int key_instantiate_and_link(struct key *key,
447 const void *data,
448 size_t datalen,
449 struct key *keyring)
450{
451 int ret;
452
453 if (keyring)
454 down_write(&keyring->sem);
455
456 ret = __key_instantiate_and_link(key, data, datalen, keyring);
457
458 if (keyring)
459 up_write(&keyring->sem);
460
461 return ret;
462} /* end key_instantiate_and_link() */
463
464EXPORT_SYMBOL(key_instantiate_and_link);
465
466/*****************************************************************************/
467/*
468 * negatively instantiate a key and link it into the target keyring atomically
469 */
470int key_negate_and_link(struct key *key,
471 unsigned timeout,
472 struct key *keyring)
473{
474 struct timespec now;
475 int ret, awaken;
476
477 key_check(key);
478 key_check(keyring);
479
480 awaken = 0;
481 ret = -EBUSY;
482
483 if (keyring)
484 down_write(&keyring->sem);
485
486 down_write(&key_construction_sem);
487
488 /* can't instantiate twice */
489 if (!(key->flags & KEY_FLAG_INSTANTIATED)) {
490 /* mark the key as being negatively instantiated */
491 write_lock(&key->lock);
492
493 atomic_inc(&key->user->nikeys);
494 key->flags |= KEY_FLAG_INSTANTIATED | KEY_FLAG_NEGATIVE;
495 now = current_kernel_time();
496 key->expiry = now.tv_sec + timeout;
497
498 if (key->flags & KEY_FLAG_USER_CONSTRUCT) {
499 key->flags &= ~KEY_FLAG_USER_CONSTRUCT;
500 awaken = 1;
501 }
502
503 write_unlock(&key->lock);
504 ret = 0;
505
506 /* and link it into the destination keyring */
507 if (keyring)
508 ret = __key_link(keyring, key);
509 }
510
511 up_write(&key_construction_sem);
512
513 if (keyring)
514 up_write(&keyring->sem);
515
516 /* wake up anyone waiting for a key to be constructed */
517 if (awaken)
518 wake_up_all(&request_key_conswq);
519
520 return ret;
521
522} /* end key_negate_and_link() */
523
524EXPORT_SYMBOL(key_negate_and_link);
525
526/*****************************************************************************/
527/*
528 * do cleaning up in process context so that we don't have to disable
529 * interrupts all over the place
530 */
531static void key_cleanup(void *data)
532{
533 struct rb_node *_n;
534 struct key *key;
535
536 go_again:
537 /* look for a dead key in the tree */
538 spin_lock(&key_serial_lock);
539
540 for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
541 key = rb_entry(_n, struct key, serial_node);
542
543 if (atomic_read(&key->usage) == 0)
544 goto found_dead_key;
545 }
546
547 spin_unlock(&key_serial_lock);
548 return;
549
550 found_dead_key:
551 /* we found a dead key - once we've removed it from the tree, we can
552 * drop the lock */
553 rb_erase(&key->serial_node, &key_serial_tree);
554 spin_unlock(&key_serial_lock);
555
556 /* deal with the user's key tracking and quota */
557 if (key->flags & KEY_FLAG_IN_QUOTA) {
558 spin_lock(&key->user->lock);
559 key->user->qnkeys--;
560 key->user->qnbytes -= key->quotalen;
561 spin_unlock(&key->user->lock);
562 }
563
564 atomic_dec(&key->user->nkeys);
565 if (key->flags & KEY_FLAG_INSTANTIATED)
566 atomic_dec(&key->user->nikeys);
567
568 key_user_put(key->user);
569
570 /* now throw away the key memory */
571 if (key->type->destroy)
572 key->type->destroy(key);
573
574 kfree(key->description);
575
576#ifdef KEY_DEBUGGING
577 key->magic = KEY_DEBUG_MAGIC_X;
578#endif
579 kmem_cache_free(key_jar, key);
580
581 /* there may, of course, be more than one key to destroy */
582 goto go_again;
583
584} /* end key_cleanup() */
585
586/*****************************************************************************/
587/*
588 * dispose of a reference to a key
589 * - when all the references are gone, we schedule the cleanup task to come and
590 * pull it out of the tree in definite process context
591 */
592void key_put(struct key *key)
593{
594 if (key) {
595 key_check(key);
596
597 if (atomic_dec_and_test(&key->usage))
598 schedule_work(&key_cleanup_task);
599 }
600
601} /* end key_put() */
602
603EXPORT_SYMBOL(key_put);
604
605/*****************************************************************************/
606/*
607 * find a key by its serial number
608 */
609struct key *key_lookup(key_serial_t id)
610{
611 struct rb_node *n;
612 struct key *key;
613
614 spin_lock(&key_serial_lock);
615
616 /* search the tree for the specified key */
617 n = key_serial_tree.rb_node;
618 while (n) {
619 key = rb_entry(n, struct key, serial_node);
620
621 if (id < key->serial)
622 n = n->rb_left;
623 else if (id > key->serial)
624 n = n->rb_right;
625 else
626 goto found;
627 }
628
629 not_found:
630 key = ERR_PTR(-ENOKEY);
631 goto error;
632
633 found:
634 /* pretent doesn't exist if it's dead */
635 if (atomic_read(&key->usage) == 0 ||
636 (key->flags & KEY_FLAG_DEAD) ||
637 key->type == &key_type_dead)
638 goto not_found;
639
640 /* this races with key_put(), but that doesn't matter since key_put()
641 * doesn't actually change the key
642 */
643 atomic_inc(&key->usage);
644
645 error:
646 spin_unlock(&key_serial_lock);
647 return key;
648
649} /* end key_lookup() */
650
651/*****************************************************************************/
652/*
653 * find and lock the specified key type against removal
654 * - we return with the sem readlocked
655 */
656struct key_type *key_type_lookup(const char *type)
657{
658 struct key_type *ktype;
659
660 down_read(&key_types_sem);
661
662 /* look up the key type to see if it's one of the registered kernel
663 * types */
664 list_for_each_entry(ktype, &key_types_list, link) {
665 if (strcmp(ktype->name, type) == 0)
666 goto found_kernel_type;
667 }
668
669 up_read(&key_types_sem);
670 ktype = ERR_PTR(-ENOKEY);
671
672 found_kernel_type:
673 return ktype;
674
675} /* end key_type_lookup() */
676
677/*****************************************************************************/
678/*
679 * unlock a key type
680 */
681void key_type_put(struct key_type *ktype)
682{
683 up_read(&key_types_sem);
684
685} /* end key_type_put() */
686
687/*****************************************************************************/
688/*
689 * attempt to update an existing key
690 * - the key has an incremented refcount
691 * - we need to put the key if we get an error
692 */
693static inline struct key *__key_update(struct key *key, const void *payload,
694 size_t plen)
695{
696 int ret;
697
698 /* need write permission on the key to update it */
699 ret = -EACCES;
700 if (!key_permission(key, KEY_WRITE))
701 goto error;
702
703 ret = -EEXIST;
704 if (!key->type->update)
705 goto error;
706
707 down_write(&key->sem);
708
709 ret = key->type->update(key, payload, plen);
710
711 if (ret == 0) {
712 /* updating a negative key instantiates it */
713 write_lock(&key->lock);
714 key->flags &= ~KEY_FLAG_NEGATIVE;
715 write_unlock(&key->lock);
716 }
717
718 up_write(&key->sem);
719
720 if (ret < 0)
721 goto error;
722 out:
723 return key;
724
725 error:
726 key_put(key);
727 key = ERR_PTR(ret);
728 goto out;
729
730} /* end __key_update() */
731
732/*****************************************************************************/
733/*
734 * search the specified keyring for a key of the same description; if one is
735 * found, update it, otherwise add a new one
736 */
737struct key *key_create_or_update(struct key *keyring,
738 const char *type,
739 const char *description,
740 const void *payload,
741 size_t plen,
742 int not_in_quota)
743{
744 struct key_type *ktype;
745 struct key *key = NULL;
746 key_perm_t perm;
747 int ret;
748
749 key_check(keyring);
750
751 /* look up the key type to see if it's one of the registered kernel
752 * types */
753 ktype = key_type_lookup(type);
754 if (IS_ERR(ktype)) {
755 key = ERR_PTR(-ENODEV);
756 goto error;
757 }
758
759 ret = -EINVAL;
760 if (!ktype->match || !ktype->instantiate)
761 goto error_2;
762
763 /* search for an existing key of the same type and description in the
764 * destination keyring
765 */
766 down_write(&keyring->sem);
767
768 key = __keyring_search_one(keyring, ktype, description, 0);
769 if (!IS_ERR(key))
770 goto found_matching_key;
771
772 /* if we're going to allocate a new key, we're going to have to modify
773 * the keyring */
774 ret = -EACCES;
775 if (!key_permission(keyring, KEY_WRITE))
776 goto error_3;
777
778 /* decide on the permissions we want */
779 perm = KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK;
780
781 if (ktype->read)
782 perm |= KEY_USR_READ;
783
784 if (ktype == &key_type_keyring || ktype->update)
785 perm |= KEY_USR_WRITE;
786
787 /* allocate a new key */
788 key = key_alloc(ktype, description, current->fsuid, current->fsgid,
789 perm, not_in_quota);
790 if (IS_ERR(key)) {
791 ret = PTR_ERR(key);
792 goto error_3;
793 }
794
795 /* instantiate it and link it into the target keyring */
796 ret = __key_instantiate_and_link(key, payload, plen, keyring);
797 if (ret < 0) {
798 key_put(key);
799 key = ERR_PTR(ret);
800 }
801
802 error_3:
803 up_write(&keyring->sem);
804 error_2:
805 key_type_put(ktype);
806 error:
807 return key;
808
809 found_matching_key:
810 /* we found a matching key, so we're going to try to update it
811 * - we can drop the locks first as we have the key pinned
812 */
813 up_write(&keyring->sem);
814 key_type_put(ktype);
815
816 key = __key_update(key, payload, plen);
817 goto error;
818
819} /* end key_create_or_update() */
820
821EXPORT_SYMBOL(key_create_or_update);
822
823/*****************************************************************************/
824/*
825 * update a key
826 */
827int key_update(struct key *key, const void *payload, size_t plen)
828{
829 int ret;
830
831 key_check(key);
832
833 /* the key must be writable */
834 ret = -EACCES;
835 if (!key_permission(key, KEY_WRITE))
836 goto error;
837
838 /* attempt to update it if supported */
839 ret = -EOPNOTSUPP;
840 if (key->type->update) {
841 down_write(&key->sem);
842 ret = key->type->update(key, payload, plen);
843
844 if (ret == 0) {
845 /* updating a negative key instantiates it */
846 write_lock(&key->lock);
847 key->flags &= ~KEY_FLAG_NEGATIVE;
848 write_unlock(&key->lock);
849 }
850
851 up_write(&key->sem);
852 }
853
854 error:
855 return ret;
856
857} /* end key_update() */
858
859EXPORT_SYMBOL(key_update);
860
861/*****************************************************************************/
862/*
863 * duplicate a key, potentially with a revised description
864 * - must be supported by the keytype (keyrings for instance can be duplicated)
865 */
866struct key *key_duplicate(struct key *source, const char *desc)
867{
868 struct key *key;
869 int ret;
870
871 key_check(source);
872
873 if (!desc)
874 desc = source->description;
875
876 down_read(&key_types_sem);
877
878 ret = -EINVAL;
879 if (!source->type->duplicate)
880 goto error;
881
882 /* allocate and instantiate a key */
883 key = key_alloc(source->type, desc, current->fsuid, current->fsgid,
884 source->perm, 0);
885 if (IS_ERR(key))
886 goto error_k;
887
888 down_read(&source->sem);
889 ret = key->type->duplicate(key, source);
890 up_read(&source->sem);
891 if (ret < 0)
892 goto error2;
893
894 atomic_inc(&key->user->nikeys);
895
896 write_lock(&key->lock);
897 key->flags |= KEY_FLAG_INSTANTIATED;
898 write_unlock(&key->lock);
899
900 error_k:
901 up_read(&key_types_sem);
902 out:
903 return key;
904
905 error2:
906 key_put(key);
907 error:
908 up_read(&key_types_sem);
909 key = ERR_PTR(ret);
910 goto out;
911
912} /* end key_duplicate() */
913
914/*****************************************************************************/
915/*
916 * revoke a key
917 */
918void key_revoke(struct key *key)
919{
920 key_check(key);
921
922 /* make sure no one's trying to change or use the key when we mark
923 * it */
924 down_write(&key->sem);
925 write_lock(&key->lock);
926 key->flags |= KEY_FLAG_REVOKED;
927 write_unlock(&key->lock);
928 up_write(&key->sem);
929
930} /* end key_revoke() */
931
932EXPORT_SYMBOL(key_revoke);
933
934/*****************************************************************************/
935/*
936 * register a type of key
937 */
938int register_key_type(struct key_type *ktype)
939{
940 struct key_type *p;
941 int ret;
942
943 ret = -EEXIST;
944 down_write(&key_types_sem);
945
946 /* disallow key types with the same name */
947 list_for_each_entry(p, &key_types_list, link) {
948 if (strcmp(p->name, ktype->name) == 0)
949 goto out;
950 }
951
952 /* store the type */
953 list_add(&ktype->link, &key_types_list);
954 ret = 0;
955
956 out:
957 up_write(&key_types_sem);
958 return ret;
959
960} /* end register_key_type() */
961
962EXPORT_SYMBOL(register_key_type);
963
964/*****************************************************************************/
965/*
966 * unregister a type of key
967 */
968void unregister_key_type(struct key_type *ktype)
969{
970 struct rb_node *_n;
971 struct key *key;
972
973 down_write(&key_types_sem);
974
975 /* withdraw the key type */
976 list_del_init(&ktype->link);
977
978 /* need to withdraw all keys of this type */
979 spin_lock(&key_serial_lock);
980
981 for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
982 key = rb_entry(_n, struct key, serial_node);
983
984 if (key->type != ktype)
985 continue;
986
987 write_lock(&key->lock);
988 key->type = &key_type_dead;
989 write_unlock(&key->lock);
990
991 /* there shouldn't be anyone looking at the description or
992 * payload now */
993 if (ktype->destroy)
994 ktype->destroy(key);
995 memset(&key->payload, 0xbd, sizeof(key->payload));
996 }
997
998 spin_unlock(&key_serial_lock);
999 up_write(&key_types_sem);
1000
1001} /* end unregister_key_type() */
1002
1003EXPORT_SYMBOL(unregister_key_type);
1004
1005/*****************************************************************************/
1006/*
1007 * initialise the key management stuff
1008 */
1009void __init key_init(void)
1010{
1011 /* allocate a slab in which we can store keys */
1012 key_jar = kmem_cache_create("key_jar", sizeof(struct key),
1013 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
1014
1015 /* add the special key types */
1016 list_add_tail(&key_type_keyring.link, &key_types_list);
1017 list_add_tail(&key_type_dead.link, &key_types_list);
1018 list_add_tail(&key_type_user.link, &key_types_list);
1019
1020 /* record the root user tracking */
1021 rb_link_node(&root_key_user.node,
1022 NULL,
1023 &key_user_tree.rb_node);
1024
1025 rb_insert_color(&root_key_user.node,
1026 &key_user_tree);
1027
1028 /* record root's user standard keyrings */
1029 key_check(&root_user_keyring);
1030 key_check(&root_session_keyring);
1031
1032 __key_insert_serial(&root_user_keyring);
1033 __key_insert_serial(&root_session_keyring);
1034
1035 keyring_publish_name(&root_user_keyring);
1036 keyring_publish_name(&root_session_keyring);
1037
1038 /* link the two root keyrings together */
1039 key_link(&root_session_keyring, &root_user_keyring);
1040} /* end key_init() */
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
new file mode 100644
index 000000000000..dc0011b3fac9
--- /dev/null
+++ b/security/keys/keyctl.c
@@ -0,0 +1,987 @@
1/* keyctl.c: userspace keyctl operations
2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/sched.h>
15#include <linux/slab.h>
16#include <linux/syscalls.h>
17#include <linux/keyctl.h>
18#include <linux/fs.h>
19#include <linux/err.h>
20#include <asm/uaccess.h>
21#include "internal.h"
22
23/*****************************************************************************/
24/*
25 * extract the description of a new key from userspace and either add it as a
26 * new key to the specified keyring or update a matching key in that keyring
27 * - the keyring must be writable
28 * - returns the new key's serial number
29 * - implements add_key()
30 */
31asmlinkage long sys_add_key(const char __user *_type,
32 const char __user *_description,
33 const void __user *_payload,
34 size_t plen,
35 key_serial_t ringid)
36{
37 struct key *keyring, *key;
38 char type[32], *description;
39 void *payload;
40 long dlen, ret;
41
42 ret = -EINVAL;
43 if (plen > 32767)
44 goto error;
45
46 /* draw all the data into kernel space */
47 ret = strncpy_from_user(type, _type, sizeof(type) - 1);
48 if (ret < 0)
49 goto error;
50 type[31] = '\0';
51
52 ret = -EFAULT;
53 dlen = strnlen_user(_description, PAGE_SIZE - 1);
54 if (dlen <= 0)
55 goto error;
56
57 ret = -EINVAL;
58 if (dlen > PAGE_SIZE - 1)
59 goto error;
60
61 ret = -ENOMEM;
62 description = kmalloc(dlen + 1, GFP_KERNEL);
63 if (!description)
64 goto error;
65
66 ret = -EFAULT;
67 if (copy_from_user(description, _description, dlen + 1) != 0)
68 goto error2;
69
70 /* pull the payload in if one was supplied */
71 payload = NULL;
72
73 if (_payload) {
74 ret = -ENOMEM;
75 payload = kmalloc(plen, GFP_KERNEL);
76 if (!payload)
77 goto error2;
78
79 ret = -EFAULT;
80 if (copy_from_user(payload, _payload, plen) != 0)
81 goto error3;
82 }
83
84 /* find the target keyring (which must be writable) */
85 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
86 if (IS_ERR(keyring)) {
87 ret = PTR_ERR(keyring);
88 goto error3;
89 }
90
91 /* create or update the requested key and add it to the target
92 * keyring */
93 key = key_create_or_update(keyring, type, description,
94 payload, plen, 0);
95 if (!IS_ERR(key)) {
96 ret = key->serial;
97 key_put(key);
98 }
99 else {
100 ret = PTR_ERR(key);
101 }
102
103 key_put(keyring);
104 error3:
105 kfree(payload);
106 error2:
107 kfree(description);
108 error:
109 return ret;
110
111} /* end sys_add_key() */
112
113/*****************************************************************************/
114/*
115 * search the process keyrings for a matching key
116 * - nested keyrings may also be searched if they have Search permission
117 * - if a key is found, it will be attached to the destination keyring if
118 * there's one specified
119 * - /sbin/request-key will be invoked if _callout_info is non-NULL
120 * - the _callout_info string will be passed to /sbin/request-key
121 * - if the _callout_info string is empty, it will be rendered as "-"
122 * - implements request_key()
123 */
124asmlinkage long sys_request_key(const char __user *_type,
125 const char __user *_description,
126 const char __user *_callout_info,
127 key_serial_t destringid)
128{
129 struct key_type *ktype;
130 struct key *key, *dest;
131 char type[32], *description, *callout_info;
132 long dlen, ret;
133
134 /* pull the type into kernel space */
135 ret = strncpy_from_user(type, _type, sizeof(type) - 1);
136 if (ret < 0)
137 goto error;
138 type[31] = '\0';
139
140 /* pull the description into kernel space */
141 ret = -EFAULT;
142 dlen = strnlen_user(_description, PAGE_SIZE - 1);
143 if (dlen <= 0)
144 goto error;
145
146 ret = -EINVAL;
147 if (dlen > PAGE_SIZE - 1)
148 goto error;
149
150 ret = -ENOMEM;
151 description = kmalloc(dlen + 1, GFP_KERNEL);
152 if (!description)
153 goto error;
154
155 ret = -EFAULT;
156 if (copy_from_user(description, _description, dlen + 1) != 0)
157 goto error2;
158
159 /* pull the callout info into kernel space */
160 callout_info = NULL;
161 if (_callout_info) {
162 ret = -EFAULT;
163 dlen = strnlen_user(_callout_info, PAGE_SIZE - 1);
164 if (dlen <= 0)
165 goto error2;
166
167 ret = -EINVAL;
168 if (dlen > PAGE_SIZE - 1)
169 goto error2;
170
171 ret = -ENOMEM;
172 callout_info = kmalloc(dlen + 1, GFP_KERNEL);
173 if (!callout_info)
174 goto error2;
175
176 ret = -EFAULT;
177 if (copy_from_user(callout_info, _callout_info, dlen + 1) != 0)
178 goto error3;
179 }
180
181 /* get the destination keyring if specified */
182 dest = NULL;
183 if (destringid) {
184 dest = lookup_user_key(destringid, 1, 0, KEY_WRITE);
185 if (IS_ERR(dest)) {
186 ret = PTR_ERR(dest);
187 goto error3;
188 }
189 }
190
191 /* find the key type */
192 ktype = key_type_lookup(type);
193 if (IS_ERR(ktype)) {
194 ret = PTR_ERR(ktype);
195 goto error4;
196 }
197
198 /* do the search */
199 key = request_key(ktype, description, callout_info);
200 if (IS_ERR(key)) {
201 ret = PTR_ERR(key);
202 goto error5;
203 }
204
205 /* link the resulting key to the destination keyring */
206 if (dest) {
207 ret = key_link(dest, key);
208 if (ret < 0)
209 goto error6;
210 }
211
212 ret = key->serial;
213
214 error6:
215 key_put(key);
216 error5:
217 key_type_put(ktype);
218 error4:
219 key_put(dest);
220 error3:
221 kfree(callout_info);
222 error2:
223 kfree(description);
224 error:
225 return ret;
226
227} /* end sys_request_key() */
228
229/*****************************************************************************/
230/*
231 * get the ID of the specified process keyring
232 * - the keyring must have search permission to be found
233 * - implements keyctl(KEYCTL_GET_KEYRING_ID)
234 */
235long keyctl_get_keyring_ID(key_serial_t id, int create)
236{
237 struct key *key;
238 long ret;
239
240 key = lookup_user_key(id, create, 0, KEY_SEARCH);
241 if (IS_ERR(key)) {
242 ret = PTR_ERR(key);
243 goto error;
244 }
245
246 ret = key->serial;
247 key_put(key);
248 error:
249 return ret;
250
251} /* end keyctl_get_keyring_ID() */
252
253/*****************************************************************************/
254/*
255 * join the session keyring
256 * - implements keyctl(KEYCTL_JOIN_SESSION_KEYRING)
257 */
258long keyctl_join_session_keyring(const char __user *_name)
259{
260 char *name;
261 long nlen, ret;
262
263 /* fetch the name from userspace */
264 name = NULL;
265 if (_name) {
266 ret = -EFAULT;
267 nlen = strnlen_user(_name, PAGE_SIZE - 1);
268 if (nlen <= 0)
269 goto error;
270
271 ret = -EINVAL;
272 if (nlen > PAGE_SIZE - 1)
273 goto error;
274
275 ret = -ENOMEM;
276 name = kmalloc(nlen + 1, GFP_KERNEL);
277 if (!name)
278 goto error;
279
280 ret = -EFAULT;
281 if (copy_from_user(name, _name, nlen + 1) != 0)
282 goto error2;
283 }
284
285 /* join the session */
286 ret = join_session_keyring(name);
287
288 error2:
289 kfree(name);
290 error:
291 return ret;
292
293} /* end keyctl_join_session_keyring() */
294
295/*****************************************************************************/
296/*
297 * update a key's data payload
298 * - the key must be writable
299 * - implements keyctl(KEYCTL_UPDATE)
300 */
301long keyctl_update_key(key_serial_t id,
302 const void __user *_payload,
303 size_t plen)
304{
305 struct key *key;
306 void *payload;
307 long ret;
308
309 ret = -EINVAL;
310 if (plen > PAGE_SIZE)
311 goto error;
312
313 /* pull the payload in if one was supplied */
314 payload = NULL;
315 if (_payload) {
316 ret = -ENOMEM;
317 payload = kmalloc(plen, GFP_KERNEL);
318 if (!payload)
319 goto error;
320
321 ret = -EFAULT;
322 if (copy_from_user(payload, _payload, plen) != 0)
323 goto error2;
324 }
325
326 /* find the target key (which must be writable) */
327 key = lookup_user_key(id, 0, 0, KEY_WRITE);
328 if (IS_ERR(key)) {
329 ret = PTR_ERR(key);
330 goto error2;
331 }
332
333 /* update the key */
334 ret = key_update(key, payload, plen);
335
336 key_put(key);
337 error2:
338 kfree(payload);
339 error:
340 return ret;
341
342} /* end keyctl_update_key() */
343
344/*****************************************************************************/
345/*
346 * revoke a key
347 * - the key must be writable
348 * - implements keyctl(KEYCTL_REVOKE)
349 */
350long keyctl_revoke_key(key_serial_t id)
351{
352 struct key *key;
353 long ret;
354
355 key = lookup_user_key(id, 0, 0, KEY_WRITE);
356 if (IS_ERR(key)) {
357 ret = PTR_ERR(key);
358 goto error;
359 }
360
361 key_revoke(key);
362 ret = 0;
363
364 key_put(key);
365 error:
366 return 0;
367
368} /* end keyctl_revoke_key() */
369
370/*****************************************************************************/
371/*
372 * clear the specified process keyring
373 * - the keyring must be writable
374 * - implements keyctl(KEYCTL_CLEAR)
375 */
376long keyctl_keyring_clear(key_serial_t ringid)
377{
378 struct key *keyring;
379 long ret;
380
381 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
382 if (IS_ERR(keyring)) {
383 ret = PTR_ERR(keyring);
384 goto error;
385 }
386
387 ret = keyring_clear(keyring);
388
389 key_put(keyring);
390 error:
391 return ret;
392
393} /* end keyctl_keyring_clear() */
394
395/*****************************************************************************/
396/*
397 * link a key into a keyring
398 * - the keyring must be writable
399 * - the key must be linkable
400 * - implements keyctl(KEYCTL_LINK)
401 */
402long keyctl_keyring_link(key_serial_t id, key_serial_t ringid)
403{
404 struct key *keyring, *key;
405 long ret;
406
407 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
408 if (IS_ERR(keyring)) {
409 ret = PTR_ERR(keyring);
410 goto error;
411 }
412
413 key = lookup_user_key(id, 1, 0, KEY_LINK);
414 if (IS_ERR(key)) {
415 ret = PTR_ERR(key);
416 goto error2;
417 }
418
419 ret = key_link(keyring, key);
420
421 key_put(key);
422 error2:
423 key_put(keyring);
424 error:
425 return ret;
426
427} /* end keyctl_keyring_link() */
428
429/*****************************************************************************/
430/*
431 * unlink the first attachment of a key from a keyring
432 * - the keyring must be writable
433 * - we don't need any permissions on the key
434 * - implements keyctl(KEYCTL_UNLINK)
435 */
436long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid)
437{
438 struct key *keyring, *key;
439 long ret;
440
441 keyring = lookup_user_key(ringid, 0, 0, KEY_WRITE);
442 if (IS_ERR(keyring)) {
443 ret = PTR_ERR(keyring);
444 goto error;
445 }
446
447 key = lookup_user_key(id, 0, 0, 0);
448 if (IS_ERR(key)) {
449 ret = PTR_ERR(key);
450 goto error2;
451 }
452
453 ret = key_unlink(keyring, key);
454
455 key_put(key);
456 error2:
457 key_put(keyring);
458 error:
459 return ret;
460
461} /* end keyctl_keyring_unlink() */
462
463/*****************************************************************************/
464/*
465 * describe a user key
466 * - the key must have view permission
467 * - if there's a buffer, we place up to buflen bytes of data into it
468 * - unless there's an error, we return the amount of description available,
469 * irrespective of how much we may have copied
470 * - the description is formatted thus:
471 * type;uid;gid;perm;description<NUL>
472 * - implements keyctl(KEYCTL_DESCRIBE)
473 */
474long keyctl_describe_key(key_serial_t keyid,
475 char __user *buffer,
476 size_t buflen)
477{
478 struct key *key;
479 char *tmpbuf;
480 long ret;
481
482 key = lookup_user_key(keyid, 0, 1, KEY_VIEW);
483 if (IS_ERR(key)) {
484 ret = PTR_ERR(key);
485 goto error;
486 }
487
488 /* calculate how much description we're going to return */
489 ret = -ENOMEM;
490 tmpbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
491 if (!tmpbuf)
492 goto error2;
493
494 ret = snprintf(tmpbuf, PAGE_SIZE - 1,
495 "%s;%d;%d;%06x;%s",
496 key->type->name,
497 key->uid,
498 key->gid,
499 key->perm,
500 key->description ? key->description :""
501 );
502
503 /* include a NUL char at the end of the data */
504 if (ret > PAGE_SIZE - 1)
505 ret = PAGE_SIZE - 1;
506 tmpbuf[ret] = 0;
507 ret++;
508
509 /* consider returning the data */
510 if (buffer && buflen > 0) {
511 if (buflen > ret)
512 buflen = ret;
513
514 if (copy_to_user(buffer, tmpbuf, buflen) != 0)
515 ret = -EFAULT;
516 }
517
518 kfree(tmpbuf);
519 error2:
520 key_put(key);
521 error:
522 return ret;
523
524} /* end keyctl_describe_key() */
525
526/*****************************************************************************/
527/*
528 * search the specified keyring for a matching key
529 * - the start keyring must be searchable
530 * - nested keyrings may also be searched if they are searchable
531 * - only keys with search permission may be found
532 * - if a key is found, it will be attached to the destination keyring if
533 * there's one specified
534 * - implements keyctl(KEYCTL_SEARCH)
535 */
536long keyctl_keyring_search(key_serial_t ringid,
537 const char __user *_type,
538 const char __user *_description,
539 key_serial_t destringid)
540{
541 struct key_type *ktype;
542 struct key *keyring, *key, *dest;
543 char type[32], *description;
544 long dlen, ret;
545
546 /* pull the type and description into kernel space */
547 ret = strncpy_from_user(type, _type, sizeof(type) - 1);
548 if (ret < 0)
549 goto error;
550 type[31] = '\0';
551
552 ret = -EFAULT;
553 dlen = strnlen_user(_description, PAGE_SIZE - 1);
554 if (dlen <= 0)
555 goto error;
556
557 ret = -EINVAL;
558 if (dlen > PAGE_SIZE - 1)
559 goto error;
560
561 ret = -ENOMEM;
562 description = kmalloc(dlen + 1, GFP_KERNEL);
563 if (!description)
564 goto error;
565
566 ret = -EFAULT;
567 if (copy_from_user(description, _description, dlen + 1) != 0)
568 goto error2;
569
570 /* get the keyring at which to begin the search */
571 keyring = lookup_user_key(ringid, 0, 0, KEY_SEARCH);
572 if (IS_ERR(keyring)) {
573 ret = PTR_ERR(keyring);
574 goto error2;
575 }
576
577 /* get the destination keyring if specified */
578 dest = NULL;
579 if (destringid) {
580 dest = lookup_user_key(destringid, 1, 0, KEY_WRITE);
581 if (IS_ERR(dest)) {
582 ret = PTR_ERR(dest);
583 goto error3;
584 }
585 }
586
587 /* find the key type */
588 ktype = key_type_lookup(type);
589 if (IS_ERR(ktype)) {
590 ret = PTR_ERR(ktype);
591 goto error4;
592 }
593
594 /* do the search */
595 key = keyring_search(keyring, ktype, description);
596 if (IS_ERR(key)) {
597 ret = PTR_ERR(key);
598
599 /* treat lack or presence of a negative key the same */
600 if (ret == -EAGAIN)
601 ret = -ENOKEY;
602 goto error5;
603 }
604
605 /* link the resulting key to the destination keyring if we can */
606 if (dest) {
607 ret = -EACCES;
608 if (!key_permission(key, KEY_LINK))
609 goto error6;
610
611 ret = key_link(dest, key);
612 if (ret < 0)
613 goto error6;
614 }
615
616 ret = key->serial;
617
618 error6:
619 key_put(key);
620 error5:
621 key_type_put(ktype);
622 error4:
623 key_put(dest);
624 error3:
625 key_put(keyring);
626 error2:
627 kfree(description);
628 error:
629 return ret;
630
631} /* end keyctl_keyring_search() */
632
633/*****************************************************************************/
634/*
635 * see if the key we're looking at is the target key
636 */
637static int keyctl_read_key_same(const struct key *key, const void *target)
638{
639 return key == target;
640
641} /* end keyctl_read_key_same() */
642
643/*****************************************************************************/
644/*
645 * read a user key's payload
646 * - the keyring must be readable or the key must be searchable from the
647 * process's keyrings
648 * - if there's a buffer, we place up to buflen bytes of data into it
649 * - unless there's an error, we return the amount of data in the key,
650 * irrespective of how much we may have copied
651 * - implements keyctl(KEYCTL_READ)
652 */
653long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
654{
655 struct key *key, *skey;
656 long ret;
657
658 /* find the key first */
659 key = lookup_user_key(keyid, 0, 0, 0);
660 if (!IS_ERR(key)) {
661 /* see if we can read it directly */
662 if (key_permission(key, KEY_READ))
663 goto can_read_key;
664
665 /* can't; see if it's searchable from this process's
666 * keyrings */
667 ret = -ENOKEY;
668 if (key_permission(key, KEY_SEARCH)) {
669 /* okay - we do have search permission on the key
670 * itself, but do we have the key? */
671 skey = search_process_keyrings_aux(key->type, key,
672 keyctl_read_key_same);
673 if (!IS_ERR(skey))
674 goto can_read_key2;
675 }
676
677 goto error2;
678 }
679
680 ret = -ENOKEY;
681 goto error;
682
683 /* the key is probably readable - now try to read it */
684 can_read_key2:
685 key_put(skey);
686 can_read_key:
687 ret = key_validate(key);
688 if (ret == 0) {
689 ret = -EOPNOTSUPP;
690 if (key->type->read) {
691 /* read the data with the semaphore held (since we
692 * might sleep) */
693 down_read(&key->sem);
694 ret = key->type->read(key, buffer, buflen);
695 up_read(&key->sem);
696 }
697 }
698
699 error2:
700 key_put(key);
701 error:
702 return ret;
703
704} /* end keyctl_read_key() */
705
706/*****************************************************************************/
707/*
708 * change the ownership of a key
709 * - the keyring owned by the changer
710 * - if the uid or gid is -1, then that parameter is not changed
711 * - implements keyctl(KEYCTL_CHOWN)
712 */
713long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
714{
715 struct key *key;
716 long ret;
717
718 ret = 0;
719 if (uid == (uid_t) -1 && gid == (gid_t) -1)
720 goto error;
721
722 key = lookup_user_key(id, 1, 1, 0);
723 if (IS_ERR(key)) {
724 ret = PTR_ERR(key);
725 goto error;
726 }
727
728 /* make the changes with the locks held to prevent chown/chown races */
729 ret = -EACCES;
730 down_write(&key->sem);
731 write_lock(&key->lock);
732
733 if (!capable(CAP_SYS_ADMIN)) {
734 /* only the sysadmin can chown a key to some other UID */
735 if (uid != (uid_t) -1 && key->uid != uid)
736 goto no_access;
737
738 /* only the sysadmin can set the key's GID to a group other
739 * than one of those that the current process subscribes to */
740 if (gid != (gid_t) -1 && gid != key->gid && !in_group_p(gid))
741 goto no_access;
742 }
743
744 /* change the UID (have to update the quotas) */
745 if (uid != (uid_t) -1 && uid != key->uid) {
746 /* don't support UID changing yet */
747 ret = -EOPNOTSUPP;
748 goto no_access;
749 }
750
751 /* change the GID */
752 if (gid != (gid_t) -1)
753 key->gid = gid;
754
755 ret = 0;
756
757 no_access:
758 write_unlock(&key->lock);
759 up_write(&key->sem);
760 key_put(key);
761 error:
762 return ret;
763
764} /* end keyctl_chown_key() */
765
766/*****************************************************************************/
767/*
768 * change the permission mask on a key
769 * - the keyring owned by the changer
770 * - implements keyctl(KEYCTL_SETPERM)
771 */
772long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
773{
774 struct key *key;
775 long ret;
776
777 ret = -EINVAL;
778 if (perm & ~(KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
779 goto error;
780
781 key = lookup_user_key(id, 1, 1, 0);
782 if (IS_ERR(key)) {
783 ret = PTR_ERR(key);
784 goto error;
785 }
786
787 /* make the changes with the locks held to prevent chown/chmod
788 * races */
789 ret = -EACCES;
790 down_write(&key->sem);
791 write_lock(&key->lock);
792
793 /* if we're not the sysadmin, we can only chmod a key that we
794 * own */
795 if (!capable(CAP_SYS_ADMIN) && key->uid != current->fsuid)
796 goto no_access;
797
798 /* changing the permissions mask */
799 key->perm = perm;
800 ret = 0;
801
802 no_access:
803 write_unlock(&key->lock);
804 up_write(&key->sem);
805 key_put(key);
806 error:
807 return ret;
808
809} /* end keyctl_setperm_key() */
810
811/*****************************************************************************/
812/*
813 * instantiate the key with the specified payload, and, if one is given, link
814 * the key into the keyring
815 */
816long keyctl_instantiate_key(key_serial_t id,
817 const void __user *_payload,
818 size_t plen,
819 key_serial_t ringid)
820{
821 struct key *key, *keyring;
822 void *payload;
823 long ret;
824
825 ret = -EINVAL;
826 if (plen > 32767)
827 goto error;
828
829 /* pull the payload in if one was supplied */
830 payload = NULL;
831
832 if (_payload) {
833 ret = -ENOMEM;
834 payload = kmalloc(plen, GFP_KERNEL);
835 if (!payload)
836 goto error;
837
838 ret = -EFAULT;
839 if (copy_from_user(payload, _payload, plen) != 0)
840 goto error2;
841 }
842
843 /* find the target key (which must be writable) */
844 key = lookup_user_key(id, 0, 1, KEY_WRITE);
845 if (IS_ERR(key)) {
846 ret = PTR_ERR(key);
847 goto error2;
848 }
849
850 /* find the destination keyring if present (which must also be
851 * writable) */
852 keyring = NULL;
853 if (ringid) {
854 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
855 if (IS_ERR(keyring)) {
856 ret = PTR_ERR(keyring);
857 goto error3;
858 }
859 }
860
861 /* instantiate the key and link it into a keyring */
862 ret = key_instantiate_and_link(key, payload, plen, keyring);
863
864 key_put(keyring);
865 error3:
866 key_put(key);
867 error2:
868 kfree(payload);
869 error:
870 return ret;
871
872} /* end keyctl_instantiate_key() */
873
874/*****************************************************************************/
875/*
876 * negatively instantiate the key with the given timeout (in seconds), and, if
877 * one is given, link the key into the keyring
878 */
879long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
880{
881 struct key *key, *keyring;
882 long ret;
883
884 /* find the target key (which must be writable) */
885 key = lookup_user_key(id, 0, 1, KEY_WRITE);
886 if (IS_ERR(key)) {
887 ret = PTR_ERR(key);
888 goto error;
889 }
890
891 /* find the destination keyring if present (which must also be
892 * writable) */
893 keyring = NULL;
894 if (ringid) {
895 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
896 if (IS_ERR(keyring)) {
897 ret = PTR_ERR(keyring);
898 goto error2;
899 }
900 }
901
902 /* instantiate the key and link it into a keyring */
903 ret = key_negate_and_link(key, timeout, keyring);
904
905 key_put(keyring);
906 error2:
907 key_put(key);
908 error:
909 return ret;
910
911} /* end keyctl_negate_key() */
912
913/*****************************************************************************/
914/*
915 * the key control system call
916 */
917asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
918 unsigned long arg4, unsigned long arg5)
919{
920 switch (option) {
921 case KEYCTL_GET_KEYRING_ID:
922 return keyctl_get_keyring_ID((key_serial_t) arg2,
923 (int) arg3);
924
925 case KEYCTL_JOIN_SESSION_KEYRING:
926 return keyctl_join_session_keyring((const char __user *) arg2);
927
928 case KEYCTL_UPDATE:
929 return keyctl_update_key((key_serial_t) arg2,
930 (const void __user *) arg3,
931 (size_t) arg4);
932
933 case KEYCTL_REVOKE:
934 return keyctl_revoke_key((key_serial_t) arg2);
935
936 case KEYCTL_DESCRIBE:
937 return keyctl_describe_key((key_serial_t) arg2,
938 (char __user *) arg3,
939 (unsigned) arg4);
940
941 case KEYCTL_CLEAR:
942 return keyctl_keyring_clear((key_serial_t) arg2);
943
944 case KEYCTL_LINK:
945 return keyctl_keyring_link((key_serial_t) arg2,
946 (key_serial_t) arg3);
947
948 case KEYCTL_UNLINK:
949 return keyctl_keyring_unlink((key_serial_t) arg2,
950 (key_serial_t) arg3);
951
952 case KEYCTL_SEARCH:
953 return keyctl_keyring_search((key_serial_t) arg2,
954 (const char __user *) arg3,
955 (const char __user *) arg4,
956 (key_serial_t) arg5);
957
958 case KEYCTL_READ:
959 return keyctl_read_key((key_serial_t) arg2,
960 (char __user *) arg3,
961 (size_t) arg4);
962
963 case KEYCTL_CHOWN:
964 return keyctl_chown_key((key_serial_t) arg2,
965 (uid_t) arg3,
966 (gid_t) arg4);
967
968 case KEYCTL_SETPERM:
969 return keyctl_setperm_key((key_serial_t) arg2,
970 (key_perm_t) arg3);
971
972 case KEYCTL_INSTANTIATE:
973 return keyctl_instantiate_key((key_serial_t) arg2,
974 (const void __user *) arg3,
975 (size_t) arg4,
976 (key_serial_t) arg5);
977
978 case KEYCTL_NEGATE:
979 return keyctl_negate_key((key_serial_t) arg2,
980 (unsigned) arg3,
981 (key_serial_t) arg4);
982
983 default:
984 return -EOPNOTSUPP;
985 }
986
987} /* end sys_keyctl() */
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
new file mode 100644
index 000000000000..e2ab4f8e7481
--- /dev/null
+++ b/security/keys/keyring.c
@@ -0,0 +1,895 @@
1/* keyring.c: keyring handling
2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/sched.h>
15#include <linux/slab.h>
16#include <linux/seq_file.h>
17#include <linux/err.h>
18#include <asm/uaccess.h>
19#include "internal.h"
20
21/*
22 * when plumbing the depths of the key tree, this sets a hard limit set on how
23 * deep we're willing to go
24 */
25#define KEYRING_SEARCH_MAX_DEPTH 6
26
27/*
28 * we keep all named keyrings in a hash to speed looking them up
29 */
30#define KEYRING_NAME_HASH_SIZE (1 << 5)
31
32static struct list_head keyring_name_hash[KEYRING_NAME_HASH_SIZE];
33static DEFINE_RWLOCK(keyring_name_lock);
34
35static inline unsigned keyring_hash(const char *desc)
36{
37 unsigned bucket = 0;
38
39 for (; *desc; desc++)
40 bucket += (unsigned char) *desc;
41
42 return bucket & (KEYRING_NAME_HASH_SIZE - 1);
43}
44
45/*
46 * the keyring type definition
47 */
48static int keyring_instantiate(struct key *keyring,
49 const void *data, size_t datalen);
50static int keyring_duplicate(struct key *keyring, const struct key *source);
51static int keyring_match(const struct key *keyring, const void *criterion);
52static void keyring_destroy(struct key *keyring);
53static void keyring_describe(const struct key *keyring, struct seq_file *m);
54static long keyring_read(const struct key *keyring,
55 char __user *buffer, size_t buflen);
56
57struct key_type key_type_keyring = {
58 .name = "keyring",
59 .def_datalen = sizeof(struct keyring_list),
60 .instantiate = keyring_instantiate,
61 .duplicate = keyring_duplicate,
62 .match = keyring_match,
63 .destroy = keyring_destroy,
64 .describe = keyring_describe,
65 .read = keyring_read,
66};
67
68/*
69 * semaphore to serialise link/link calls to prevent two link calls in parallel
70 * introducing a cycle
71 */
72DECLARE_RWSEM(keyring_serialise_link_sem);
73
74/*****************************************************************************/
75/*
76 * publish the name of a keyring so that it can be found by name (if it has
77 * one)
78 */
79void keyring_publish_name(struct key *keyring)
80{
81 int bucket;
82
83 if (keyring->description) {
84 bucket = keyring_hash(keyring->description);
85
86 write_lock(&keyring_name_lock);
87
88 if (!keyring_name_hash[bucket].next)
89 INIT_LIST_HEAD(&keyring_name_hash[bucket]);
90
91 list_add_tail(&keyring->type_data.link,
92 &keyring_name_hash[bucket]);
93
94 write_unlock(&keyring_name_lock);
95 }
96
97} /* end keyring_publish_name() */
98
99/*****************************************************************************/
100/*
101 * initialise a keyring
102 * - we object if we were given any data
103 */
104static int keyring_instantiate(struct key *keyring,
105 const void *data, size_t datalen)
106{
107 int ret;
108
109 ret = -EINVAL;
110 if (datalen == 0) {
111 /* make the keyring available by name if it has one */
112 keyring_publish_name(keyring);
113 ret = 0;
114 }
115
116 return ret;
117
118} /* end keyring_instantiate() */
119
120/*****************************************************************************/
121/*
122 * duplicate the list of subscribed keys from a source keyring into this one
123 */
124static int keyring_duplicate(struct key *keyring, const struct key *source)
125{
126 struct keyring_list *sklist, *klist;
127 unsigned max;
128 size_t size;
129 int loop, ret;
130
131 const unsigned limit =
132 (PAGE_SIZE - sizeof(*klist)) / sizeof(struct key);
133
134 ret = 0;
135 sklist = source->payload.subscriptions;
136
137 if (sklist && sklist->nkeys > 0) {
138 max = sklist->nkeys;
139 BUG_ON(max > limit);
140
141 max = (max + 3) & ~3;
142 if (max > limit)
143 max = limit;
144
145 ret = -ENOMEM;
146 size = sizeof(*klist) + sizeof(struct key) * max;
147 klist = kmalloc(size, GFP_KERNEL);
148 if (!klist)
149 goto error;
150
151 klist->maxkeys = max;
152 klist->nkeys = sklist->nkeys;
153 memcpy(klist->keys,
154 sklist->keys,
155 sklist->nkeys * sizeof(struct key));
156
157 for (loop = klist->nkeys - 1; loop >= 0; loop--)
158 atomic_inc(&klist->keys[loop]->usage);
159
160 keyring->payload.subscriptions = klist;
161 ret = 0;
162 }
163
164 error:
165 return ret;
166
167} /* end keyring_duplicate() */
168
169/*****************************************************************************/
170/*
171 * match keyrings on their name
172 */
173static int keyring_match(const struct key *keyring, const void *description)
174{
175 return keyring->description &&
176 strcmp(keyring->description, description) == 0;
177
178} /* end keyring_match() */
179
180/*****************************************************************************/
181/*
182 * dispose of the data dangling from the corpse of a keyring
183 */
184static void keyring_destroy(struct key *keyring)
185{
186 struct keyring_list *klist;
187 int loop;
188
189 if (keyring->description) {
190 write_lock(&keyring_name_lock);
191 list_del(&keyring->type_data.link);
192 write_unlock(&keyring_name_lock);
193 }
194
195 klist = keyring->payload.subscriptions;
196 if (klist) {
197 for (loop = klist->nkeys - 1; loop >= 0; loop--)
198 key_put(klist->keys[loop]);
199 kfree(klist);
200 }
201
202} /* end keyring_destroy() */
203
204/*****************************************************************************/
205/*
206 * describe the keyring
207 */
208static void keyring_describe(const struct key *keyring, struct seq_file *m)
209{
210 struct keyring_list *klist;
211
212 if (keyring->description) {
213 seq_puts(m, keyring->description);
214 }
215 else {
216 seq_puts(m, "[anon]");
217 }
218
219 klist = keyring->payload.subscriptions;
220 if (klist)
221 seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys);
222 else
223 seq_puts(m, ": empty");
224
225} /* end keyring_describe() */
226
227/*****************************************************************************/
228/*
229 * read a list of key IDs from the keyring's contents
230 */
231static long keyring_read(const struct key *keyring,
232 char __user *buffer, size_t buflen)
233{
234 struct keyring_list *klist;
235 struct key *key;
236 size_t qty, tmp;
237 int loop, ret;
238
239 ret = 0;
240 klist = keyring->payload.subscriptions;
241
242 if (klist) {
243 /* calculate how much data we could return */
244 qty = klist->nkeys * sizeof(key_serial_t);
245
246 if (buffer && buflen > 0) {
247 if (buflen > qty)
248 buflen = qty;
249
250 /* copy the IDs of the subscribed keys into the
251 * buffer */
252 ret = -EFAULT;
253
254 for (loop = 0; loop < klist->nkeys; loop++) {
255 key = klist->keys[loop];
256
257 tmp = sizeof(key_serial_t);
258 if (tmp > buflen)
259 tmp = buflen;
260
261 if (copy_to_user(buffer,
262 &key->serial,
263 tmp) != 0)
264 goto error;
265
266 buflen -= tmp;
267 if (buflen == 0)
268 break;
269 buffer += tmp;
270 }
271 }
272
273 ret = qty;
274 }
275
276 error:
277 return ret;
278
279} /* end keyring_read() */
280
281/*****************************************************************************/
282/*
283 * allocate a keyring and link into the destination keyring
284 */
285struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
286 int not_in_quota, struct key *dest)
287{
288 struct key *keyring;
289 int ret;
290
291 keyring = key_alloc(&key_type_keyring, description,
292 uid, gid, KEY_USR_ALL, not_in_quota);
293
294 if (!IS_ERR(keyring)) {
295 ret = key_instantiate_and_link(keyring, NULL, 0, dest);
296 if (ret < 0) {
297 key_put(keyring);
298 keyring = ERR_PTR(ret);
299 }
300 }
301
302 return keyring;
303
304} /* end keyring_alloc() */
305
306/*****************************************************************************/
307/*
308 * search the supplied keyring tree for a key that matches the criterion
309 * - perform a breadth-then-depth search up to the prescribed limit
310 * - we only find keys on which we have search permission
311 * - we use the supplied match function to see if the description (or other
312 * feature of interest) matches
313 * - we readlock the keyrings as we search down the tree
314 * - we return -EAGAIN if we didn't find any matching key
315 * - we return -ENOKEY if we only found negative matching keys
316 */
317struct key *keyring_search_aux(struct key *keyring,
318 struct key_type *type,
319 const void *description,
320 key_match_func_t match)
321{
322 struct {
323 struct key *keyring;
324 int kix;
325 } stack[KEYRING_SEARCH_MAX_DEPTH];
326
327 struct keyring_list *keylist;
328 struct timespec now;
329 struct key *key;
330 long err;
331 int sp, psp, kix;
332
333 key_check(keyring);
334
335 /* top keyring must have search permission to begin the search */
336 key = ERR_PTR(-EACCES);
337 if (!key_permission(keyring, KEY_SEARCH))
338 goto error;
339
340 key = ERR_PTR(-ENOTDIR);
341 if (keyring->type != &key_type_keyring)
342 goto error;
343
344 now = current_kernel_time();
345 err = -EAGAIN;
346 sp = 0;
347
348 /* start processing a new keyring */
349 descend:
350 read_lock(&keyring->lock);
351 if (keyring->flags & KEY_FLAG_REVOKED)
352 goto not_this_keyring;
353
354 keylist = keyring->payload.subscriptions;
355 if (!keylist)
356 goto not_this_keyring;
357
358 /* iterate through the keys in this keyring first */
359 for (kix = 0; kix < keylist->nkeys; kix++) {
360 key = keylist->keys[kix];
361
362 /* ignore keys not of this type */
363 if (key->type != type)
364 continue;
365
366 /* skip revoked keys and expired keys */
367 if (key->flags & KEY_FLAG_REVOKED)
368 continue;
369
370 if (key->expiry && now.tv_sec >= key->expiry)
371 continue;
372
373 /* keys that don't match */
374 if (!match(key, description))
375 continue;
376
377 /* key must have search permissions */
378 if (!key_permission(key, KEY_SEARCH))
379 continue;
380
381 /* we set a different error code if we find a negative key */
382 if (key->flags & KEY_FLAG_NEGATIVE) {
383 err = -ENOKEY;
384 continue;
385 }
386
387 goto found;
388 }
389
390 /* search through the keyrings nested in this one */
391 kix = 0;
392 ascend:
393 while (kix < keylist->nkeys) {
394 key = keylist->keys[kix];
395 if (key->type != &key_type_keyring)
396 goto next;
397
398 /* recursively search nested keyrings
399 * - only search keyrings for which we have search permission
400 */
401 if (sp >= KEYRING_SEARCH_MAX_DEPTH)
402 goto next;
403
404 if (!key_permission(key, KEY_SEARCH))
405 goto next;
406
407 /* evade loops in the keyring tree */
408 for (psp = 0; psp < sp; psp++)
409 if (stack[psp].keyring == keyring)
410 goto next;
411
412 /* stack the current position */
413 stack[sp].keyring = keyring;
414 stack[sp].kix = kix;
415 sp++;
416
417 /* begin again with the new keyring */
418 keyring = key;
419 goto descend;
420
421 next:
422 kix++;
423 }
424
425 /* the keyring we're looking at was disqualified or didn't contain a
426 * matching key */
427 not_this_keyring:
428 read_unlock(&keyring->lock);
429
430 if (sp > 0) {
431 /* resume the processing of a keyring higher up in the tree */
432 sp--;
433 keyring = stack[sp].keyring;
434 keylist = keyring->payload.subscriptions;
435 kix = stack[sp].kix + 1;
436 goto ascend;
437 }
438
439 key = ERR_PTR(err);
440 goto error;
441
442 /* we found a viable match */
443 found:
444 atomic_inc(&key->usage);
445 read_unlock(&keyring->lock);
446
447 /* unwind the keyring stack */
448 while (sp > 0) {
449 sp--;
450 read_unlock(&stack[sp].keyring->lock);
451 }
452
453 key_check(key);
454 error:
455 return key;
456
457} /* end keyring_search_aux() */
458
459/*****************************************************************************/
460/*
461 * search the supplied keyring tree for a key that matches the criterion
462 * - perform a breadth-then-depth search up to the prescribed limit
463 * - we only find keys on which we have search permission
464 * - we readlock the keyrings as we search down the tree
465 * - we return -EAGAIN if we didn't find any matching key
466 * - we return -ENOKEY if we only found negative matching keys
467 */
468struct key *keyring_search(struct key *keyring,
469 struct key_type *type,
470 const char *description)
471{
472 return keyring_search_aux(keyring, type, description, type->match);
473
474} /* end keyring_search() */
475
476EXPORT_SYMBOL(keyring_search);
477
478/*****************************************************************************/
479/*
480 * search the given keyring only (no recursion)
481 * - keyring must be locked by caller
482 */
483struct key *__keyring_search_one(struct key *keyring,
484 const struct key_type *ktype,
485 const char *description,
486 key_perm_t perm)
487{
488 struct keyring_list *klist;
489 struct key *key;
490 int loop;
491
492 klist = keyring->payload.subscriptions;
493 if (klist) {
494 for (loop = 0; loop < klist->nkeys; loop++) {
495 key = klist->keys[loop];
496
497 if (key->type == ktype &&
498 key->type->match(key, description) &&
499 key_permission(key, perm) &&
500 !(key->flags & KEY_FLAG_REVOKED)
501 )
502 goto found;
503 }
504 }
505
506 key = ERR_PTR(-ENOKEY);
507 goto error;
508
509 found:
510 atomic_inc(&key->usage);
511 error:
512 return key;
513
514} /* end __keyring_search_one() */
515
516/*****************************************************************************/
517/*
518 * find a keyring with the specified name
519 * - all named keyrings are searched
520 * - only find keyrings with search permission for the process
521 * - only find keyrings with a serial number greater than the one specified
522 */
523struct key *find_keyring_by_name(const char *name, key_serial_t bound)
524{
525 struct key *keyring;
526 int bucket;
527
528 keyring = ERR_PTR(-EINVAL);
529 if (!name)
530 goto error;
531
532 bucket = keyring_hash(name);
533
534 read_lock(&keyring_name_lock);
535
536 if (keyring_name_hash[bucket].next) {
537 /* search this hash bucket for a keyring with a matching name
538 * that's readable and that hasn't been revoked */
539 list_for_each_entry(keyring,
540 &keyring_name_hash[bucket],
541 type_data.link
542 ) {
543 if (keyring->flags & KEY_FLAG_REVOKED)
544 continue;
545
546 if (strcmp(keyring->description, name) != 0)
547 continue;
548
549 if (!key_permission(keyring, KEY_SEARCH))
550 continue;
551
552 /* found a potential candidate, but we still need to
553 * check the serial number */
554 if (keyring->serial <= bound)
555 continue;
556
557 /* we've got a match */
558 atomic_inc(&keyring->usage);
559 read_unlock(&keyring_name_lock);
560 goto error;
561 }
562 }
563
564 read_unlock(&keyring_name_lock);
565 keyring = ERR_PTR(-ENOKEY);
566
567 error:
568 return keyring;
569
570} /* end find_keyring_by_name() */
571
572/*****************************************************************************/
573/*
574 * see if a cycle will will be created by inserting acyclic tree B in acyclic
575 * tree A at the topmost level (ie: as a direct child of A)
576 * - since we are adding B to A at the top level, checking for cycles should
577 * just be a matter of seeing if node A is somewhere in tree B
578 */
579static int keyring_detect_cycle(struct key *A, struct key *B)
580{
581 struct {
582 struct key *subtree;
583 int kix;
584 } stack[KEYRING_SEARCH_MAX_DEPTH];
585
586 struct keyring_list *keylist;
587 struct key *subtree, *key;
588 int sp, kix, ret;
589
590 ret = -EDEADLK;
591 if (A == B)
592 goto error;
593
594 subtree = B;
595 sp = 0;
596
597 /* start processing a new keyring */
598 descend:
599 read_lock(&subtree->lock);
600 if (subtree->flags & KEY_FLAG_REVOKED)
601 goto not_this_keyring;
602
603 keylist = subtree->payload.subscriptions;
604 if (!keylist)
605 goto not_this_keyring;
606 kix = 0;
607
608 ascend:
609 /* iterate through the remaining keys in this keyring */
610 for (; kix < keylist->nkeys; kix++) {
611 key = keylist->keys[kix];
612
613 if (key == A)
614 goto cycle_detected;
615
616 /* recursively check nested keyrings */
617 if (key->type == &key_type_keyring) {
618 if (sp >= KEYRING_SEARCH_MAX_DEPTH)
619 goto too_deep;
620
621 /* stack the current position */
622 stack[sp].subtree = subtree;
623 stack[sp].kix = kix;
624 sp++;
625
626 /* begin again with the new keyring */
627 subtree = key;
628 goto descend;
629 }
630 }
631
632 /* the keyring we're looking at was disqualified or didn't contain a
633 * matching key */
634 not_this_keyring:
635 read_unlock(&subtree->lock);
636
637 if (sp > 0) {
638 /* resume the checking of a keyring higher up in the tree */
639 sp--;
640 subtree = stack[sp].subtree;
641 keylist = subtree->payload.subscriptions;
642 kix = stack[sp].kix + 1;
643 goto ascend;
644 }
645
646 ret = 0; /* no cycles detected */
647
648 error:
649 return ret;
650
651 too_deep:
652 ret = -ELOOP;
653 goto error_unwind;
654 cycle_detected:
655 ret = -EDEADLK;
656 error_unwind:
657 read_unlock(&subtree->lock);
658
659 /* unwind the keyring stack */
660 while (sp > 0) {
661 sp--;
662 read_unlock(&stack[sp].subtree->lock);
663 }
664
665 goto error;
666
667} /* end keyring_detect_cycle() */
668
669/*****************************************************************************/
670/*
671 * link a key into to a keyring
672 * - must be called with the keyring's semaphore held
673 */
674int __key_link(struct key *keyring, struct key *key)
675{
676 struct keyring_list *klist, *nklist;
677 unsigned max;
678 size_t size;
679 int ret;
680
681 ret = -EKEYREVOKED;
682 if (keyring->flags & KEY_FLAG_REVOKED)
683 goto error;
684
685 ret = -ENOTDIR;
686 if (keyring->type != &key_type_keyring)
687 goto error;
688
689 /* serialise link/link calls to prevent parallel calls causing a
690 * cycle when applied to two keyring in opposite orders */
691 down_write(&keyring_serialise_link_sem);
692
693 /* check that we aren't going to create a cycle adding one keyring to
694 * another */
695 if (key->type == &key_type_keyring) {
696 ret = keyring_detect_cycle(keyring, key);
697 if (ret < 0)
698 goto error2;
699 }
700
701 /* check that we aren't going to overrun the user's quota */
702 ret = key_payload_reserve(keyring,
703 keyring->datalen + KEYQUOTA_LINK_BYTES);
704 if (ret < 0)
705 goto error2;
706
707 klist = keyring->payload.subscriptions;
708
709 if (klist && klist->nkeys < klist->maxkeys) {
710 /* there's sufficient slack space to add directly */
711 atomic_inc(&key->usage);
712
713 write_lock(&keyring->lock);
714 klist->keys[klist->nkeys++] = key;
715 write_unlock(&keyring->lock);
716
717 ret = 0;
718 }
719 else {
720 /* grow the key list */
721 max = 4;
722 if (klist)
723 max += klist->maxkeys;
724
725 ret = -ENFILE;
726 size = sizeof(*klist) + sizeof(*key) * max;
727 if (size > PAGE_SIZE)
728 goto error3;
729
730 ret = -ENOMEM;
731 nklist = kmalloc(size, GFP_KERNEL);
732 if (!nklist)
733 goto error3;
734 nklist->maxkeys = max;
735 nklist->nkeys = 0;
736
737 if (klist) {
738 nklist->nkeys = klist->nkeys;
739 memcpy(nklist->keys,
740 klist->keys,
741 sizeof(struct key *) * klist->nkeys);
742 }
743
744 /* add the key into the new space */
745 atomic_inc(&key->usage);
746
747 write_lock(&keyring->lock);
748 keyring->payload.subscriptions = nklist;
749 nklist->keys[nklist->nkeys++] = key;
750 write_unlock(&keyring->lock);
751
752 /* dispose of the old keyring list */
753 kfree(klist);
754
755 ret = 0;
756 }
757
758 error2:
759 up_write(&keyring_serialise_link_sem);
760 error:
761 return ret;
762
763 error3:
764 /* undo the quota changes */
765 key_payload_reserve(keyring,
766 keyring->datalen - KEYQUOTA_LINK_BYTES);
767 goto error2;
768
769} /* end __key_link() */
770
771/*****************************************************************************/
772/*
773 * link a key to a keyring
774 */
775int key_link(struct key *keyring, struct key *key)
776{
777 int ret;
778
779 key_check(keyring);
780 key_check(key);
781
782 down_write(&keyring->sem);
783 ret = __key_link(keyring, key);
784 up_write(&keyring->sem);
785
786 return ret;
787
788} /* end key_link() */
789
790EXPORT_SYMBOL(key_link);
791
792/*****************************************************************************/
793/*
794 * unlink the first link to a key from a keyring
795 */
796int key_unlink(struct key *keyring, struct key *key)
797{
798 struct keyring_list *klist;
799 int loop, ret;
800
801 key_check(keyring);
802 key_check(key);
803
804 ret = -ENOTDIR;
805 if (keyring->type != &key_type_keyring)
806 goto error;
807
808 down_write(&keyring->sem);
809
810 klist = keyring->payload.subscriptions;
811 if (klist) {
812 /* search the keyring for the key */
813 for (loop = 0; loop < klist->nkeys; loop++)
814 if (klist->keys[loop] == key)
815 goto key_is_present;
816 }
817
818 up_write(&keyring->sem);
819 ret = -ENOENT;
820 goto error;
821
822 key_is_present:
823 /* adjust the user's quota */
824 key_payload_reserve(keyring,
825 keyring->datalen - KEYQUOTA_LINK_BYTES);
826
827 /* shuffle down the key pointers
828 * - it might be worth shrinking the allocated memory, but that runs
829 * the risk of ENOMEM as we would have to copy
830 */
831 write_lock(&keyring->lock);
832
833 klist->nkeys--;
834 if (loop < klist->nkeys)
835 memcpy(&klist->keys[loop],
836 &klist->keys[loop + 1],
837 (klist->nkeys - loop) * sizeof(struct key *));
838
839 write_unlock(&keyring->lock);
840
841 up_write(&keyring->sem);
842 key_put(key);
843 ret = 0;
844
845 error:
846 return ret;
847
848} /* end key_unlink() */
849
850EXPORT_SYMBOL(key_unlink);
851
852/*****************************************************************************/
853/*
854 * clear the specified process keyring
855 * - implements keyctl(KEYCTL_CLEAR)
856 */
857int keyring_clear(struct key *keyring)
858{
859 struct keyring_list *klist;
860 int loop, ret;
861
862 ret = -ENOTDIR;
863 if (keyring->type == &key_type_keyring) {
864 /* detach the pointer block with the locks held */
865 down_write(&keyring->sem);
866
867 klist = keyring->payload.subscriptions;
868 if (klist) {
869 /* adjust the quota */
870 key_payload_reserve(keyring,
871 sizeof(struct keyring_list));
872
873 write_lock(&keyring->lock);
874 keyring->payload.subscriptions = NULL;
875 write_unlock(&keyring->lock);
876 }
877
878 up_write(&keyring->sem);
879
880 /* free the keys after the locks have been dropped */
881 if (klist) {
882 for (loop = klist->nkeys - 1; loop >= 0; loop--)
883 key_put(klist->keys[loop]);
884
885 kfree(klist);
886 }
887
888 ret = 0;
889 }
890
891 return ret;
892
893} /* end keyring_clear() */
894
895EXPORT_SYMBOL(keyring_clear);
diff --git a/security/keys/proc.c b/security/keys/proc.c
new file mode 100644
index 000000000000..91343b85c39c
--- /dev/null
+++ b/security/keys/proc.c
@@ -0,0 +1,251 @@
1/* proc.c: proc files for key database enumeration
2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/sched.h>
15#include <linux/slab.h>
16#include <linux/fs.h>
17#include <linux/proc_fs.h>
18#include <linux/seq_file.h>
19#include <asm/errno.h>
20#include "internal.h"
21
22#ifdef CONFIG_KEYS_DEBUG_PROC_KEYS
23static int proc_keys_open(struct inode *inode, struct file *file);
24static void *proc_keys_start(struct seq_file *p, loff_t *_pos);
25static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos);
26static void proc_keys_stop(struct seq_file *p, void *v);
27static int proc_keys_show(struct seq_file *m, void *v);
28
29static struct seq_operations proc_keys_ops = {
30 .start = proc_keys_start,
31 .next = proc_keys_next,
32 .stop = proc_keys_stop,
33 .show = proc_keys_show,
34};
35
36static struct file_operations proc_keys_fops = {
37 .open = proc_keys_open,
38 .read = seq_read,
39 .llseek = seq_lseek,
40 .release = seq_release,
41};
42#endif
43
44static int proc_key_users_open(struct inode *inode, struct file *file);
45static void *proc_key_users_start(struct seq_file *p, loff_t *_pos);
46static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos);
47static void proc_key_users_stop(struct seq_file *p, void *v);
48static int proc_key_users_show(struct seq_file *m, void *v);
49
50static struct seq_operations proc_key_users_ops = {
51 .start = proc_key_users_start,
52 .next = proc_key_users_next,
53 .stop = proc_key_users_stop,
54 .show = proc_key_users_show,
55};
56
57static struct file_operations proc_key_users_fops = {
58 .open = proc_key_users_open,
59 .read = seq_read,
60 .llseek = seq_lseek,
61 .release = seq_release,
62};
63
64/*****************************************************************************/
65/*
66 * declare the /proc files
67 */
68static int __init key_proc_init(void)
69{
70 struct proc_dir_entry *p;
71
72#ifdef CONFIG_KEYS_DEBUG_PROC_KEYS
73 p = create_proc_entry("keys", 0, NULL);
74 if (!p)
75 panic("Cannot create /proc/keys\n");
76
77 p->proc_fops = &proc_keys_fops;
78#endif
79
80 p = create_proc_entry("key-users", 0, NULL);
81 if (!p)
82 panic("Cannot create /proc/key-users\n");
83
84 p->proc_fops = &proc_key_users_fops;
85
86 return 0;
87
88} /* end key_proc_init() */
89
90__initcall(key_proc_init);
91
92/*****************************************************************************/
93/*
94 * implement "/proc/keys" to provides a list of the keys on the system
95 */
96#ifdef CONFIG_KEYS_DEBUG_PROC_KEYS
97
98static int proc_keys_open(struct inode *inode, struct file *file)
99{
100 return seq_open(file, &proc_keys_ops);
101
102}
103
104static void *proc_keys_start(struct seq_file *p, loff_t *_pos)
105{
106 struct rb_node *_p;
107 loff_t pos = *_pos;
108
109 spin_lock(&key_serial_lock);
110
111 _p = rb_first(&key_serial_tree);
112 while (pos > 0 && _p) {
113 pos--;
114 _p = rb_next(_p);
115 }
116
117 return _p;
118
119}
120
121static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos)
122{
123 (*_pos)++;
124 return rb_next((struct rb_node *) v);
125
126}
127
128static void proc_keys_stop(struct seq_file *p, void *v)
129{
130 spin_unlock(&key_serial_lock);
131}
132
133static int proc_keys_show(struct seq_file *m, void *v)
134{
135 struct rb_node *_p = v;
136 struct key *key = rb_entry(_p, struct key, serial_node);
137 struct timespec now;
138 unsigned long timo;
139 char xbuf[12];
140
141 now = current_kernel_time();
142
143 read_lock(&key->lock);
144
145 /* come up with a suitable timeout value */
146 if (key->expiry == 0) {
147 memcpy(xbuf, "perm", 5);
148 }
149 else if (now.tv_sec >= key->expiry) {
150 memcpy(xbuf, "expd", 5);
151 }
152 else {
153 timo = key->expiry - now.tv_sec;
154
155 if (timo < 60)
156 sprintf(xbuf, "%lus", timo);
157 else if (timo < 60*60)
158 sprintf(xbuf, "%lum", timo / 60);
159 else if (timo < 60*60*24)
160 sprintf(xbuf, "%luh", timo / (60*60));
161 else if (timo < 60*60*24*7)
162 sprintf(xbuf, "%lud", timo / (60*60*24));
163 else
164 sprintf(xbuf, "%luw", timo / (60*60*24*7));
165 }
166
167 seq_printf(m, "%08x %c%c%c%c%c%c %5d %4s %06x %5d %5d %-9.9s ",
168 key->serial,
169 key->flags & KEY_FLAG_INSTANTIATED ? 'I' : '-',
170 key->flags & KEY_FLAG_REVOKED ? 'R' : '-',
171 key->flags & KEY_FLAG_DEAD ? 'D' : '-',
172 key->flags & KEY_FLAG_IN_QUOTA ? 'Q' : '-',
173 key->flags & KEY_FLAG_USER_CONSTRUCT ? 'U' : '-',
174 key->flags & KEY_FLAG_NEGATIVE ? 'N' : '-',
175 atomic_read(&key->usage),
176 xbuf,
177 key->perm,
178 key->uid,
179 key->gid,
180 key->type->name);
181
182 if (key->type->describe)
183 key->type->describe(key, m);
184 seq_putc(m, '\n');
185
186 read_unlock(&key->lock);
187
188 return 0;
189
190}
191
192#endif /* CONFIG_KEYS_DEBUG_PROC_KEYS */
193
194/*****************************************************************************/
195/*
196 * implement "/proc/key-users" to provides a list of the key users
197 */
198static int proc_key_users_open(struct inode *inode, struct file *file)
199{
200 return seq_open(file, &proc_key_users_ops);
201
202}
203
204static void *proc_key_users_start(struct seq_file *p, loff_t *_pos)
205{
206 struct rb_node *_p;
207 loff_t pos = *_pos;
208
209 spin_lock(&key_user_lock);
210
211 _p = rb_first(&key_user_tree);
212 while (pos > 0 && _p) {
213 pos--;
214 _p = rb_next(_p);
215 }
216
217 return _p;
218
219}
220
221static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos)
222{
223 (*_pos)++;
224 return rb_next((struct rb_node *) v);
225
226}
227
228static void proc_key_users_stop(struct seq_file *p, void *v)
229{
230 spin_unlock(&key_user_lock);
231}
232
233static int proc_key_users_show(struct seq_file *m, void *v)
234{
235 struct rb_node *_p = v;
236 struct key_user *user = rb_entry(_p, struct key_user, node);
237
238 seq_printf(m, "%5u: %5d %d/%d %d/%d %d/%d\n",
239 user->uid,
240 atomic_read(&user->usage),
241 atomic_read(&user->nkeys),
242 atomic_read(&user->nikeys),
243 user->qnkeys,
244 KEYQUOTA_MAX_KEYS,
245 user->qnbytes,
246 KEYQUOTA_MAX_BYTES
247 );
248
249 return 0;
250
251}
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
new file mode 100644
index 000000000000..2eb0e471cd40
--- /dev/null
+++ b/security/keys/process_keys.c
@@ -0,0 +1,665 @@
1/* process_keys.c: management of a process's keyrings
2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/sched.h>
15#include <linux/slab.h>
16#include <linux/keyctl.h>
17#include <linux/fs.h>
18#include <linux/err.h>
19#include <asm/uaccess.h>
20#include "internal.h"
21
22/* session keyring create vs join semaphore */
23static DECLARE_MUTEX(key_session_sem);
24
25/* the root user's tracking struct */
26struct key_user root_key_user = {
27 .usage = ATOMIC_INIT(3),
28 .consq = LIST_HEAD_INIT(root_key_user.consq),
29 .lock = SPIN_LOCK_UNLOCKED,
30 .nkeys = ATOMIC_INIT(2),
31 .nikeys = ATOMIC_INIT(2),
32 .uid = 0,
33};
34
35/* the root user's UID keyring */
36struct key root_user_keyring = {
37 .usage = ATOMIC_INIT(1),
38 .serial = 2,
39 .type = &key_type_keyring,
40 .user = &root_key_user,
41 .lock = RW_LOCK_UNLOCKED,
42 .sem = __RWSEM_INITIALIZER(root_user_keyring.sem),
43 .perm = KEY_USR_ALL,
44 .flags = KEY_FLAG_INSTANTIATED,
45 .description = "_uid.0",
46#ifdef KEY_DEBUGGING
47 .magic = KEY_DEBUG_MAGIC,
48#endif
49};
50
51/* the root user's default session keyring */
52struct key root_session_keyring = {
53 .usage = ATOMIC_INIT(1),
54 .serial = 1,
55 .type = &key_type_keyring,
56 .user = &root_key_user,
57 .lock = RW_LOCK_UNLOCKED,
58 .sem = __RWSEM_INITIALIZER(root_session_keyring.sem),
59 .perm = KEY_USR_ALL,
60 .flags = KEY_FLAG_INSTANTIATED,
61 .description = "_uid_ses.0",
62#ifdef KEY_DEBUGGING
63 .magic = KEY_DEBUG_MAGIC,
64#endif
65};
66
67/*****************************************************************************/
68/*
69 * allocate the keyrings to be associated with a UID
70 */
71int alloc_uid_keyring(struct user_struct *user)
72{
73 struct key *uid_keyring, *session_keyring;
74 char buf[20];
75 int ret;
76
77 /* concoct a default session keyring */
78 sprintf(buf, "_uid_ses.%u", user->uid);
79
80 session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0, NULL);
81 if (IS_ERR(session_keyring)) {
82 ret = PTR_ERR(session_keyring);
83 goto error;
84 }
85
86 /* and a UID specific keyring, pointed to by the default session
87 * keyring */
88 sprintf(buf, "_uid.%u", user->uid);
89
90 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0,
91 session_keyring);
92 if (IS_ERR(uid_keyring)) {
93 key_put(session_keyring);
94 ret = PTR_ERR(uid_keyring);
95 goto error;
96 }
97
98 /* install the keyrings */
99 user->uid_keyring = uid_keyring;
100 user->session_keyring = session_keyring;
101 ret = 0;
102
103 error:
104 return ret;
105
106} /* end alloc_uid_keyring() */
107
108/*****************************************************************************/
109/*
110 * deal with the UID changing
111 */
112void switch_uid_keyring(struct user_struct *new_user)
113{
114#if 0 /* do nothing for now */
115 struct key *old;
116
117 /* switch to the new user's session keyring if we were running under
118 * root's default session keyring */
119 if (new_user->uid != 0 &&
120 current->session_keyring == &root_session_keyring
121 ) {
122 atomic_inc(&new_user->session_keyring->usage);
123
124 task_lock(current);
125 old = current->session_keyring;
126 current->session_keyring = new_user->session_keyring;
127 task_unlock(current);
128
129 key_put(old);
130 }
131#endif
132
133} /* end switch_uid_keyring() */
134
135/*****************************************************************************/
136/*
137 * install a fresh thread keyring, discarding the old one
138 */
139int install_thread_keyring(struct task_struct *tsk)
140{
141 struct key *keyring, *old;
142 char buf[20];
143 int ret;
144
145 sprintf(buf, "_tid.%u", tsk->pid);
146
147 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL);
148 if (IS_ERR(keyring)) {
149 ret = PTR_ERR(keyring);
150 goto error;
151 }
152
153 task_lock(tsk);
154 old = tsk->thread_keyring;
155 tsk->thread_keyring = keyring;
156 task_unlock(tsk);
157
158 ret = 0;
159
160 key_put(old);
161 error:
162 return ret;
163
164} /* end install_thread_keyring() */
165
166/*****************************************************************************/
167/*
168 * make sure a process keyring is installed
169 */
170static int install_process_keyring(struct task_struct *tsk)
171{
172 unsigned long flags;
173 struct key *keyring;
174 char buf[20];
175 int ret;
176
177 if (!tsk->signal->process_keyring) {
178 sprintf(buf, "_pid.%u", tsk->tgid);
179
180 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL);
181 if (IS_ERR(keyring)) {
182 ret = PTR_ERR(keyring);
183 goto error;
184 }
185
186 /* attach or swap keyrings */
187 spin_lock_irqsave(&tsk->sighand->siglock, flags);
188 if (!tsk->signal->process_keyring) {
189 tsk->signal->process_keyring = keyring;
190 keyring = NULL;
191 }
192 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
193
194 key_put(keyring);
195 }
196
197 ret = 0;
198 error:
199 return ret;
200
201} /* end install_process_keyring() */
202
203/*****************************************************************************/
204/*
205 * install a session keyring, discarding the old one
206 * - if a keyring is not supplied, an empty one is invented
207 */
208static int install_session_keyring(struct task_struct *tsk,
209 struct key *keyring)
210{
211 unsigned long flags;
212 struct key *old;
213 char buf[20];
214 int ret;
215
216 /* create an empty session keyring */
217 if (!keyring) {
218 sprintf(buf, "_ses.%u", tsk->tgid);
219
220 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL);
221 if (IS_ERR(keyring)) {
222 ret = PTR_ERR(keyring);
223 goto error;
224 }
225 }
226 else {
227 atomic_inc(&keyring->usage);
228 }
229
230 /* install the keyring */
231 spin_lock_irqsave(&tsk->sighand->siglock, flags);
232 old = tsk->signal->session_keyring;
233 tsk->signal->session_keyring = keyring;
234 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
235
236 ret = 0;
237
238 key_put(old);
239 error:
240 return ret;
241
242} /* end install_session_keyring() */
243
244/*****************************************************************************/
245/*
246 * copy the keys in a thread group for fork without CLONE_THREAD
247 */
248int copy_thread_group_keys(struct task_struct *tsk)
249{
250 unsigned long flags;
251
252 key_check(current->thread_group->session_keyring);
253 key_check(current->thread_group->process_keyring);
254
255 /* no process keyring yet */
256 tsk->signal->process_keyring = NULL;
257
258 /* same session keyring */
259 spin_lock_irqsave(&current->sighand->siglock, flags);
260 tsk->signal->session_keyring =
261 key_get(current->signal->session_keyring);
262 spin_unlock_irqrestore(&current->sighand->siglock, flags);
263
264 return 0;
265
266} /* end copy_thread_group_keys() */
267
268/*****************************************************************************/
269/*
270 * copy the keys for fork
271 */
272int copy_keys(unsigned long clone_flags, struct task_struct *tsk)
273{
274 key_check(tsk->thread_keyring);
275
276 /* no thread keyring yet */
277 tsk->thread_keyring = NULL;
278 return 0;
279
280} /* end copy_keys() */
281
282/*****************************************************************************/
283/*
284 * dispose of thread group keys upon thread group destruction
285 */
286void exit_thread_group_keys(struct signal_struct *tg)
287{
288 key_put(tg->session_keyring);
289 key_put(tg->process_keyring);
290
291} /* end exit_thread_group_keys() */
292
293/*****************************************************************************/
294/*
295 * dispose of keys upon thread exit
296 */
297void exit_keys(struct task_struct *tsk)
298{
299 key_put(tsk->thread_keyring);
300
301} /* end exit_keys() */
302
303/*****************************************************************************/
304/*
305 * deal with execve()
306 */
307int exec_keys(struct task_struct *tsk)
308{
309 unsigned long flags;
310 struct key *old;
311
312 /* newly exec'd tasks don't get a thread keyring */
313 task_lock(tsk);
314 old = tsk->thread_keyring;
315 tsk->thread_keyring = NULL;
316 task_unlock(tsk);
317
318 key_put(old);
319
320 /* discard the process keyring from a newly exec'd task */
321 spin_lock_irqsave(&tsk->sighand->siglock, flags);
322 old = tsk->signal->process_keyring;
323 tsk->signal->process_keyring = NULL;
324 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
325
326 key_put(old);
327
328 return 0;
329
330} /* end exec_keys() */
331
332/*****************************************************************************/
333/*
334 * deal with SUID programs
335 * - we might want to make this invent a new session keyring
336 */
337int suid_keys(struct task_struct *tsk)
338{
339 return 0;
340
341} /* end suid_keys() */
342
343/*****************************************************************************/
344/*
345 * the filesystem user ID changed
346 */
347void key_fsuid_changed(struct task_struct *tsk)
348{
349 /* update the ownership of the thread keyring */
350 if (tsk->thread_keyring) {
351 down_write(&tsk->thread_keyring->sem);
352 write_lock(&tsk->thread_keyring->lock);
353 tsk->thread_keyring->uid = tsk->fsuid;
354 write_unlock(&tsk->thread_keyring->lock);
355 up_write(&tsk->thread_keyring->sem);
356 }
357
358} /* end key_fsuid_changed() */
359
360/*****************************************************************************/
361/*
362 * the filesystem group ID changed
363 */
364void key_fsgid_changed(struct task_struct *tsk)
365{
366 /* update the ownership of the thread keyring */
367 if (tsk->thread_keyring) {
368 down_write(&tsk->thread_keyring->sem);
369 write_lock(&tsk->thread_keyring->lock);
370 tsk->thread_keyring->gid = tsk->fsgid;
371 write_unlock(&tsk->thread_keyring->lock);
372 up_write(&tsk->thread_keyring->sem);
373 }
374
375} /* end key_fsgid_changed() */
376
377/*****************************************************************************/
378/*
379 * search the process keyrings for the first matching key
380 * - we use the supplied match function to see if the description (or other
381 * feature of interest) matches
382 * - we return -EAGAIN if we didn't find any matching key
383 * - we return -ENOKEY if we found only negative matching keys
384 */
385struct key *search_process_keyrings_aux(struct key_type *type,
386 const void *description,
387 key_match_func_t match)
388{
389 struct task_struct *tsk = current;
390 unsigned long flags;
391 struct key *key, *ret, *err, *tmp;
392
393 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
394 * searchable, but we failed to find a key or we found a negative key;
395 * otherwise we want to return a sample error (probably -EACCES) if
396 * none of the keyrings were searchable
397 *
398 * in terms of priority: success > -ENOKEY > -EAGAIN > other error
399 */
400 key = NULL;
401 ret = NULL;
402 err = ERR_PTR(-EAGAIN);
403
404 /* search the thread keyring first */
405 if (tsk->thread_keyring) {
406 key = keyring_search_aux(tsk->thread_keyring, type,
407 description, match);
408 if (!IS_ERR(key))
409 goto found;
410
411 switch (PTR_ERR(key)) {
412 case -EAGAIN: /* no key */
413 if (ret)
414 break;
415 case -ENOKEY: /* negative key */
416 ret = key;
417 break;
418 default:
419 err = key;
420 break;
421 }
422 }
423
424 /* search the process keyring second */
425 if (tsk->signal->process_keyring) {
426 key = keyring_search_aux(tsk->signal->process_keyring,
427 type, description, match);
428 if (!IS_ERR(key))
429 goto found;
430
431 switch (PTR_ERR(key)) {
432 case -EAGAIN: /* no key */
433 if (ret)
434 break;
435 case -ENOKEY: /* negative key */
436 ret = key;
437 break;
438 default:
439 err = key;
440 break;
441 }
442 }
443
444 /* search the session keyring last */
445 spin_lock_irqsave(&tsk->sighand->siglock, flags);
446
447 tmp = tsk->signal->session_keyring;
448 if (!tmp)
449 tmp = tsk->user->session_keyring;
450 atomic_inc(&tmp->usage);
451
452 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
453
454 key = keyring_search_aux(tmp, type, description, match);
455 key_put(tmp);
456 if (!IS_ERR(key))
457 goto found;
458
459 switch (PTR_ERR(key)) {
460 case -EAGAIN: /* no key */
461 if (ret)
462 break;
463 case -ENOKEY: /* negative key */
464 ret = key;
465 break;
466 default:
467 err = key;
468 break;
469 }
470
471 /* no key - decide on the error we're going to go for */
472 key = ret ? ret : err;
473
474 found:
475 return key;
476
477} /* end search_process_keyrings_aux() */
478
479/*****************************************************************************/
480/*
481 * search the process keyrings for the first matching key
482 * - we return -EAGAIN if we didn't find any matching key
483 * - we return -ENOKEY if we found only negative matching keys
484 */
485struct key *search_process_keyrings(struct key_type *type,
486 const char *description)
487{
488 return search_process_keyrings_aux(type, description, type->match);
489
490} /* end search_process_keyrings() */
491
492/*****************************************************************************/
493/*
494 * lookup a key given a key ID from userspace with a given permissions mask
495 * - don't create special keyrings unless so requested
496 * - partially constructed keys aren't found unless requested
497 */
498struct key *lookup_user_key(key_serial_t id, int create, int partial,
499 key_perm_t perm)
500{
501 struct task_struct *tsk = current;
502 unsigned long flags;
503 struct key *key;
504 int ret;
505
506 key = ERR_PTR(-ENOKEY);
507
508 switch (id) {
509 case KEY_SPEC_THREAD_KEYRING:
510 if (!tsk->thread_keyring) {
511 if (!create)
512 goto error;
513
514 ret = install_thread_keyring(tsk);
515 if (ret < 0) {
516 key = ERR_PTR(ret);
517 goto error;
518 }
519 }
520
521 key = tsk->thread_keyring;
522 atomic_inc(&key->usage);
523 break;
524
525 case KEY_SPEC_PROCESS_KEYRING:
526 if (!tsk->signal->process_keyring) {
527 if (!create)
528 goto error;
529
530 ret = install_process_keyring(tsk);
531 if (ret < 0) {
532 key = ERR_PTR(ret);
533 goto error;
534 }
535 }
536
537 key = tsk->signal->process_keyring;
538 atomic_inc(&key->usage);
539 break;
540
541 case KEY_SPEC_SESSION_KEYRING:
542 if (!tsk->signal->session_keyring) {
543 /* always install a session keyring upon access if one
544 * doesn't exist yet */
545 ret = install_session_keyring(
546 tsk, tsk->user->session_keyring);
547 if (ret < 0)
548 goto error;
549 }
550
551 spin_lock_irqsave(&tsk->sighand->siglock, flags);
552 key = tsk->signal->session_keyring;
553 atomic_inc(&key->usage);
554 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
555 break;
556
557 case KEY_SPEC_USER_KEYRING:
558 key = tsk->user->uid_keyring;
559 atomic_inc(&key->usage);
560 break;
561
562 case KEY_SPEC_USER_SESSION_KEYRING:
563 key = tsk->user->session_keyring;
564 atomic_inc(&key->usage);
565 break;
566
567 case KEY_SPEC_GROUP_KEYRING:
568 /* group keyrings are not yet supported */
569 key = ERR_PTR(-EINVAL);
570 goto error;
571
572 default:
573 key = ERR_PTR(-EINVAL);
574 if (id < 1)
575 goto error;
576
577 key = key_lookup(id);
578 if (IS_ERR(key))
579 goto error;
580 break;
581 }
582
583 /* check the status and permissions */
584 if (perm) {
585 ret = key_validate(key);
586 if (ret < 0)
587 goto invalid_key;
588 }
589
590 ret = -EIO;
591 if (!partial && !(key->flags & KEY_FLAG_INSTANTIATED))
592 goto invalid_key;
593
594 ret = -EACCES;
595 if (!key_permission(key, perm))
596 goto invalid_key;
597
598 error:
599 return key;
600
601 invalid_key:
602 key_put(key);
603 key = ERR_PTR(ret);
604 goto error;
605
606} /* end lookup_user_key() */
607
608/*****************************************************************************/
609/*
610 * join the named keyring as the session keyring if possible, or attempt to
611 * create a new one of that name if not
612 * - if the name is NULL, an empty anonymous keyring is installed instead
613 * - named session keyring joining is done with a semaphore held
614 */
615long join_session_keyring(const char *name)
616{
617 struct task_struct *tsk = current;
618 unsigned long flags;
619 struct key *keyring;
620 long ret;
621
622 /* if no name is provided, install an anonymous keyring */
623 if (!name) {
624 ret = install_session_keyring(tsk, NULL);
625 if (ret < 0)
626 goto error;
627
628 spin_lock_irqsave(&tsk->sighand->siglock, flags);
629 ret = tsk->signal->session_keyring->serial;
630 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
631 goto error;
632 }
633
634 /* allow the user to join or create a named keyring */
635 down(&key_session_sem);
636
637 /* look for an existing keyring of this name */
638 keyring = find_keyring_by_name(name, 0);
639 if (PTR_ERR(keyring) == -ENOKEY) {
640 /* not found - try and create a new one */
641 keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL);
642 if (IS_ERR(keyring)) {
643 ret = PTR_ERR(keyring);
644 goto error;
645 }
646 }
647 else if (IS_ERR(keyring)) {
648 ret = PTR_ERR(keyring);
649 goto error2;
650 }
651
652 /* we've got a keyring - now to install it */
653 ret = install_session_keyring(tsk, keyring);
654 if (ret < 0)
655 goto error2;
656
657 ret = keyring->serial;
658 key_put(keyring);
659
660 error2:
661 up(&key_session_sem);
662 error:
663 return ret;
664
665} /* end join_session_keyring() */
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
new file mode 100644
index 000000000000..9705b1aeba5d
--- /dev/null
+++ b/security/keys/request_key.c
@@ -0,0 +1,359 @@
1/* request_key.c: request a key from userspace
2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/sched.h>
14#include <linux/kmod.h>
15#include <linux/err.h>
16#include "internal.h"
17
18struct key_construction {
19 struct list_head link; /* link in construction queue */
20 struct key *key; /* key being constructed */
21};
22
23/* when waiting for someone else's keys, you get added to this */
24DECLARE_WAIT_QUEUE_HEAD(request_key_conswq);
25
26/*****************************************************************************/
27/*
28 * request userspace finish the construction of a key
29 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring> <info>"
30 * - if callout_info is an empty string, it'll be rendered as a "-" instead
31 */
32static int call_request_key(struct key *key,
33 const char *op,
34 const char *callout_info)
35{
36 struct task_struct *tsk = current;
37 unsigned long flags;
38 key_serial_t prkey, sskey;
39 char *argv[10], *envp[3], uid_str[12], gid_str[12];
40 char key_str[12], keyring_str[3][12];
41 int i;
42
43 /* record the UID and GID */
44 sprintf(uid_str, "%d", current->fsuid);
45 sprintf(gid_str, "%d", current->fsgid);
46
47 /* we say which key is under construction */
48 sprintf(key_str, "%d", key->serial);
49
50 /* we specify the process's default keyrings */
51 sprintf(keyring_str[0], "%d",
52 tsk->thread_keyring ? tsk->thread_keyring->serial : 0);
53
54 prkey = 0;
55 if (tsk->signal->process_keyring)
56 prkey = tsk->signal->process_keyring->serial;
57
58 sskey = 0;
59 spin_lock_irqsave(&tsk->sighand->siglock, flags);
60 if (tsk->signal->session_keyring)
61 sskey = tsk->signal->session_keyring->serial;
62 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
63
64
65 if (!sskey)
66 sskey = tsk->user->session_keyring->serial;
67
68 sprintf(keyring_str[1], "%d", prkey);
69 sprintf(keyring_str[2], "%d", sskey);
70
71 /* set up a minimal environment */
72 i = 0;
73 envp[i++] = "HOME=/";
74 envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
75 envp[i] = NULL;
76
77 /* set up the argument list */
78 i = 0;
79 argv[i++] = "/sbin/request-key";
80 argv[i++] = (char *) op;
81 argv[i++] = key_str;
82 argv[i++] = uid_str;
83 argv[i++] = gid_str;
84 argv[i++] = keyring_str[0];
85 argv[i++] = keyring_str[1];
86 argv[i++] = keyring_str[2];
87 argv[i++] = callout_info[0] ? (char *) callout_info : "-";
88 argv[i] = NULL;
89
90 /* do it */
91 return call_usermodehelper(argv[0], argv, envp, 1);
92
93} /* end call_request_key() */
94
95/*****************************************************************************/
96/*
97 * call out to userspace for the key
98 * - called with the construction sem held, but the sem is dropped here
99 * - we ignore program failure and go on key status instead
100 */
101static struct key *__request_key_construction(struct key_type *type,
102 const char *description,
103 const char *callout_info)
104{
105 struct key_construction cons;
106 struct timespec now;
107 struct key *key;
108 int ret, negative;
109
110 /* create a key and add it to the queue */
111 key = key_alloc(type, description,
112 current->fsuid, current->fsgid, KEY_USR_ALL, 0);
113 if (IS_ERR(key))
114 goto alloc_failed;
115
116 write_lock(&key->lock);
117 key->flags |= KEY_FLAG_USER_CONSTRUCT;
118 write_unlock(&key->lock);
119
120 cons.key = key;
121 list_add_tail(&cons.link, &key->user->consq);
122
123 /* we drop the construction sem here on behalf of the caller */
124 up_write(&key_construction_sem);
125
126 /* make the call */
127 ret = call_request_key(key, "create", callout_info);
128 if (ret < 0)
129 goto request_failed;
130
131 /* if the key wasn't instantiated, then we want to give an error */
132 ret = -ENOKEY;
133 if (!(key->flags & KEY_FLAG_INSTANTIATED))
134 goto request_failed;
135
136 down_write(&key_construction_sem);
137 list_del(&cons.link);
138 up_write(&key_construction_sem);
139
140 /* also give an error if the key was negatively instantiated */
141 check_not_negative:
142 if (key->flags & KEY_FLAG_NEGATIVE) {
143 key_put(key);
144 key = ERR_PTR(-ENOKEY);
145 }
146
147 out:
148 return key;
149
150 request_failed:
151 /* it wasn't instantiated
152 * - remove from construction queue
153 * - mark the key as dead
154 */
155 negative = 0;
156 down_write(&key_construction_sem);
157
158 list_del(&cons.link);
159
160 write_lock(&key->lock);
161 key->flags &= ~KEY_FLAG_USER_CONSTRUCT;
162
163 /* check it didn't get instantiated between the check and the down */
164 if (!(key->flags & KEY_FLAG_INSTANTIATED)) {
165 key->flags |= KEY_FLAG_INSTANTIATED | KEY_FLAG_NEGATIVE;
166 negative = 1;
167 }
168
169 write_unlock(&key->lock);
170 up_write(&key_construction_sem);
171
172 if (!negative)
173 goto check_not_negative; /* surprisingly, the key got
174 * instantiated */
175
176 /* set the timeout and store in the session keyring if we can */
177 now = current_kernel_time();
178 key->expiry = now.tv_sec + key_negative_timeout;
179
180 if (current->signal->session_keyring) {
181 unsigned long flags;
182 struct key *keyring;
183
184 spin_lock_irqsave(&current->sighand->siglock, flags);
185 keyring = current->signal->session_keyring;
186 atomic_inc(&keyring->usage);
187 spin_unlock_irqrestore(&current->sighand->siglock, flags);
188
189 key_link(keyring, key);
190 key_put(keyring);
191 }
192
193 key_put(key);
194
195 /* notify anyone who was waiting */
196 wake_up_all(&request_key_conswq);
197
198 key = ERR_PTR(ret);
199 goto out;
200
201 alloc_failed:
202 up_write(&key_construction_sem);
203 goto out;
204
205} /* end __request_key_construction() */
206
207/*****************************************************************************/
208/*
209 * call out to userspace to request the key
210 * - we check the construction queue first to see if an appropriate key is
211 * already being constructed by userspace
212 */
213static struct key *request_key_construction(struct key_type *type,
214 const char *description,
215 struct key_user *user,
216 const char *callout_info)
217{
218 struct key_construction *pcons;
219 struct key *key, *ckey;
220
221 DECLARE_WAITQUEUE(myself, current);
222
223 /* see if there's such a key under construction already */
224 down_write(&key_construction_sem);
225
226 list_for_each_entry(pcons, &user->consq, link) {
227 ckey = pcons->key;
228
229 if (ckey->type != type)
230 continue;
231
232 if (type->match(ckey, description))
233 goto found_key_under_construction;
234 }
235
236 /* see about getting userspace to construct the key */
237 key = __request_key_construction(type, description, callout_info);
238 error:
239 return key;
240
241 /* someone else has the same key under construction
242 * - we want to keep an eye on their key
243 */
244 found_key_under_construction:
245 atomic_inc(&ckey->usage);
246 up_write(&key_construction_sem);
247
248 /* wait for the key to be completed one way or another */
249 add_wait_queue(&request_key_conswq, &myself);
250
251 for (;;) {
252 set_current_state(TASK_UNINTERRUPTIBLE);
253 if (!(ckey->flags & KEY_FLAG_USER_CONSTRUCT))
254 break;
255 schedule();
256 }
257
258 set_current_state(TASK_RUNNING);
259 remove_wait_queue(&request_key_conswq, &myself);
260
261 /* we'll need to search this process's keyrings to see if the key is
262 * now there since we can't automatically assume it's also available
263 * there */
264 key_put(ckey);
265 ckey = NULL;
266
267 key = NULL; /* request a retry */
268 goto error;
269
270} /* end request_key_construction() */
271
272/*****************************************************************************/
273/*
274 * request a key
275 * - search the process's keyrings
276 * - check the list of keys being created or updated
277 * - call out to userspace for a key if requested (supplementary info can be
278 * passed)
279 */
280struct key *request_key(struct key_type *type,
281 const char *description,
282 const char *callout_info)
283{
284 struct key_user *user;
285 struct key *key;
286
287 /* search all the process keyrings for a key */
288 key = search_process_keyrings_aux(type, description, type->match);
289
290 if (PTR_ERR(key) == -EAGAIN) {
291 /* the search failed, but the keyrings were searchable, so we
292 * should consult userspace if we can */
293 key = ERR_PTR(-ENOKEY);
294 if (!callout_info)
295 goto error;
296
297 /* - get hold of the user's construction queue */
298 user = key_user_lookup(current->fsuid);
299 if (!user) {
300 key = ERR_PTR(-ENOMEM);
301 goto error;
302 }
303
304 for (;;) {
305 /* ask userspace (returns NULL if it waited on a key
306 * being constructed) */
307 key = request_key_construction(type, description,
308 user, callout_info);
309 if (key)
310 break;
311
312 /* someone else made the key we want, so we need to
313 * search again as it might now be available to us */
314 key = search_process_keyrings_aux(type, description,
315 type->match);
316 if (PTR_ERR(key) != -EAGAIN)
317 break;
318 }
319
320 key_user_put(user);
321 }
322
323 error:
324 return key;
325
326} /* end request_key() */
327
328EXPORT_SYMBOL(request_key);
329
330/*****************************************************************************/
331/*
332 * validate a key
333 */
334int key_validate(struct key *key)
335{
336 struct timespec now;
337 int ret = 0;
338
339 if (key) {
340 /* check it's still accessible */
341 ret = -EKEYREVOKED;
342 if (key->flags & (KEY_FLAG_REVOKED | KEY_FLAG_DEAD))
343 goto error;
344
345 /* check it hasn't expired */
346 ret = 0;
347 if (key->expiry) {
348 now = current_kernel_time();
349 if (now.tv_sec >= key->expiry)
350 ret = -EKEYEXPIRED;
351 }
352 }
353
354 error:
355 return ret;
356
357} /* end key_validate() */
358
359EXPORT_SYMBOL(key_validate);
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
new file mode 100644
index 000000000000..8d65b3a28129
--- /dev/null
+++ b/security/keys/user_defined.c
@@ -0,0 +1,191 @@
1/* user_defined.c: user defined key type
2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/sched.h>
15#include <linux/slab.h>
16#include <linux/seq_file.h>
17#include <linux/err.h>
18#include <asm/uaccess.h>
19#include "internal.h"
20
21static int user_instantiate(struct key *key, const void *data, size_t datalen);
22static int user_duplicate(struct key *key, const struct key *source);
23static int user_update(struct key *key, const void *data, size_t datalen);
24static int user_match(const struct key *key, const void *criterion);
25static void user_destroy(struct key *key);
26static void user_describe(const struct key *user, struct seq_file *m);
27static long user_read(const struct key *key,
28 char __user *buffer, size_t buflen);
29
30/*
31 * user defined keys take an arbitrary string as the description and an
32 * arbitrary blob of data as the payload
33 */
34struct key_type key_type_user = {
35 .name = "user",
36 .instantiate = user_instantiate,
37 .duplicate = user_duplicate,
38 .update = user_update,
39 .match = user_match,
40 .destroy = user_destroy,
41 .describe = user_describe,
42 .read = user_read,
43};
44
45/*****************************************************************************/
46/*
47 * instantiate a user defined key
48 */
49static int user_instantiate(struct key *key, const void *data, size_t datalen)
50{
51 int ret;
52
53 ret = -EINVAL;
54 if (datalen <= 0 || datalen > 32767 || !data)
55 goto error;
56
57 ret = key_payload_reserve(key, datalen);
58 if (ret < 0)
59 goto error;
60
61 /* attach the data */
62 ret = -ENOMEM;
63 key->payload.data = kmalloc(datalen, GFP_KERNEL);
64 if (!key->payload.data)
65 goto error;
66
67 memcpy(key->payload.data, data, datalen);
68 ret = 0;
69
70 error:
71 return ret;
72
73} /* end user_instantiate() */
74
75/*****************************************************************************/
76/*
77 * duplicate a user defined key
78 */
79static int user_duplicate(struct key *key, const struct key *source)
80{
81 int ret;
82
83 /* just copy the payload */
84 ret = -ENOMEM;
85 key->payload.data = kmalloc(source->datalen, GFP_KERNEL);
86
87 if (key->payload.data) {
88 key->datalen = source->datalen;
89 memcpy(key->payload.data, source->payload.data, source->datalen);
90 ret = 0;
91 }
92
93 return ret;
94
95} /* end user_duplicate() */
96
97/*****************************************************************************/
98/*
99 * update a user defined key
100 */
101static int user_update(struct key *key, const void *data, size_t datalen)
102{
103 void *new, *zap;
104 int ret;
105
106 ret = -EINVAL;
107 if (datalen <= 0 || datalen > 32767 || !data)
108 goto error;
109
110 /* copy the data */
111 ret = -ENOMEM;
112 new = kmalloc(datalen, GFP_KERNEL);
113 if (!new)
114 goto error;
115
116 memcpy(new, data, datalen);
117
118 /* check the quota and attach the new data */
119 zap = new;
120 write_lock(&key->lock);
121
122 ret = key_payload_reserve(key, datalen);
123
124 if (ret == 0) {
125 /* attach the new data, displacing the old */
126 zap = key->payload.data;
127 key->payload.data = new;
128 key->expiry = 0;
129 }
130
131 write_unlock(&key->lock);
132 kfree(zap);
133
134 error:
135 return ret;
136
137} /* end user_update() */
138
139/*****************************************************************************/
140/*
141 * match users on their name
142 */
143static int user_match(const struct key *key, const void *description)
144{
145 return strcmp(key->description, description) == 0;
146
147} /* end user_match() */
148
149/*****************************************************************************/
150/*
151 * dispose of the data dangling from the corpse of a user
152 */
153static void user_destroy(struct key *key)
154{
155 kfree(key->payload.data);
156
157} /* end user_destroy() */
158
159/*****************************************************************************/
160/*
161 * describe the user
162 */
163static void user_describe(const struct key *key, struct seq_file *m)
164{
165 seq_puts(m, key->description);
166
167 seq_printf(m, ": %u", key->datalen);
168
169} /* end user_describe() */
170
171/*****************************************************************************/
172/*
173 * read the key data
174 */
175static long user_read(const struct key *key,
176 char __user *buffer, size_t buflen)
177{
178 long ret = key->datalen;
179
180 /* we can return the data as is */
181 if (buffer && buflen > 0) {
182 if (buflen > key->datalen)
183 buflen = key->datalen;
184
185 if (copy_to_user(buffer, key->payload.data, buflen) != 0)
186 ret = -EFAULT;
187 }
188
189 return ret;
190
191} /* end user_read() */