PageRenderTime 27ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/security/keys/request_key_auth.c

https://github.com/genesi/linux-shortbus
C | 264 lines | 171 code | 39 blank | 54 comment | 17 complexity | 3154c9a40589c2ba62ac876f3b784430 MD5 | raw file
  1. /* Request key authorisation token key definition.
  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. #include <linux/module.h>
  14. #include <linux/sched.h>
  15. #include <linux/err.h>
  16. #include <linux/seq_file.h>
  17. #include <linux/slab.h>
  18. #include <asm/uaccess.h>
  19. #include "internal.h"
  20. static int request_key_auth_instantiate(struct key *, const void *, size_t);
  21. static void request_key_auth_describe(const struct key *, struct seq_file *);
  22. static void request_key_auth_revoke(struct key *);
  23. static void request_key_auth_destroy(struct key *);
  24. static long request_key_auth_read(const struct key *, char __user *, size_t);
  25. /*
  26. * The request-key authorisation key type definition.
  27. */
  28. struct key_type key_type_request_key_auth = {
  29. .name = ".request_key_auth",
  30. .def_datalen = sizeof(struct request_key_auth),
  31. .instantiate = request_key_auth_instantiate,
  32. .describe = request_key_auth_describe,
  33. .revoke = request_key_auth_revoke,
  34. .destroy = request_key_auth_destroy,
  35. .read = request_key_auth_read,
  36. };
  37. /*
  38. * Instantiate a request-key authorisation key.
  39. */
  40. static int request_key_auth_instantiate(struct key *key,
  41. const void *data,
  42. size_t datalen)
  43. {
  44. key->payload.data = (struct request_key_auth *) data;
  45. return 0;
  46. }
  47. /*
  48. * Describe an authorisation token.
  49. */
  50. static void request_key_auth_describe(const struct key *key,
  51. struct seq_file *m)
  52. {
  53. struct request_key_auth *rka = key->payload.data;
  54. seq_puts(m, "key:");
  55. seq_puts(m, key->description);
  56. seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
  57. }
  58. /*
  59. * Read the callout_info data (retrieves the callout information).
  60. * - the key's semaphore is read-locked
  61. */
  62. static long request_key_auth_read(const struct key *key,
  63. char __user *buffer, size_t buflen)
  64. {
  65. struct request_key_auth *rka = key->payload.data;
  66. size_t datalen;
  67. long ret;
  68. datalen = rka->callout_len;
  69. ret = datalen;
  70. /* we can return the data as is */
  71. if (buffer && buflen > 0) {
  72. if (buflen > datalen)
  73. buflen = datalen;
  74. if (copy_to_user(buffer, rka->callout_info, buflen) != 0)
  75. ret = -EFAULT;
  76. }
  77. return ret;
  78. }
  79. /*
  80. * Handle revocation of an authorisation token key.
  81. *
  82. * Called with the key sem write-locked.
  83. */
  84. static void request_key_auth_revoke(struct key *key)
  85. {
  86. struct request_key_auth *rka = key->payload.data;
  87. kenter("{%d}", key->serial);
  88. if (rka->cred) {
  89. put_cred(rka->cred);
  90. rka->cred = NULL;
  91. }
  92. }
  93. /*
  94. * Destroy an instantiation authorisation token key.
  95. */
  96. static void request_key_auth_destroy(struct key *key)
  97. {
  98. struct request_key_auth *rka = key->payload.data;
  99. kenter("{%d}", key->serial);
  100. if (rka->cred) {
  101. put_cred(rka->cred);
  102. rka->cred = NULL;
  103. }
  104. key_put(rka->target_key);
  105. key_put(rka->dest_keyring);
  106. kfree(rka->callout_info);
  107. kfree(rka);
  108. }
  109. /*
  110. * Create an authorisation token for /sbin/request-key or whoever to gain
  111. * access to the caller's security data.
  112. */
  113. struct key *request_key_auth_new(struct key *target, const void *callout_info,
  114. size_t callout_len, struct key *dest_keyring)
  115. {
  116. struct request_key_auth *rka, *irka;
  117. const struct cred *cred = current->cred;
  118. struct key *authkey = NULL;
  119. char desc[20];
  120. int ret;
  121. kenter("%d,", target->serial);
  122. /* allocate a auth record */
  123. rka = kmalloc(sizeof(*rka), GFP_KERNEL);
  124. if (!rka) {
  125. kleave(" = -ENOMEM");
  126. return ERR_PTR(-ENOMEM);
  127. }
  128. rka->callout_info = kmalloc(callout_len, GFP_KERNEL);
  129. if (!rka->callout_info) {
  130. kleave(" = -ENOMEM");
  131. kfree(rka);
  132. return ERR_PTR(-ENOMEM);
  133. }
  134. /* see if the calling process is already servicing the key request of
  135. * another process */
  136. if (cred->request_key_auth) {
  137. /* it is - use that instantiation context here too */
  138. down_read(&cred->request_key_auth->sem);
  139. /* if the auth key has been revoked, then the key we're
  140. * servicing is already instantiated */
  141. if (test_bit(KEY_FLAG_REVOKED, &cred->request_key_auth->flags))
  142. goto auth_key_revoked;
  143. irka = cred->request_key_auth->payload.data;
  144. rka->cred = get_cred(irka->cred);
  145. rka->pid = irka->pid;
  146. up_read(&cred->request_key_auth->sem);
  147. }
  148. else {
  149. /* it isn't - use this process as the context */
  150. rka->cred = get_cred(cred);
  151. rka->pid = current->pid;
  152. }
  153. rka->target_key = key_get(target);
  154. rka->dest_keyring = key_get(dest_keyring);
  155. memcpy(rka->callout_info, callout_info, callout_len);
  156. rka->callout_len = callout_len;
  157. /* allocate the auth key */
  158. sprintf(desc, "%x", target->serial);
  159. authkey = key_alloc(&key_type_request_key_auth, desc,
  160. cred->fsuid, cred->fsgid, cred,
  161. KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
  162. KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA);
  163. if (IS_ERR(authkey)) {
  164. ret = PTR_ERR(authkey);
  165. goto error_alloc;
  166. }
  167. /* construct the auth key */
  168. ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
  169. if (ret < 0)
  170. goto error_inst;
  171. kleave(" = {%d,%d}", authkey->serial, atomic_read(&authkey->usage));
  172. return authkey;
  173. auth_key_revoked:
  174. up_read(&cred->request_key_auth->sem);
  175. kfree(rka->callout_info);
  176. kfree(rka);
  177. kleave("= -EKEYREVOKED");
  178. return ERR_PTR(-EKEYREVOKED);
  179. error_inst:
  180. key_revoke(authkey);
  181. key_put(authkey);
  182. error_alloc:
  183. key_put(rka->target_key);
  184. key_put(rka->dest_keyring);
  185. kfree(rka->callout_info);
  186. kfree(rka);
  187. kleave("= %d", ret);
  188. return ERR_PTR(ret);
  189. }
  190. /*
  191. * See if an authorisation key is associated with a particular key.
  192. */
  193. static int key_get_instantiation_authkey_match(const struct key *key,
  194. const void *_id)
  195. {
  196. struct request_key_auth *rka = key->payload.data;
  197. key_serial_t id = (key_serial_t)(unsigned long) _id;
  198. return rka->target_key->serial == id;
  199. }
  200. /*
  201. * Search the current process's keyrings for the authorisation key for
  202. * instantiation of a key.
  203. */
  204. struct key *key_get_instantiation_authkey(key_serial_t target_id)
  205. {
  206. const struct cred *cred = current_cred();
  207. struct key *authkey;
  208. key_ref_t authkey_ref;
  209. authkey_ref = search_process_keyrings(
  210. &key_type_request_key_auth,
  211. (void *) (unsigned long) target_id,
  212. key_get_instantiation_authkey_match,
  213. cred);
  214. if (IS_ERR(authkey_ref)) {
  215. authkey = ERR_CAST(authkey_ref);
  216. goto error;
  217. }
  218. authkey = key_ref_to_ptr(authkey_ref);
  219. if (test_bit(KEY_FLAG_REVOKED, &authkey->flags)) {
  220. key_put(authkey);
  221. authkey = ERR_PTR(-EKEYREVOKED);
  222. }
  223. error:
  224. return authkey;
  225. }