Linux-2.6.12-rc2
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / security / keys / keyctl.c
CommitLineData
1da177e4
LT
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() */