big_key.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /* Large capacity key type
  2. *
  3. * Copyright (C) 2013 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. #include <linux/module.h>
  12. #include <linux/init.h>
  13. #include <linux/seq_file.h>
  14. #include <linux/file.h>
  15. #include <linux/shmem_fs.h>
  16. #include <linux/err.h>
  17. #include <keys/user-type.h>
  18. #include <keys/big_key-type.h>
  19. MODULE_LICENSE("GPL");
  20. /*
  21. * If the data is under this limit, there's no point creating a shm file to
  22. * hold it as the permanently resident metadata for the shmem fs will be at
  23. * least as large as the data.
  24. */
  25. #define BIG_KEY_FILE_THRESHOLD (sizeof(struct inode) + sizeof(struct dentry))
  26. /*
  27. * big_key defined keys take an arbitrary string as the description and an
  28. * arbitrary blob of data as the payload
  29. */
  30. struct key_type key_type_big_key = {
  31. .name = "big_key",
  32. .preparse = big_key_preparse,
  33. .free_preparse = big_key_free_preparse,
  34. .instantiate = generic_key_instantiate,
  35. .revoke = big_key_revoke,
  36. .destroy = big_key_destroy,
  37. .describe = big_key_describe,
  38. .read = big_key_read,
  39. };
  40. /*
  41. * Preparse a big key
  42. */
  43. int big_key_preparse(struct key_preparsed_payload *prep)
  44. {
  45. struct path *path = (struct path *)&prep->payload;
  46. struct file *file;
  47. ssize_t written;
  48. size_t datalen = prep->datalen;
  49. int ret;
  50. ret = -EINVAL;
  51. if (datalen <= 0 || datalen > 1024 * 1024 || !prep->data)
  52. goto error;
  53. /* Set an arbitrary quota */
  54. prep->quotalen = 16;
  55. prep->type_data[1] = (void *)(unsigned long)datalen;
  56. if (datalen > BIG_KEY_FILE_THRESHOLD) {
  57. /* Create a shmem file to store the data in. This will permit the data
  58. * to be swapped out if needed.
  59. *
  60. * TODO: Encrypt the stored data with a temporary key.
  61. */
  62. file = shmem_kernel_file_setup("", datalen, 0);
  63. if (IS_ERR(file)) {
  64. ret = PTR_ERR(file);
  65. goto error;
  66. }
  67. written = kernel_write(file, prep->data, prep->datalen, 0);
  68. if (written != datalen) {
  69. ret = written;
  70. if (written >= 0)
  71. ret = -ENOMEM;
  72. goto err_fput;
  73. }
  74. /* Pin the mount and dentry to the key so that we can open it again
  75. * later
  76. */
  77. *path = file->f_path;
  78. path_get(path);
  79. fput(file);
  80. } else {
  81. /* Just store the data in a buffer */
  82. void *data = kmalloc(datalen, GFP_KERNEL);
  83. if (!data)
  84. return -ENOMEM;
  85. prep->payload[0] = memcpy(data, prep->data, prep->datalen);
  86. }
  87. return 0;
  88. err_fput:
  89. fput(file);
  90. error:
  91. return ret;
  92. }
  93. /*
  94. * Clear preparsement.
  95. */
  96. void big_key_free_preparse(struct key_preparsed_payload *prep)
  97. {
  98. if (prep->datalen > BIG_KEY_FILE_THRESHOLD) {
  99. struct path *path = (struct path *)&prep->payload;
  100. path_put(path);
  101. } else {
  102. kfree(prep->payload[0]);
  103. }
  104. }
  105. /*
  106. * dispose of the links from a revoked keyring
  107. * - called with the key sem write-locked
  108. */
  109. void big_key_revoke(struct key *key)
  110. {
  111. struct path *path = (struct path *)&key->payload.data2;
  112. /* clear the quota */
  113. key_payload_reserve(key, 0);
  114. if (key_is_instantiated(key) && key->type_data.x[1] > BIG_KEY_FILE_THRESHOLD)
  115. vfs_truncate(path, 0);
  116. }
  117. /*
  118. * dispose of the data dangling from the corpse of a big_key key
  119. */
  120. void big_key_destroy(struct key *key)
  121. {
  122. if (key->type_data.x[1] > BIG_KEY_FILE_THRESHOLD) {
  123. struct path *path = (struct path *)&key->payload.data2;
  124. path_put(path);
  125. path->mnt = NULL;
  126. path->dentry = NULL;
  127. } else {
  128. kfree(key->payload.data);
  129. key->payload.data = NULL;
  130. }
  131. }
  132. /*
  133. * describe the big_key key
  134. */
  135. void big_key_describe(const struct key *key, struct seq_file *m)
  136. {
  137. unsigned long datalen = key->type_data.x[1];
  138. seq_puts(m, key->description);
  139. if (key_is_instantiated(key))
  140. seq_printf(m, ": %lu [%s]",
  141. datalen,
  142. datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff");
  143. }
  144. /*
  145. * read the key data
  146. * - the key's semaphore is read-locked
  147. */
  148. long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
  149. {
  150. unsigned long datalen = key->type_data.x[1];
  151. long ret;
  152. if (!buffer || buflen < datalen)
  153. return datalen;
  154. if (datalen > BIG_KEY_FILE_THRESHOLD) {
  155. struct path *path = (struct path *)&key->payload.data2;
  156. struct file *file;
  157. loff_t pos;
  158. file = dentry_open(path, O_RDONLY, current_cred());
  159. if (IS_ERR(file))
  160. return PTR_ERR(file);
  161. pos = 0;
  162. ret = vfs_read(file, buffer, datalen, &pos);
  163. fput(file);
  164. if (ret >= 0 && ret != datalen)
  165. ret = -EIO;
  166. } else {
  167. ret = datalen;
  168. if (copy_to_user(buffer, key->payload.data, datalen) != 0)
  169. ret = -EFAULT;
  170. }
  171. return ret;
  172. }
  173. /*
  174. * Module stuff
  175. */
  176. static int __init big_key_init(void)
  177. {
  178. return register_key_type(&key_type_big_key);
  179. }
  180. static void __exit big_key_cleanup(void)
  181. {
  182. unregister_key_type(&key_type_big_key);
  183. }
  184. module_init(big_key_init);
  185. module_exit(big_key_cleanup);