[PATCH] keys: Discard key spinlock and use RCU for key payload
[linux-3.10.git] / security / keys / keyctl.c
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  */
31 asmlinkage 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  */
124 asmlinkage 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  */
235 long 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  */
258 long 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  */
301 long 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  */
350 long 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  */
376 long 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  */
402 long 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  */
436 long 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  */
474 long 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  */
536 long 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  */
637 static 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  */
653 long 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  */
713 long 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
732         if (!capable(CAP_SYS_ADMIN)) {
733                 /* only the sysadmin can chown a key to some other UID */
734                 if (uid != (uid_t) -1 && key->uid != uid)
735                         goto no_access;
736
737                 /* only the sysadmin can set the key's GID to a group other
738                  * than one of those that the current process subscribes to */
739                 if (gid != (gid_t) -1 && gid != key->gid && !in_group_p(gid))
740                         goto no_access;
741         }
742
743         /* change the UID (have to update the quotas) */
744         if (uid != (uid_t) -1 && uid != key->uid) {
745                 /* don't support UID changing yet */
746                 ret = -EOPNOTSUPP;
747                 goto no_access;
748         }
749
750         /* change the GID */
751         if (gid != (gid_t) -1)
752                 key->gid = gid;
753
754         ret = 0;
755
756  no_access:
757         up_write(&key->sem);
758         key_put(key);
759  error:
760         return ret;
761
762 } /* end keyctl_chown_key() */
763
764 /*****************************************************************************/
765 /*
766  * change the permission mask on a key
767  * - the keyring owned by the changer
768  * - implements keyctl(KEYCTL_SETPERM)
769  */
770 long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
771 {
772         struct key *key;
773         long ret;
774
775         ret = -EINVAL;
776         if (perm & ~(KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
777                 goto error;
778
779         key = lookup_user_key(id, 1, 1, 0);
780         if (IS_ERR(key)) {
781                 ret = PTR_ERR(key);
782                 goto error;
783         }
784
785         /* make the changes with the locks held to prevent chown/chmod races */
786         ret = -EACCES;
787         down_write(&key->sem);
788
789         /* if we're not the sysadmin, we can only change a key that we own */
790         if (capable(CAP_SYS_ADMIN) || key->uid == current->fsuid) {
791                 key->perm = perm;
792                 ret = 0;
793         }
794
795         up_write(&key->sem);
796         key_put(key);
797 error:
798         return ret;
799
800 } /* end keyctl_setperm_key() */
801
802 /*****************************************************************************/
803 /*
804  * instantiate the key with the specified payload, and, if one is given, link
805  * the key into the keyring
806  */
807 long keyctl_instantiate_key(key_serial_t id,
808                             const void __user *_payload,
809                             size_t plen,
810                             key_serial_t ringid)
811 {
812         struct key *key, *keyring;
813         void *payload;
814         long ret;
815
816         ret = -EINVAL;
817         if (plen > 32767)
818                 goto error;
819
820         /* pull the payload in if one was supplied */
821         payload = NULL;
822
823         if (_payload) {
824                 ret = -ENOMEM;
825                 payload = kmalloc(plen, GFP_KERNEL);
826                 if (!payload)
827                         goto error;
828
829                 ret = -EFAULT;
830                 if (copy_from_user(payload, _payload, plen) != 0)
831                         goto error2;
832         }
833
834         /* find the target key (which must be writable) */
835         key = lookup_user_key(id, 0, 1, KEY_WRITE);
836         if (IS_ERR(key)) {
837                 ret = PTR_ERR(key);
838                 goto error2;
839         }
840
841         /* find the destination keyring if present (which must also be
842          * writable) */
843         keyring = NULL;
844         if (ringid) {
845                 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
846                 if (IS_ERR(keyring)) {
847                         ret = PTR_ERR(keyring);
848                         goto error3;
849                 }
850         }
851
852         /* instantiate the key and link it into a keyring */
853         ret = key_instantiate_and_link(key, payload, plen, keyring);
854
855         key_put(keyring);
856  error3:
857         key_put(key);
858  error2:
859         kfree(payload);
860  error:
861         return ret;
862
863 } /* end keyctl_instantiate_key() */
864
865 /*****************************************************************************/
866 /*
867  * negatively instantiate the key with the given timeout (in seconds), and, if
868  * one is given, link the key into the keyring
869  */
870 long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
871 {
872         struct key *key, *keyring;
873         long ret;
874
875         /* find the target key (which must be writable) */
876         key = lookup_user_key(id, 0, 1, KEY_WRITE);
877         if (IS_ERR(key)) {
878                 ret = PTR_ERR(key);
879                 goto error;
880         }
881
882         /* find the destination keyring if present (which must also be
883          * writable) */
884         keyring = NULL;
885         if (ringid) {
886                 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
887                 if (IS_ERR(keyring)) {
888                         ret = PTR_ERR(keyring);
889                         goto error2;
890                 }
891         }
892
893         /* instantiate the key and link it into a keyring */
894         ret = key_negate_and_link(key, timeout, keyring);
895
896         key_put(keyring);
897  error2:
898         key_put(key);
899  error:
900         return ret;
901
902 } /* end keyctl_negate_key() */
903
904 /*****************************************************************************/
905 /*
906  * the key control system call
907  */
908 asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
909                            unsigned long arg4, unsigned long arg5)
910 {
911         switch (option) {
912         case KEYCTL_GET_KEYRING_ID:
913                 return keyctl_get_keyring_ID((key_serial_t) arg2,
914                                              (int) arg3);
915
916         case KEYCTL_JOIN_SESSION_KEYRING:
917                 return keyctl_join_session_keyring((const char __user *) arg2);
918
919         case KEYCTL_UPDATE:
920                 return keyctl_update_key((key_serial_t) arg2,
921                                          (const void __user *) arg3,
922                                          (size_t) arg4);
923
924         case KEYCTL_REVOKE:
925                 return keyctl_revoke_key((key_serial_t) arg2);
926
927         case KEYCTL_DESCRIBE:
928                 return keyctl_describe_key((key_serial_t) arg2,
929                                            (char __user *) arg3,
930                                            (unsigned) arg4);
931
932         case KEYCTL_CLEAR:
933                 return keyctl_keyring_clear((key_serial_t) arg2);
934
935         case KEYCTL_LINK:
936                 return keyctl_keyring_link((key_serial_t) arg2,
937                                            (key_serial_t) arg3);
938
939         case KEYCTL_UNLINK:
940                 return keyctl_keyring_unlink((key_serial_t) arg2,
941                                              (key_serial_t) arg3);
942
943         case KEYCTL_SEARCH:
944                 return keyctl_keyring_search((key_serial_t) arg2,
945                                              (const char __user *) arg3,
946                                              (const char __user *) arg4,
947                                              (key_serial_t) arg5);
948
949         case KEYCTL_READ:
950                 return keyctl_read_key((key_serial_t) arg2,
951                                        (char __user *) arg3,
952                                        (size_t) arg4);
953
954         case KEYCTL_CHOWN:
955                 return keyctl_chown_key((key_serial_t) arg2,
956                                         (uid_t) arg3,
957                                         (gid_t) arg4);
958
959         case KEYCTL_SETPERM:
960                 return keyctl_setperm_key((key_serial_t) arg2,
961                                           (key_perm_t) arg3);
962
963         case KEYCTL_INSTANTIATE:
964                 return keyctl_instantiate_key((key_serial_t) arg2,
965                                               (const void __user *) arg3,
966                                               (size_t) arg4,
967                                               (key_serial_t) arg5);
968
969         case KEYCTL_NEGATE:
970                 return keyctl_negate_key((key_serial_t) arg2,
971                                          (unsigned) arg3,
972                                          (key_serial_t) arg4);
973
974         default:
975                 return -EOPNOTSUPP;
976         }
977
978 } /* end sys_keyctl() */