Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KEYS: Make request_key() and co fundamentally asynchronous

Make request_key() and co fundamentally asynchronous to make it easier for
NFS to make use of them. There are now accessor functions that do
asynchronous constructions, a wait function to wait for construction to
complete, and a completion function for the key type to indicate completion
of construction.

Note that the construction queue is now gone. Instead, keys under
construction are linked in to the appropriate keyring in advance, and that
anyone encountering one must wait for it to be complete before they can use
it. This is done automatically for userspace.

The following auxiliary changes are also made:

(1) Key type implementation stuff is split from linux/key.h into
linux/key-type.h.

(2) AF_RXRPC provides a way to allocate null rxrpc-type keys so that AFS does
not need to call key_instantiate_and_link() directly.

(3) Adjust the debugging macros so that they're -Wformat checked even if
they are disabled, and make it so they can be enabled simply by defining
__KDEBUG to be consistent with other code of mine.

(3) Documentation.

[alan@lxorguk.ukuu.org.uk: keys: missing word in documentation]
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

David Howells and committed by
Linus Torvalds
76181c13 398c95bd

+604 -434
+21 -4
Documentation/keys-request-key.txt
··· 20 20 const char *callout_string, 21 21 void *aux); 22 22 23 + or: 24 + 25 + struct key *request_key_async(const struct key_type *type, 26 + const char *description, 27 + const char *callout_string); 28 + 29 + or: 30 + 31 + struct key *request_key_async_with_auxdata(const struct key_type *type, 32 + const char *description, 33 + const char *callout_string, 34 + void *aux); 35 + 23 36 Or by userspace invoking the request_key system call: 24 37 25 38 key_serial_t request_key(const char *type, ··· 45 32 destroyed. The kernel interface returns a pointer directly to the key, and 46 33 it's up to the caller to destroy the key. 47 34 48 - The request_key_with_auxdata() call is like the in-kernel request_key() call, 49 - except that it permits auxiliary data to be passed to the upcaller (the default 50 - is NULL). This is only useful for those key types that define their own upcall 51 - mechanism rather than using /sbin/request-key. 35 + The request_key*_with_auxdata() calls are like the in-kernel request_key*() 36 + calls, except that they permit auxiliary data to be passed to the upcaller (the 37 + default is NULL). This is only useful for those key types that define their 38 + own upcall mechanism rather than using /sbin/request-key. 39 + 40 + The two async in-kernel calls may return keys that are still in the process of 41 + being constructed. The two non-async ones will wait for construction to 42 + complete first. 52 43 53 44 The userspace interface links the key to a keyring associated with the process 54 45 to prevent the key from going away, and returns the serial number of the key to
+79 -14
Documentation/keys.txt
··· 4 4 5 5 This service allows cryptographic keys, authentication tokens, cross-domain 6 6 user mappings, and similar to be cached in the kernel for the use of 7 - filesystems other kernel services. 7 + filesystems and other kernel services. 8 8 9 9 Keyrings are permitted; these are a special type of key that can hold links to 10 10 other keys. Processes each have three standard keyring subscriptions that a ··· 726 726 two different users opening the same file is left to the filesystem author to 727 727 solve. 728 728 729 + To access the key manager, the following header must be #included: 730 + 731 + <linux/key.h> 732 + 733 + Specific key types should have a header file under include/keys/ that should be 734 + used to access that type. For keys of type "user", for example, that would be: 735 + 736 + <keys/user-type.h> 737 + 729 738 Note that there are two different types of pointers to keys that may be 730 739 encountered: 731 740 ··· 798 789 799 790 This is identical to request_key(), except that the auxiliary data is 800 791 passed to the key_type->request_key() op if it exists. 792 + 793 + 794 + (*) A key can be requested asynchronously by calling one of: 795 + 796 + struct key *request_key_async(const struct key_type *type, 797 + const char *description, 798 + const char *callout_string); 799 + 800 + or: 801 + 802 + struct key *request_key_async_with_auxdata(const struct key_type *type, 803 + const char *description, 804 + const char *callout_string, 805 + void *aux); 806 + 807 + which are asynchronous equivalents of request_key() and 808 + request_key_with_auxdata() respectively. 809 + 810 + These two functions return with the key potentially still under 811 + construction. To wait for contruction completion, the following should be 812 + called: 813 + 814 + int wait_for_key_construction(struct key *key, bool intr); 815 + 816 + The function will wait for the key to finish being constructed and then 817 + invokes key_validate() to return an appropriate value to indicate the state 818 + of the key (0 indicates the key is usable). 819 + 820 + If intr is true, then the wait can be interrupted by a signal, in which 821 + case error ERESTARTSYS will be returned. 801 822 802 823 803 824 (*) When it is no longer required, the key should be released using: ··· 963 924 964 925 A kernel service may want to define its own key type. For instance, an AFS 965 926 filesystem might want to define a Kerberos 5 ticket key type. To do this, it 966 - author fills in a struct key_type and registers it with the system. 927 + author fills in a key_type struct and registers it with the system. 928 + 929 + Source files that implement key types should include the following header file: 930 + 931 + <linux/key-type.h> 967 932 968 933 The structure has a number of fields, some of which are mandatory: 969 934 ··· 1096 1053 as might happen when the userspace buffer is accessed. 1097 1054 1098 1055 1099 - (*) int (*request_key)(struct key *key, struct key *authkey, const char *op, 1056 + (*) int (*request_key)(struct key_construction *cons, const char *op, 1100 1057 void *aux); 1101 1058 1102 - This method is optional. If provided, request_key() and 1103 - request_key_with_auxdata() will invoke this function rather than 1104 - upcalling to /sbin/request-key to operate upon a key of this type. 1059 + This method is optional. If provided, request_key() and friends will 1060 + invoke this function rather than upcalling to /sbin/request-key to operate 1061 + upon a key of this type. 1105 1062 1106 - The aux parameter is as passed to request_key_with_auxdata() or is NULL 1107 - otherwise. Also passed are the key to be operated upon, the 1108 - authorisation key for this operation and the operation type (currently 1109 - only "create"). 1063 + The aux parameter is as passed to request_key_async_with_auxdata() and 1064 + similar or is NULL otherwise. Also passed are the construction record for 1065 + the key to be operated upon and the operation type (currently only 1066 + "create"). 1110 1067 1111 - This function should return only when the upcall is complete. Upon return 1112 - the authorisation key will be revoked, and the target key will be 1113 - negatively instantiated if it is still uninstantiated. The error will be 1114 - returned to the caller of request_key*(). 1068 + This method is permitted to return before the upcall is complete, but the 1069 + following function must be called under all circumstances to complete the 1070 + instantiation process, whether or not it succeeds, whether or not there's 1071 + an error: 1072 + 1073 + void complete_request_key(struct key_construction *cons, int error); 1074 + 1075 + The error parameter should be 0 on success, -ve on error. The 1076 + construction record is destroyed by this action and the authorisation key 1077 + will be revoked. If an error is indicated, the key under construction 1078 + will be negatively instantiated if it wasn't already instantiated. 1079 + 1080 + If this method returns an error, that error will be returned to the 1081 + caller of request_key*(). complete_request_key() must be called prior to 1082 + returning. 1083 + 1084 + The key under construction and the authorisation key can be found in the 1085 + key_construction struct pointed to by cons: 1086 + 1087 + (*) struct key *key; 1088 + 1089 + The key under construction. 1090 + 1091 + (*) struct key *authkey; 1092 + 1093 + The authorisation key. 1115 1094 1116 1095 1117 1096 ============================
+7
Documentation/networking/rxrpc.txt
··· 857 857 858 858 This is used to extract the error number from a message indicating either 859 859 a local error occurred or a network error occurred. 860 + 861 + (*) Allocate a null key for doing anonymous security. 862 + 863 + struct key *rxrpc_get_null_key(const char *keyname); 864 + 865 + This is used to allocate a null RxRPC key that can be used to indicate 866 + anonymous security for a particular domain.
+6 -11
fs/afs/cell.c
··· 33 33 static struct afs_cell *afs_cell_alloc(const char *name, char *vllist) 34 34 { 35 35 struct afs_cell *cell; 36 + struct key *key; 36 37 size_t namelen; 37 38 char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp, *next; 38 39 int ret; ··· 90 89 do { 91 90 *dp++ = toupper(*cp); 92 91 } while (*cp++); 93 - cell->anonymous_key = key_alloc(&key_type_rxrpc, keyname, 0, 0, current, 94 - KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA); 95 - if (IS_ERR(cell->anonymous_key)) { 96 - _debug("no key"); 97 - ret = PTR_ERR(cell->anonymous_key); 98 - goto error; 99 - } 100 92 101 - ret = key_instantiate_and_link(cell->anonymous_key, NULL, 0, 102 - NULL, NULL); 103 - if (ret < 0) { 104 - _debug("instantiate failed"); 93 + key = rxrpc_get_null_key(keyname); 94 + if (IS_ERR(key)) { 95 + _debug("no key"); 96 + ret = PTR_ERR(key); 105 97 goto error; 106 98 } 99 + cell->anonymous_key = key; 107 100 108 101 _debug("anon key %p{%x}", 109 102 cell->anonymous_key, key_serial(cell->anonymous_key));
+2
include/keys/rxrpc-type.h
··· 19 19 */ 20 20 extern struct key_type key_type_rxrpc; 21 21 22 + extern struct key *rxrpc_get_null_key(const char *); 23 + 22 24 #endif /* _KEYS_USER_TYPE_H */
+112
include/linux/key-type.h
··· 1 + /* Definitions for key type implementations 2 + * 3 + * Copyright (C) 2007 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 Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #ifndef _LINUX_KEY_TYPE_H 13 + #define _LINUX_KEY_TYPE_H 14 + 15 + #include <linux/key.h> 16 + 17 + #ifdef CONFIG_KEYS 18 + 19 + /* 20 + * key under-construction record 21 + * - passed to the request_key actor if supplied 22 + */ 23 + struct key_construction { 24 + struct key *key; /* key being constructed */ 25 + struct key *authkey;/* authorisation for key being constructed */ 26 + }; 27 + 28 + typedef int (*request_key_actor_t)(struct key_construction *key, 29 + const char *op, void *aux); 30 + 31 + /* 32 + * kernel managed key type definition 33 + */ 34 + struct key_type { 35 + /* name of the type */ 36 + const char *name; 37 + 38 + /* default payload length for quota precalculation (optional) 39 + * - this can be used instead of calling key_payload_reserve(), that 40 + * function only needs to be called if the real datalen is different 41 + */ 42 + size_t def_datalen; 43 + 44 + /* instantiate a key of this type 45 + * - this method should call key_payload_reserve() to determine if the 46 + * user's quota will hold the payload 47 + */ 48 + int (*instantiate)(struct key *key, const void *data, size_t datalen); 49 + 50 + /* update a key of this type (optional) 51 + * - this method should call key_payload_reserve() to recalculate the 52 + * quota consumption 53 + * - the key must be locked against read when modifying 54 + */ 55 + int (*update)(struct key *key, const void *data, size_t datalen); 56 + 57 + /* match a key against a description */ 58 + int (*match)(const struct key *key, const void *desc); 59 + 60 + /* clear some of the data from a key on revokation (optional) 61 + * - the key's semaphore will be write-locked by the caller 62 + */ 63 + void (*revoke)(struct key *key); 64 + 65 + /* clear the data from a key (optional) */ 66 + void (*destroy)(struct key *key); 67 + 68 + /* describe a key */ 69 + void (*describe)(const struct key *key, struct seq_file *p); 70 + 71 + /* read a key's data (optional) 72 + * - permission checks will be done by the caller 73 + * - the key's semaphore will be readlocked by the caller 74 + * - should return the amount of data that could be read, no matter how 75 + * much is copied into the buffer 76 + * - shouldn't do the copy if the buffer is NULL 77 + */ 78 + long (*read)(const struct key *key, char __user *buffer, size_t buflen); 79 + 80 + /* handle request_key() for this type instead of invoking 81 + * /sbin/request-key (optional) 82 + * - key is the key to instantiate 83 + * - authkey is the authority to assume when instantiating this key 84 + * - op is the operation to be done, usually "create" 85 + * - the call must not return until the instantiation process has run 86 + * its course 87 + */ 88 + request_key_actor_t request_key; 89 + 90 + /* internal fields */ 91 + struct list_head link; /* link in types list */ 92 + }; 93 + 94 + extern struct key_type key_type_keyring; 95 + 96 + extern int register_key_type(struct key_type *ktype); 97 + extern void unregister_key_type(struct key_type *ktype); 98 + 99 + extern int key_payload_reserve(struct key *key, size_t datalen); 100 + extern int key_instantiate_and_link(struct key *key, 101 + const void *data, 102 + size_t datalen, 103 + struct key *keyring, 104 + struct key *instkey); 105 + extern int key_negate_and_link(struct key *key, 106 + unsigned timeout, 107 + struct key *keyring, 108 + struct key *instkey); 109 + extern void complete_request_key(struct key_construction *cons, int error); 110 + 111 + #endif /* CONFIG_KEYS */ 112 + #endif /* _LINUX_KEY_TYPE_H */
+13 -86
include/linux/key.h
··· 1 - /* key.h: authentication token and access key management 1 + /* Authentication token and access key management 2 2 * 3 - * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 + * Copyright (C) 2004, 2007 Red Hat, Inc. All Rights Reserved. 4 4 * Written by David Howells (dhowells@redhat.com) 5 5 * 6 6 * This program is free software; you can redistribute it and/or ··· 175 175 } payload; 176 176 }; 177 177 178 - /*****************************************************************************/ 179 - /* 180 - * kernel managed key type definition 181 - */ 182 - typedef int (*request_key_actor_t)(struct key *key, struct key *authkey, 183 - const char *op, void *aux); 184 - 185 - struct key_type { 186 - /* name of the type */ 187 - const char *name; 188 - 189 - /* default payload length for quota precalculation (optional) 190 - * - this can be used instead of calling key_payload_reserve(), that 191 - * function only needs to be called if the real datalen is different 192 - */ 193 - size_t def_datalen; 194 - 195 - /* instantiate a key of this type 196 - * - this method should call key_payload_reserve() to determine if the 197 - * user's quota will hold the payload 198 - */ 199 - int (*instantiate)(struct key *key, const void *data, size_t datalen); 200 - 201 - /* update a key of this type (optional) 202 - * - this method should call key_payload_reserve() to recalculate the 203 - * quota consumption 204 - * - the key must be locked against read when modifying 205 - */ 206 - int (*update)(struct key *key, const void *data, size_t datalen); 207 - 208 - /* match a key against a description */ 209 - int (*match)(const struct key *key, const void *desc); 210 - 211 - /* clear some of the data from a key on revokation (optional) 212 - * - the key's semaphore will be write-locked by the caller 213 - */ 214 - void (*revoke)(struct key *key); 215 - 216 - /* clear the data from a key (optional) */ 217 - void (*destroy)(struct key *key); 218 - 219 - /* describe a key */ 220 - void (*describe)(const struct key *key, struct seq_file *p); 221 - 222 - /* read a key's data (optional) 223 - * - permission checks will be done by the caller 224 - * - the key's semaphore will be readlocked by the caller 225 - * - should return the amount of data that could be read, no matter how 226 - * much is copied into the buffer 227 - * - shouldn't do the copy if the buffer is NULL 228 - */ 229 - long (*read)(const struct key *key, char __user *buffer, size_t buflen); 230 - 231 - /* handle request_key() for this type instead of invoking 232 - * /sbin/request-key (optional) 233 - * - key is the key to instantiate 234 - * - authkey is the authority to assume when instantiating this key 235 - * - op is the operation to be done, usually "create" 236 - * - the call must not return until the instantiation process has run 237 - * its course 238 - */ 239 - request_key_actor_t request_key; 240 - 241 - /* internal fields */ 242 - struct list_head link; /* link in types list */ 243 - }; 244 - 245 - extern struct key_type key_type_keyring; 246 - 247 - extern int register_key_type(struct key_type *ktype); 248 - extern void unregister_key_type(struct key_type *ktype); 249 - 250 178 extern struct key *key_alloc(struct key_type *type, 251 179 const char *desc, 252 180 uid_t uid, gid_t gid, ··· 187 259 #define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */ 188 260 #define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */ 189 261 190 - extern int key_payload_reserve(struct key *key, size_t datalen); 191 - extern int key_instantiate_and_link(struct key *key, 192 - const void *data, 193 - size_t datalen, 194 - struct key *keyring, 195 - struct key *instkey); 196 - extern int key_negate_and_link(struct key *key, 197 - unsigned timeout, 198 - struct key *keyring, 199 - struct key *instkey); 200 262 extern void key_revoke(struct key *key); 201 263 extern void key_put(struct key *key); 202 264 ··· 210 292 const char *description, 211 293 const char *callout_info, 212 294 void *aux); 295 + 296 + extern struct key *request_key_async(struct key_type *type, 297 + const char *description, 298 + const char *callout_info); 299 + 300 + extern struct key *request_key_async_with_auxdata(struct key_type *type, 301 + const char *description, 302 + const char *callout_info, 303 + void *aux); 304 + 305 + extern int wait_for_key_construction(struct key *key, bool intr); 213 306 214 307 extern int key_validate(struct key *key); 215 308 ··· 256 327 struct key *key); 257 328 258 329 extern struct key *key_lookup(key_serial_t id); 259 - 260 - extern void keyring_replace_payload(struct key *key, void *replacement); 261 330 262 331 #define key_serial(key) ((key) ? (key)->serial : 0) 263 332
+1
net/rxrpc/af_rxrpc.c
··· 14 14 #include <linux/skbuff.h> 15 15 #include <linux/poll.h> 16 16 #include <linux/proc_fs.h> 17 + #include <linux/key-type.h> 17 18 #include <net/net_namespace.h> 18 19 #include <net/sock.h> 19 20 #include <net/af_rxrpc.h>
+29 -3
net/rxrpc/ar-key.c
··· 15 15 #include <linux/module.h> 16 16 #include <linux/net.h> 17 17 #include <linux/skbuff.h> 18 - #include <linux/key.h> 18 + #include <linux/key-type.h> 19 19 #include <linux/crypto.h> 20 20 #include <net/sock.h> 21 21 #include <net/af_rxrpc.h> ··· 40 40 .destroy = rxrpc_destroy, 41 41 .describe = rxrpc_describe, 42 42 }; 43 - 44 43 EXPORT_SYMBOL(key_type_rxrpc); 45 44 46 45 /* ··· 329 330 _leave(" = -ENOMEM [ins %d]", ret); 330 331 return -ENOMEM; 331 332 } 332 - 333 333 EXPORT_SYMBOL(rxrpc_get_server_data_key); 334 + 335 + /** 336 + * rxrpc_get_null_key - Generate a null RxRPC key 337 + * @keyname: The name to give the key. 338 + * 339 + * Generate a null RxRPC key that can be used to indicate anonymous security is 340 + * required for a particular domain. 341 + */ 342 + struct key *rxrpc_get_null_key(const char *keyname) 343 + { 344 + struct key *key; 345 + int ret; 346 + 347 + key = key_alloc(&key_type_rxrpc, keyname, 0, 0, current, 348 + KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA); 349 + if (IS_ERR(key)) 350 + return key; 351 + 352 + ret = key_instantiate_and_link(key, NULL, 0, NULL, NULL); 353 + if (ret < 0) { 354 + key_revoke(key); 355 + key_put(key); 356 + return ERR_PTR(ret); 357 + } 358 + 359 + return key; 360 + } 361 + EXPORT_SYMBOL(rxrpc_get_null_key);
+23 -12
security/keys/internal.h
··· 1 1 /* internal.h: authentication token and access key management internal defs 2 2 * 3 - * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved. 3 + * Copyright (C) 2003-5, 2007 Red Hat, Inc. All Rights Reserved. 4 4 * Written by David Howells (dhowells@redhat.com) 5 5 * 6 6 * This program is free software; you can redistribute it and/or ··· 12 12 #ifndef _INTERNAL_H 13 13 #define _INTERNAL_H 14 14 15 - #include <linux/key.h> 15 + #include <linux/key-type.h> 16 16 #include <linux/key-ui.h> 17 17 18 - #if 0 19 - #define kenter(FMT, a...) printk("==> %s("FMT")\n",__FUNCTION__ , ## a) 20 - #define kleave(FMT, a...) printk("<== %s()"FMT"\n",__FUNCTION__ , ## a) 21 - #define kdebug(FMT, a...) printk(FMT"\n" , ## a) 18 + static inline __attribute__((format(printf, 1, 2))) 19 + void no_printk(const char *fmt, ...) 20 + { 21 + } 22 + 23 + #ifdef __KDEBUG 24 + #define kenter(FMT, ...) \ 25 + printk(KERN_DEBUG "==> %s("FMT")\n", __FUNCTION__, ##__VA_ARGS__) 26 + #define kleave(FMT, ...) \ 27 + printk(KERN_DEBUG "<== %s()"FMT"\n", __FUNCTION__, ##__VA_ARGS__) 28 + #define kdebug(FMT, ...) \ 29 + printk(KERN_DEBUG "xxx" FMT"yyy\n", ##__VA_ARGS__) 22 30 #else 23 - #define kenter(FMT, a...) do {} while(0) 24 - #define kleave(FMT, a...) do {} while(0) 25 - #define kdebug(FMT, a...) do {} while(0) 31 + #define kenter(FMT, ...) \ 32 + no_printk(KERN_DEBUG "==> %s("FMT")\n", __FUNCTION__, ##__VA_ARGS__) 33 + #define kleave(FMT, ...) \ 34 + no_printk(KERN_DEBUG "<== %s()"FMT"\n", __FUNCTION__, ##__VA_ARGS__) 35 + #define kdebug(FMT, ...) \ 36 + no_printk(KERN_DEBUG FMT"\n", ##__VA_ARGS__) 26 37 #endif 27 38 28 39 extern struct key_type key_type_user; ··· 47 36 */ 48 37 struct key_user { 49 38 struct rb_node node; 50 - struct list_head consq; /* construction queue */ 39 + struct mutex cons_lock; /* construction initiation lock */ 51 40 spinlock_t lock; 52 41 atomic_t usage; /* for accessing qnkeys & qnbytes */ 53 42 atomic_t nkeys; /* number of keys */ ··· 73 62 extern struct rb_root key_serial_tree; 74 63 extern spinlock_t key_serial_lock; 75 64 extern struct semaphore key_alloc_sem; 76 - extern struct rw_semaphore key_construction_sem; 65 + extern struct mutex key_construction_mutex; 77 66 extern wait_queue_head_t request_key_conswq; 78 67 79 68 ··· 120 109 struct request_key_auth { 121 110 struct key *target_key; 122 111 struct task_struct *context; 123 - const char *callout_info; 112 + char *callout_info; 124 113 pid_t pid; 125 114 }; 126 115
+18 -16
security/keys/key.c
··· 1 - /* key.c: basic authentication token and access key management 1 + /* Basic authentication token and access key management 2 2 * 3 - * Copyright (C) 2004-6 Red Hat, Inc. All Rights Reserved. 3 + * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved. 4 4 * Written by David Howells (dhowells@redhat.com) 5 5 * 6 6 * This program is free software; you can redistribute it and/or ··· 34 34 static DECLARE_WORK(key_cleanup_task, key_cleanup); 35 35 36 36 /* we serialise key instantiation and link */ 37 - DECLARE_RWSEM(key_construction_sem); 37 + DEFINE_MUTEX(key_construction_mutex); 38 38 39 39 /* any key who's type gets unegistered will be re-typed to this */ 40 40 static struct key_type key_type_dead = { ··· 104 104 candidate->qnkeys = 0; 105 105 candidate->qnbytes = 0; 106 106 spin_lock_init(&candidate->lock); 107 - INIT_LIST_HEAD(&candidate->consq); 107 + mutex_init(&candidate->cons_lock); 108 108 109 109 rb_link_node(&candidate->node, parent, p); 110 110 rb_insert_color(&candidate->node, &key_user_tree); ··· 418 418 awaken = 0; 419 419 ret = -EBUSY; 420 420 421 - down_write(&key_construction_sem); 421 + mutex_lock(&key_construction_mutex); 422 422 423 423 /* can't instantiate twice */ 424 424 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { ··· 443 443 } 444 444 } 445 445 446 - up_write(&key_construction_sem); 446 + mutex_unlock(&key_construction_mutex); 447 447 448 448 /* wake up anyone waiting for a key to be constructed */ 449 449 if (awaken) 450 - wake_up_all(&request_key_conswq); 450 + wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT); 451 451 452 452 return ret; 453 453 ··· 500 500 if (keyring) 501 501 down_write(&keyring->sem); 502 502 503 - down_write(&key_construction_sem); 503 + mutex_lock(&key_construction_mutex); 504 504 505 505 /* can't instantiate twice */ 506 506 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { ··· 525 525 key_revoke(instkey); 526 526 } 527 527 528 - up_write(&key_construction_sem); 528 + mutex_unlock(&key_construction_mutex); 529 529 530 530 if (keyring) 531 531 up_write(&keyring->sem); 532 532 533 533 /* wake up anyone waiting for a key to be constructed */ 534 534 if (awaken) 535 - wake_up_all(&request_key_conswq); 535 + wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT); 536 536 537 537 return ret; 538 538 ··· 899 899 { 900 900 key_check(key); 901 901 902 - /* make sure no one's trying to change or use the key when we mark 903 - * it */ 904 - down_write(&key->sem); 905 - set_bit(KEY_FLAG_REVOKED, &key->flags); 906 - 907 - if (key->type->revoke) 902 + /* make sure no one's trying to change or use the key when we mark it 903 + * - we tell lockdep that we might nest because we might be revoking an 904 + * authorisation key whilst holding the sem on a key we've just 905 + * instantiated 906 + */ 907 + down_write_nested(&key->sem, 1); 908 + if (!test_and_set_bit(KEY_FLAG_REVOKED, &key->flags) && 909 + key->type->revoke) 908 910 key->type->revoke(key); 909 911 910 912 up_write(&key->sem);
+13 -3
security/keys/process_keys.c
··· 26 26 /* the root user's tracking struct */ 27 27 struct key_user root_key_user = { 28 28 .usage = ATOMIC_INIT(3), 29 - .consq = LIST_HEAD_INIT(root_key_user.consq), 29 + .cons_lock = __MUTEX_INITIALIZER(root_key_user.cons_lock), 30 30 .lock = __SPIN_LOCK_UNLOCKED(root_key_user.lock), 31 31 .nkeys = ATOMIC_INIT(2), 32 32 .nikeys = ATOMIC_INIT(2), ··· 679 679 break; 680 680 } 681 681 682 - /* check the status */ 683 - if (perm) { 682 + if (!partial) { 683 + ret = wait_for_key_construction(key, true); 684 + switch (ret) { 685 + case -ERESTARTSYS: 686 + goto invalid_key; 687 + default: 688 + if (perm) 689 + goto invalid_key; 690 + case 0: 691 + break; 692 + } 693 + } else if (perm) { 684 694 ret = key_validate(key); 685 695 if (ret < 0) 686 696 goto invalid_key;
+270 -284
security/keys/request_key.c
··· 1 - /* request_key.c: request a key from userspace 1 + /* Request a key from userspace 2 2 * 3 - * Copyright (C) 2004-6 Red Hat, Inc. All Rights Reserved. 3 + * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved. 4 4 * Written by David Howells (dhowells@redhat.com) 5 5 * 6 6 * This program is free software; you can redistribute it and/or ··· 18 18 #include <linux/keyctl.h> 19 19 #include "internal.h" 20 20 21 - struct key_construction { 22 - struct list_head link; /* link in construction queue */ 23 - struct key *key; /* key being constructed */ 24 - }; 21 + /* 22 + * wait_on_bit() sleep function for uninterruptible waiting 23 + */ 24 + static int key_wait_bit(void *flags) 25 + { 26 + schedule(); 27 + return 0; 28 + } 25 29 26 - /* when waiting for someone else's keys, you get added to this */ 27 - DECLARE_WAIT_QUEUE_HEAD(request_key_conswq); 30 + /* 31 + * wait_on_bit() sleep function for interruptible waiting 32 + */ 33 + static int key_wait_bit_intr(void *flags) 34 + { 35 + schedule(); 36 + return signal_pending(current) ? -ERESTARTSYS : 0; 37 + } 28 38 29 - /*****************************************************************************/ 39 + /* 40 + * call to complete the construction of a key 41 + */ 42 + void complete_request_key(struct key_construction *cons, int error) 43 + { 44 + kenter("{%d,%d},%d", cons->key->serial, cons->authkey->serial, error); 45 + 46 + if (error < 0) 47 + key_negate_and_link(cons->key, key_negative_timeout, NULL, 48 + cons->authkey); 49 + else 50 + key_revoke(cons->authkey); 51 + 52 + key_put(cons->key); 53 + key_put(cons->authkey); 54 + kfree(cons); 55 + } 56 + EXPORT_SYMBOL(complete_request_key); 57 + 30 58 /* 31 59 * request userspace finish the construction of a key 32 60 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>" 33 61 */ 34 - static int call_sbin_request_key(struct key *key, 35 - struct key *authkey, 62 + static int call_sbin_request_key(struct key_construction *cons, 36 63 const char *op, 37 64 void *aux) 38 65 { 39 66 struct task_struct *tsk = current; 40 67 key_serial_t prkey, sskey; 41 - struct key *keyring; 68 + struct key *key = cons->key, *authkey = cons->authkey, *keyring; 42 69 char *argv[9], *envp[3], uid_str[12], gid_str[12]; 43 70 char key_str[12], keyring_str[3][12]; 44 71 char desc[20]; ··· 109 82 rcu_read_lock(); 110 83 sskey = rcu_dereference(tsk->signal->session_keyring)->serial; 111 84 rcu_read_unlock(); 112 - } 113 - else { 85 + } else { 114 86 sskey = tsk->user->session_keyring->serial; 115 87 } 116 88 ··· 136 110 /* do it */ 137 111 ret = call_usermodehelper_keys(argv[0], argv, envp, keyring, 138 112 UMH_WAIT_PROC); 113 + kdebug("usermode -> 0x%x", ret); 114 + if (ret >= 0) { 115 + /* ret is the exit/wait code */ 116 + if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags) || 117 + key_validate(key) < 0) 118 + ret = -ENOKEY; 119 + else 120 + /* ignore any errors from userspace if the key was 121 + * instantiated */ 122 + ret = 0; 123 + } 139 124 140 125 error_link: 141 126 key_put(keyring); 142 127 143 128 error_alloc: 144 129 kleave(" = %d", ret); 130 + complete_request_key(cons, ret); 145 131 return ret; 132 + } 146 133 147 - } /* end call_sbin_request_key() */ 148 - 149 - /*****************************************************************************/ 150 134 /* 151 - * call out to userspace for the key 152 - * - called with the construction sem held, but the sem is dropped here 135 + * call out to userspace for key construction 153 136 * - we ignore program failure and go on key status instead 154 137 */ 155 - static struct key *__request_key_construction(struct key_type *type, 156 - const char *description, 157 - const char *callout_info, 158 - void *aux, 159 - unsigned long flags) 138 + static int construct_key(struct key *key, const char *callout_info, void *aux) 160 139 { 140 + struct key_construction *cons; 161 141 request_key_actor_t actor; 162 - struct key_construction cons; 163 - struct timespec now; 164 - struct key *key, *authkey; 165 - int ret, negated; 142 + struct key *authkey; 143 + int ret; 166 144 167 - kenter("%s,%s,%s,%lx", type->name, description, callout_info, flags); 145 + kenter("%d,%s,%p", key->serial, callout_info, aux); 168 146 169 - /* create a key and add it to the queue */ 170 - key = key_alloc(type, description, 171 - current->fsuid, current->fsgid, current, KEY_POS_ALL, 172 - flags); 173 - if (IS_ERR(key)) 174 - goto alloc_failed; 175 - 176 - set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); 177 - 178 - cons.key = key; 179 - list_add_tail(&cons.link, &key->user->consq); 180 - 181 - /* we drop the construction sem here on behalf of the caller */ 182 - up_write(&key_construction_sem); 147 + cons = kmalloc(sizeof(*cons), GFP_KERNEL); 148 + if (!cons) 149 + return -ENOMEM; 183 150 184 151 /* allocate an authorisation key */ 185 152 authkey = request_key_auth_new(key, callout_info); 186 153 if (IS_ERR(authkey)) { 154 + kfree(cons); 187 155 ret = PTR_ERR(authkey); 188 156 authkey = NULL; 189 - goto alloc_authkey_failed; 157 + } else { 158 + cons->authkey = key_get(authkey); 159 + cons->key = key_get(key); 160 + 161 + /* make the call */ 162 + actor = call_sbin_request_key; 163 + if (key->type->request_key) 164 + actor = key->type->request_key; 165 + 166 + ret = actor(cons, "create", aux); 167 + 168 + /* check that the actor called complete_request_key() prior to 169 + * returning an error */ 170 + WARN_ON(ret < 0 && 171 + !test_bit(KEY_FLAG_REVOKED, &authkey->flags)); 172 + key_put(authkey); 190 173 } 191 174 192 - /* make the call */ 193 - actor = call_sbin_request_key; 194 - if (type->request_key) 195 - actor = type->request_key; 196 - ret = actor(key, authkey, "create", aux); 197 - if (ret < 0) 198 - goto request_failed; 175 + kleave(" = %d", ret); 176 + return ret; 177 + } 199 178 200 - /* if the key wasn't instantiated, then we want to give an error */ 201 - ret = -ENOKEY; 202 - if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) 203 - goto request_failed; 204 - 205 - key_revoke(authkey); 206 - key_put(authkey); 207 - 208 - down_write(&key_construction_sem); 209 - list_del(&cons.link); 210 - up_write(&key_construction_sem); 211 - 212 - /* also give an error if the key was negatively instantiated */ 213 - check_not_negative: 214 - if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { 215 - key_put(key); 216 - key = ERR_PTR(-ENOKEY); 217 - } 218 - 219 - out: 220 - kleave(" = %p", key); 221 - return key; 222 - 223 - request_failed: 224 - key_revoke(authkey); 225 - key_put(authkey); 226 - 227 - alloc_authkey_failed: 228 - /* it wasn't instantiated 229 - * - remove from construction queue 230 - * - mark the key as dead 231 - */ 232 - negated = 0; 233 - down_write(&key_construction_sem); 234 - 235 - list_del(&cons.link); 236 - 237 - /* check it didn't get instantiated between the check and the down */ 238 - if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { 239 - set_bit(KEY_FLAG_NEGATIVE, &key->flags); 240 - set_bit(KEY_FLAG_INSTANTIATED, &key->flags); 241 - negated = 1; 242 - } 243 - 244 - clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); 245 - 246 - up_write(&key_construction_sem); 247 - 248 - if (!negated) 249 - goto check_not_negative; /* surprisingly, the key got 250 - * instantiated */ 251 - 252 - /* set the timeout and store in the session keyring if we can */ 253 - now = current_kernel_time(); 254 - key->expiry = now.tv_sec + key_negative_timeout; 255 - 256 - if (current->signal->session_keyring) { 257 - struct key *keyring; 258 - 259 - rcu_read_lock(); 260 - keyring = rcu_dereference(current->signal->session_keyring); 261 - atomic_inc(&keyring->usage); 262 - rcu_read_unlock(); 263 - 264 - key_link(keyring, key); 265 - key_put(keyring); 266 - } 267 - 268 - key_put(key); 269 - 270 - /* notify anyone who was waiting */ 271 - wake_up_all(&request_key_conswq); 272 - 273 - key = ERR_PTR(ret); 274 - goto out; 275 - 276 - alloc_failed: 277 - up_write(&key_construction_sem); 278 - goto out; 279 - 280 - } /* end __request_key_construction() */ 281 - 282 - /*****************************************************************************/ 283 179 /* 284 - * call out to userspace to request the key 285 - * - we check the construction queue first to see if an appropriate key is 286 - * already being constructed by userspace 180 + * link a key to the appropriate destination keyring 181 + * - the caller must hold a write lock on the destination keyring 287 182 */ 288 - static struct key *request_key_construction(struct key_type *type, 289 - const char *description, 290 - const char *callout_info, 291 - void *aux, 292 - struct key_user *user, 293 - unsigned long flags) 294 - { 295 - struct key_construction *pcons; 296 - struct key *key, *ckey; 297 - 298 - DECLARE_WAITQUEUE(myself, current); 299 - 300 - kenter("%s,%s,{%d},%s,%lx", 301 - type->name, description, user->uid, callout_info, flags); 302 - 303 - /* see if there's such a key under construction already */ 304 - down_write(&key_construction_sem); 305 - 306 - list_for_each_entry(pcons, &user->consq, link) { 307 - ckey = pcons->key; 308 - 309 - if (ckey->type != type) 310 - continue; 311 - 312 - if (type->match(ckey, description)) 313 - goto found_key_under_construction; 314 - } 315 - 316 - /* see about getting userspace to construct the key */ 317 - key = __request_key_construction(type, description, callout_info, aux, 318 - flags); 319 - error: 320 - kleave(" = %p", key); 321 - return key; 322 - 323 - /* someone else has the same key under construction 324 - * - we want to keep an eye on their key 325 - */ 326 - found_key_under_construction: 327 - atomic_inc(&ckey->usage); 328 - up_write(&key_construction_sem); 329 - 330 - /* wait for the key to be completed one way or another */ 331 - add_wait_queue(&request_key_conswq, &myself); 332 - 333 - for (;;) { 334 - set_current_state(TASK_INTERRUPTIBLE); 335 - if (!test_bit(KEY_FLAG_USER_CONSTRUCT, &ckey->flags)) 336 - break; 337 - if (signal_pending(current)) 338 - break; 339 - schedule(); 340 - } 341 - 342 - set_current_state(TASK_RUNNING); 343 - remove_wait_queue(&request_key_conswq, &myself); 344 - 345 - /* we'll need to search this process's keyrings to see if the key is 346 - * now there since we can't automatically assume it's also available 347 - * there */ 348 - key_put(ckey); 349 - ckey = NULL; 350 - 351 - key = NULL; /* request a retry */ 352 - goto error; 353 - 354 - } /* end request_key_construction() */ 355 - 356 - /*****************************************************************************/ 357 - /* 358 - * link a freshly minted key to an appropriate destination keyring 359 - */ 360 - static void request_key_link(struct key *key, struct key *dest_keyring) 183 + static void construct_key_make_link(struct key *key, struct key *dest_keyring) 361 184 { 362 185 struct task_struct *tsk = current; 363 186 struct key *drop = NULL; ··· 238 363 break; 239 364 240 365 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING: 241 - dest_keyring = current->user->session_keyring; 366 + dest_keyring = tsk->user->session_keyring; 242 367 break; 243 368 244 369 case KEY_REQKEY_DEFL_USER_KEYRING: 245 - dest_keyring = current->user->uid_keyring; 370 + dest_keyring = tsk->user->uid_keyring; 246 371 break; 247 372 248 373 case KEY_REQKEY_DEFL_GROUP_KEYRING: ··· 252 377 } 253 378 254 379 /* and attach the key to it */ 255 - key_link(dest_keyring, key); 256 - 380 + __key_link(dest_keyring, key); 257 381 key_put(drop); 258 - 259 382 kleave(""); 383 + } 260 384 261 - } /* end request_key_link() */ 385 + /* 386 + * allocate a new key in under-construction state and attempt to link it in to 387 + * the requested place 388 + * - may return a key that's already under construction instead 389 + */ 390 + static int construct_alloc_key(struct key_type *type, 391 + const char *description, 392 + struct key *dest_keyring, 393 + unsigned long flags, 394 + struct key_user *user, 395 + struct key **_key) 396 + { 397 + struct key *key; 398 + key_ref_t key_ref; 262 399 263 - /*****************************************************************************/ 400 + kenter("%s,%s,,,", type->name, description); 401 + 402 + mutex_lock(&user->cons_lock); 403 + 404 + key = key_alloc(type, description, 405 + current->fsuid, current->fsgid, current, KEY_POS_ALL, 406 + flags); 407 + if (IS_ERR(key)) 408 + goto alloc_failed; 409 + 410 + set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); 411 + 412 + if (dest_keyring) 413 + down_write(&dest_keyring->sem); 414 + 415 + /* attach the key to the destination keyring under lock, but we do need 416 + * to do another check just in case someone beat us to it whilst we 417 + * waited for locks */ 418 + mutex_lock(&key_construction_mutex); 419 + 420 + key_ref = search_process_keyrings(type, description, type->match, 421 + current); 422 + if (!IS_ERR(key_ref)) 423 + goto key_already_present; 424 + 425 + if (dest_keyring) 426 + construct_key_make_link(key, dest_keyring); 427 + 428 + mutex_unlock(&key_construction_mutex); 429 + if (dest_keyring) 430 + up_write(&dest_keyring->sem); 431 + mutex_unlock(&user->cons_lock); 432 + *_key = key; 433 + kleave(" = 0 [%d]", key_serial(key)); 434 + return 0; 435 + 436 + key_already_present: 437 + mutex_unlock(&key_construction_mutex); 438 + if (dest_keyring) 439 + up_write(&dest_keyring->sem); 440 + mutex_unlock(&user->cons_lock); 441 + key_put(key); 442 + *_key = key = key_ref_to_ptr(key_ref); 443 + kleave(" = -EINPROGRESS [%d]", key_serial(key)); 444 + return -EINPROGRESS; 445 + 446 + alloc_failed: 447 + mutex_unlock(&user->cons_lock); 448 + *_key = NULL; 449 + kleave(" = %ld", PTR_ERR(key)); 450 + return PTR_ERR(key); 451 + } 452 + 453 + /* 454 + * commence key construction 455 + */ 456 + static struct key *construct_key_and_link(struct key_type *type, 457 + const char *description, 458 + const char *callout_info, 459 + void *aux, 460 + struct key *dest_keyring, 461 + unsigned long flags) 462 + { 463 + struct key_user *user; 464 + struct key *key; 465 + int ret; 466 + 467 + user = key_user_lookup(current->fsuid); 468 + if (!user) 469 + return ERR_PTR(-ENOMEM); 470 + 471 + ret = construct_alloc_key(type, description, dest_keyring, flags, user, 472 + &key); 473 + key_user_put(user); 474 + 475 + if (ret == 0) { 476 + ret = construct_key(key, callout_info, aux); 477 + if (ret < 0) 478 + goto construction_failed; 479 + } 480 + 481 + return key; 482 + 483 + construction_failed: 484 + key_negate_and_link(key, key_negative_timeout, NULL, NULL); 485 + key_put(key); 486 + return ERR_PTR(ret); 487 + } 488 + 264 489 /* 265 490 * request a key 266 491 * - search the process's keyrings ··· 375 400 struct key *dest_keyring, 376 401 unsigned long flags) 377 402 { 378 - struct key_user *user; 379 403 struct key *key; 380 404 key_ref_t key_ref; 381 405 ··· 386 412 key_ref = search_process_keyrings(type, description, type->match, 387 413 current); 388 414 389 - kdebug("search 1: %p", key_ref); 390 - 391 415 if (!IS_ERR(key_ref)) { 392 416 key = key_ref_to_ptr(key_ref); 393 - } 394 - else if (PTR_ERR(key_ref) != -EAGAIN) { 417 + } else if (PTR_ERR(key_ref) != -EAGAIN) { 395 418 key = ERR_PTR(PTR_ERR(key_ref)); 396 - } 397 - else { 419 + } else { 398 420 /* the search failed, but the keyrings were searchable, so we 399 421 * should consult userspace if we can */ 400 422 key = ERR_PTR(-ENOKEY); 401 423 if (!callout_info) 402 424 goto error; 403 425 404 - /* - get hold of the user's construction queue */ 405 - user = key_user_lookup(current->fsuid); 406 - if (!user) 407 - goto nomem; 408 - 409 - for (;;) { 410 - if (signal_pending(current)) 411 - goto interrupted; 412 - 413 - /* ask userspace (returns NULL if it waited on a key 414 - * being constructed) */ 415 - key = request_key_construction(type, description, 416 - callout_info, aux, 417 - user, flags); 418 - if (key) 419 - break; 420 - 421 - /* someone else made the key we want, so we need to 422 - * search again as it might now be available to us */ 423 - key_ref = search_process_keyrings(type, description, 424 - type->match, 425 - current); 426 - 427 - kdebug("search 2: %p", key_ref); 428 - 429 - if (!IS_ERR(key_ref)) { 430 - key = key_ref_to_ptr(key_ref); 431 - break; 432 - } 433 - 434 - if (PTR_ERR(key_ref) != -EAGAIN) { 435 - key = ERR_PTR(PTR_ERR(key_ref)); 436 - break; 437 - } 438 - } 439 - 440 - key_user_put(user); 441 - 442 - /* link the new key into the appropriate keyring */ 443 - if (!IS_ERR(key)) 444 - request_key_link(key, dest_keyring); 426 + key = construct_key_and_link(type, description, callout_info, 427 + aux, dest_keyring, flags); 445 428 } 446 429 447 430 error: 448 431 kleave(" = %p", key); 449 432 return key; 433 + } 450 434 451 - nomem: 452 - key = ERR_PTR(-ENOMEM); 453 - goto error; 435 + /* 436 + * wait for construction of a key to complete 437 + */ 438 + int wait_for_key_construction(struct key *key, bool intr) 439 + { 440 + int ret; 454 441 455 - interrupted: 456 - key_user_put(user); 457 - key = ERR_PTR(-EINTR); 458 - goto error; 442 + ret = wait_on_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT, 443 + intr ? key_wait_bit_intr : key_wait_bit, 444 + intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); 445 + if (ret < 0) 446 + return ret; 447 + return key_validate(key); 448 + } 449 + EXPORT_SYMBOL(wait_for_key_construction); 459 450 460 - } /* end request_key_and_link() */ 461 - 462 - /*****************************************************************************/ 463 451 /* 464 452 * request a key 465 453 * - search the process's keyrings 466 454 * - check the list of keys being created or updated 467 455 * - call out to userspace for a key if supplementary info was provided 456 + * - waits uninterruptible for creation to complete 468 457 */ 469 458 struct key *request_key(struct key_type *type, 470 459 const char *description, 471 460 const char *callout_info) 472 461 { 473 - return request_key_and_link(type, description, callout_info, NULL, 474 - NULL, KEY_ALLOC_IN_QUOTA); 462 + struct key *key; 463 + int ret; 475 464 476 - } /* end request_key() */ 477 - 465 + key = request_key_and_link(type, description, callout_info, NULL, 466 + NULL, KEY_ALLOC_IN_QUOTA); 467 + if (!IS_ERR(key)) { 468 + ret = wait_for_key_construction(key, false); 469 + if (ret < 0) { 470 + key_put(key); 471 + return ERR_PTR(ret); 472 + } 473 + } 474 + return key; 475 + } 478 476 EXPORT_SYMBOL(request_key); 479 477 480 - /*****************************************************************************/ 481 478 /* 482 479 * request a key with auxiliary data for the upcaller 483 480 * - search the process's keyrings 484 481 * - check the list of keys being created or updated 485 482 * - call out to userspace for a key if supplementary info was provided 483 + * - waits uninterruptible for creation to complete 486 484 */ 487 485 struct key *request_key_with_auxdata(struct key_type *type, 488 486 const char *description, 489 487 const char *callout_info, 490 488 void *aux) 491 489 { 490 + struct key *key; 491 + int ret; 492 + 493 + key = request_key_and_link(type, description, callout_info, aux, 494 + NULL, KEY_ALLOC_IN_QUOTA); 495 + if (!IS_ERR(key)) { 496 + ret = wait_for_key_construction(key, false); 497 + if (ret < 0) { 498 + key_put(key); 499 + return ERR_PTR(ret); 500 + } 501 + } 502 + return key; 503 + } 504 + EXPORT_SYMBOL(request_key_with_auxdata); 505 + 506 + /* 507 + * request a key (allow async construction) 508 + * - search the process's keyrings 509 + * - check the list of keys being created or updated 510 + * - call out to userspace for a key if supplementary info was provided 511 + */ 512 + struct key *request_key_async(struct key_type *type, 513 + const char *description, 514 + const char *callout_info) 515 + { 516 + return request_key_and_link(type, description, callout_info, NULL, 517 + NULL, KEY_ALLOC_IN_QUOTA); 518 + } 519 + EXPORT_SYMBOL(request_key_async); 520 + 521 + /* 522 + * request a key with auxiliary data for the upcaller (allow async construction) 523 + * - search the process's keyrings 524 + * - check the list of keys being created or updated 525 + * - call out to userspace for a key if supplementary info was provided 526 + */ 527 + struct key *request_key_async_with_auxdata(struct key_type *type, 528 + const char *description, 529 + const char *callout_info, 530 + void *aux) 531 + { 492 532 return request_key_and_link(type, description, callout_info, aux, 493 533 NULL, KEY_ALLOC_IN_QUOTA); 494 - 495 - } /* end request_key_with_auxdata() */ 496 - 497 - EXPORT_SYMBOL(request_key_with_auxdata); 534 + } 535 + EXPORT_SYMBOL(request_key_async_with_auxdata);
+10 -1
security/keys/request_key_auth.c
··· 127 127 } 128 128 129 129 key_put(rka->target_key); 130 + kfree(rka->callout_info); 130 131 kfree(rka); 131 132 132 133 } /* end request_key_auth_destroy() */ ··· 150 149 rka = kmalloc(sizeof(*rka), GFP_KERNEL); 151 150 if (!rka) { 152 151 kleave(" = -ENOMEM"); 152 + return ERR_PTR(-ENOMEM); 153 + } 154 + rka->callout_info = kmalloc(strlen(callout_info) + 1, GFP_KERNEL); 155 + if (!rka->callout_info) { 156 + kleave(" = -ENOMEM"); 157 + kfree(rka); 153 158 return ERR_PTR(-ENOMEM); 154 159 } 155 160 ··· 186 179 } 187 180 188 181 rka->target_key = key_get(target); 189 - rka->callout_info = callout_info; 182 + strcpy(rka->callout_info, callout_info); 190 183 191 184 /* allocate the auth key */ 192 185 sprintf(desc, "%x", target->serial); ··· 210 203 211 204 auth_key_revoked: 212 205 up_read(&current->request_key_auth->sem); 206 + kfree(rka->callout_info); 213 207 kfree(rka); 214 208 kleave("= -EKEYREVOKED"); 215 209 return ERR_PTR(-EKEYREVOKED); ··· 220 212 key_put(authkey); 221 213 error_alloc: 222 214 key_put(rka->target_key); 215 + kfree(rka->callout_info); 223 216 kfree(rka); 224 217 kleave("= %d", ret); 225 218 return ERR_PTR(ret);