1 /* request_key_auth.c: request key authorisation controlling key def 2 * 3 * Copyright (C) 2005 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 * See Documentation/keys-request-key.txt 12 */ 13 14 #include <linux/module.h> 15 #include <linux/sched.h> 16 #include <linux/err.h> 17 #include <linux/seq_file.h> 18 #include <linux/slab.h> 19 #include <asm/uaccess.h> 20 #include "internal.h" 21 22 static int request_key_auth_instantiate(struct key *, const void *, size_t); 23 static void request_key_auth_describe(const struct key *, struct seq_file *); 24 static void request_key_auth_revoke(struct key *); 25 static void request_key_auth_destroy(struct key *); 26 static long request_key_auth_read(const struct key *, char __user *, size_t); 27 28 /* 29 * the request-key authorisation key type definition 30 */ 31 struct key_type key_type_request_key_auth = { 32 .name = ".request_key_auth", 33 .def_datalen = sizeof(struct request_key_auth), 34 .instantiate = request_key_auth_instantiate, 35 .describe = request_key_auth_describe, 36 .revoke = request_key_auth_revoke, 37 .destroy = request_key_auth_destroy, 38 .read = request_key_auth_read, 39 }; 40 41 /*****************************************************************************/ 42 /* 43 * instantiate a request-key authorisation key 44 */ 45 static int request_key_auth_instantiate(struct key *key, 46 const void *data, 47 size_t datalen) 48 { 49 key->payload.data = (struct request_key_auth *) data; 50 return 0; 51 52 } /* end request_key_auth_instantiate() */ 53 54 /*****************************************************************************/ 55 /* 56 * reading a request-key authorisation key retrieves the callout information 57 */ 58 static void request_key_auth_describe(const struct key *key, 59 struct seq_file *m) 60 { 61 struct request_key_auth *rka = key->payload.data; 62 63 seq_puts(m, "key:"); 64 seq_puts(m, key->description); 65 seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len); 66 67 } /* end request_key_auth_describe() */ 68 69 /*****************************************************************************/ 70 /* 71 * read the callout_info data 72 * - the key's semaphore is read-locked 73 */ 74 static long request_key_auth_read(const struct key *key, 75 char __user *buffer, size_t buflen) 76 { 77 struct request_key_auth *rka = key->payload.data; 78 size_t datalen; 79 long ret; 80 81 datalen = rka->callout_len; 82 ret = datalen; 83 84 /* we can return the data as is */ 85 if (buffer && buflen > 0) { 86 if (buflen > datalen) 87 buflen = datalen; 88 89 if (copy_to_user(buffer, rka->callout_info, buflen) != 0) 90 ret = -EFAULT; 91 } 92 93 return ret; 94 95 } /* end request_key_auth_read() */ 96 97 /*****************************************************************************/ 98 /* 99 * handle revocation of an authorisation token key 100 * - called with the key sem write-locked 101 */ 102 static void request_key_auth_revoke(struct key *key) 103 { 104 struct request_key_auth *rka = key->payload.data; 105 106 kenter("{%d}", key->serial); 107 108 if (rka->context) { 109 put_task_struct(rka->context); 110 rka->context = NULL; 111 } 112 113 } /* end request_key_auth_revoke() */ 114 115 /*****************************************************************************/ 116 /* 117 * destroy an instantiation authorisation token key 118 */ 119 static void request_key_auth_destroy(struct key *key) 120 { 121 struct request_key_auth *rka = key->payload.data; 122 123 kenter("{%d}", key->serial); 124 125 if (rka->context) { 126 put_task_struct(rka->context); 127 rka->context = NULL; 128 } 129 130 key_put(rka->target_key); 131 kfree(rka->callout_info); 132 kfree(rka); 133 134 } /* end request_key_auth_destroy() */ 135 136 /*****************************************************************************/ 137 /* 138 * create an authorisation token for /sbin/request-key or whoever to gain 139 * access to the caller's security data 140 */ 141 struct key *request_key_auth_new(struct key *target, const void *callout_info, 142 size_t callout_len) 143 { 144 struct request_key_auth *rka, *irka; 145 struct key *authkey = NULL; 146 char desc[20]; 147 int ret; 148 149 kenter("%d,", target->serial); 150 151 /* allocate a auth record */ 152 rka = kmalloc(sizeof(*rka), GFP_KERNEL); 153 if (!rka) { 154 kleave(" = -ENOMEM"); 155 return ERR_PTR(-ENOMEM); 156 } 157 rka->callout_info = kmalloc(callout_len, GFP_KERNEL); 158 if (!rka->callout_info) { 159 kleave(" = -ENOMEM"); 160 kfree(rka); 161 return ERR_PTR(-ENOMEM); 162 } 163 164 /* see if the calling process is already servicing the key request of 165 * another process */ 166 if (current->request_key_auth) { 167 /* it is - use that instantiation context here too */ 168 down_read(¤t->request_key_auth->sem); 169 170 /* if the auth key has been revoked, then the key we're 171 * servicing is already instantiated */ 172 if (test_bit(KEY_FLAG_REVOKED, 173 ¤t->request_key_auth->flags)) 174 goto auth_key_revoked; 175 176 irka = current->request_key_auth->payload.data; 177 rka->context = irka->context; 178 rka->pid = irka->pid; 179 get_task_struct(rka->context); 180 181 up_read(¤t->request_key_auth->sem); 182 } 183 else { 184 /* it isn't - use this process as the context */ 185 rka->context = current; 186 rka->pid = current->pid; 187 get_task_struct(rka->context); 188 } 189 190 rka->target_key = key_get(target); 191 memcpy(rka->callout_info, callout_info, callout_len); 192 rka->callout_len = callout_len; 193 194 /* allocate the auth key */ 195 sprintf(desc, "%x", target->serial); 196 197 authkey = key_alloc(&key_type_request_key_auth, desc, 198 current->fsuid, current->fsgid, current, 199 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | 200 KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA); 201 if (IS_ERR(authkey)) { 202 ret = PTR_ERR(authkey); 203 goto error_alloc; 204 } 205 206 /* construct and attach to the keyring */ 207 ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL); 208 if (ret < 0) 209 goto error_inst; 210 211 kleave(" = {%d}", authkey->serial); 212 return authkey; 213 214 auth_key_revoked: 215 up_read(¤t->request_key_auth->sem); 216 kfree(rka->callout_info); 217 kfree(rka); 218 kleave("= -EKEYREVOKED"); 219 return ERR_PTR(-EKEYREVOKED); 220 221 error_inst: 222 key_revoke(authkey); 223 key_put(authkey); 224 error_alloc: 225 key_put(rka->target_key); 226 kfree(rka->callout_info); 227 kfree(rka); 228 kleave("= %d", ret); 229 return ERR_PTR(ret); 230 231 } /* end request_key_auth_new() */ 232 233 /*****************************************************************************/ 234 /* 235 * see if an authorisation key is associated with a particular key 236 */ 237 static int key_get_instantiation_authkey_match(const struct key *key, 238 const void *_id) 239 { 240 struct request_key_auth *rka = key->payload.data; 241 key_serial_t id = (key_serial_t)(unsigned long) _id; 242 243 return rka->target_key->serial == id; 244 245 } /* end key_get_instantiation_authkey_match() */ 246 247 /*****************************************************************************/ 248 /* 249 * get the authorisation key for instantiation of a specific key if attached to 250 * the current process's keyrings 251 * - this key is inserted into a keyring and that is set as /sbin/request-key's 252 * session keyring 253 * - a target_id of zero specifies any valid token 254 */ 255 struct key *key_get_instantiation_authkey(key_serial_t target_id) 256 { 257 struct key *authkey; 258 key_ref_t authkey_ref; 259 260 authkey_ref = search_process_keyrings( 261 &key_type_request_key_auth, 262 (void *) (unsigned long) target_id, 263 key_get_instantiation_authkey_match, 264 current); 265 266 if (IS_ERR(authkey_ref)) { 267 authkey = ERR_CAST(authkey_ref); 268 goto error; 269 } 270 271 authkey = key_ref_to_ptr(authkey_ref); 272 if (test_bit(KEY_FLAG_REVOKED, &authkey->flags)) { 273 key_put(authkey); 274 authkey = ERR_PTR(-EKEYREVOKED); 275 } 276 277 error: 278 return authkey; 279 280 } /* end key_get_instantiation_authkey() */ 281