ima_fs.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /*
  2. * Copyright (C) 2005,2006,2007,2008 IBM Corporation
  3. *
  4. * Authors:
  5. * Kylene Hall <kjhall@us.ibm.com>
  6. * Reiner Sailer <sailer@us.ibm.com>
  7. * Mimi Zohar <zohar@us.ibm.com>
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation, version 2 of the
  12. * License.
  13. *
  14. * File: ima_fs.c
  15. * implemenents security file system for reporting
  16. * current measurement list and IMA statistics
  17. */
  18. #include <linux/module.h>
  19. #include <linux/seq_file.h>
  20. #include <linux/rculist.h>
  21. #include <linux/rcupdate.h>
  22. #include <linux/parser.h>
  23. #include "ima.h"
  24. static int valid_policy = 1;
  25. #define TMPBUFLEN 12
  26. static ssize_t ima_show_htable_value(char __user *buf, size_t count,
  27. loff_t *ppos, atomic_long_t *val)
  28. {
  29. char tmpbuf[TMPBUFLEN];
  30. ssize_t len;
  31. len = scnprintf(tmpbuf, TMPBUFLEN, "%li\n", atomic_long_read(val));
  32. return simple_read_from_buffer(buf, count, ppos, tmpbuf, len);
  33. }
  34. static ssize_t ima_show_htable_violations(struct file *filp,
  35. char __user *buf,
  36. size_t count, loff_t *ppos)
  37. {
  38. return ima_show_htable_value(buf, count, ppos, &ima_htable.violations);
  39. }
  40. static struct file_operations ima_htable_violations_ops = {
  41. .read = ima_show_htable_violations
  42. };
  43. static ssize_t ima_show_measurements_count(struct file *filp,
  44. char __user *buf,
  45. size_t count, loff_t *ppos)
  46. {
  47. return ima_show_htable_value(buf, count, ppos, &ima_htable.len);
  48. }
  49. static struct file_operations ima_measurements_count_ops = {
  50. .read = ima_show_measurements_count
  51. };
  52. /* returns pointer to hlist_node */
  53. static void *ima_measurements_start(struct seq_file *m, loff_t *pos)
  54. {
  55. loff_t l = *pos;
  56. struct ima_queue_entry *qe;
  57. /* we need a lock since pos could point beyond last element */
  58. rcu_read_lock();
  59. list_for_each_entry_rcu(qe, &ima_measurements, later) {
  60. if (!l--) {
  61. rcu_read_unlock();
  62. return qe;
  63. }
  64. }
  65. rcu_read_unlock();
  66. return NULL;
  67. }
  68. static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos)
  69. {
  70. struct ima_queue_entry *qe = v;
  71. /* lock protects when reading beyond last element
  72. * against concurrent list-extension
  73. */
  74. rcu_read_lock();
  75. qe = list_entry(rcu_dereference(qe->later.next),
  76. struct ima_queue_entry, later);
  77. rcu_read_unlock();
  78. (*pos)++;
  79. return (&qe->later == &ima_measurements) ? NULL : qe;
  80. }
  81. static void ima_measurements_stop(struct seq_file *m, void *v)
  82. {
  83. }
  84. static void ima_putc(struct seq_file *m, void *data, int datalen)
  85. {
  86. while (datalen--)
  87. seq_putc(m, *(char *)data++);
  88. }
  89. /* print format:
  90. * 32bit-le=pcr#
  91. * char[20]=template digest
  92. * 32bit-le=template name size
  93. * char[n]=template name
  94. * eventdata[n]=template specific data
  95. */
  96. static int ima_measurements_show(struct seq_file *m, void *v)
  97. {
  98. /* the list never shrinks, so we don't need a lock here */
  99. struct ima_queue_entry *qe = v;
  100. struct ima_template_entry *e;
  101. int namelen;
  102. u32 pcr = CONFIG_IMA_MEASURE_PCR_IDX;
  103. /* get entry */
  104. e = qe->entry;
  105. if (e == NULL)
  106. return -1;
  107. /*
  108. * 1st: PCRIndex
  109. * PCR used is always the same (config option) in
  110. * little-endian format
  111. */
  112. ima_putc(m, &pcr, sizeof pcr);
  113. /* 2nd: template digest */
  114. ima_putc(m, e->digest, IMA_DIGEST_SIZE);
  115. /* 3rd: template name size */
  116. namelen = strlen(e->template_name);
  117. ima_putc(m, &namelen, sizeof namelen);
  118. /* 4th: template name */
  119. ima_putc(m, (void *)e->template_name, namelen);
  120. /* 5th: template specific data */
  121. ima_template_show(m, (struct ima_template_data *)&e->template,
  122. IMA_SHOW_BINARY);
  123. return 0;
  124. }
  125. static struct seq_operations ima_measurments_seqops = {
  126. .start = ima_measurements_start,
  127. .next = ima_measurements_next,
  128. .stop = ima_measurements_stop,
  129. .show = ima_measurements_show
  130. };
  131. static int ima_measurements_open(struct inode *inode, struct file *file)
  132. {
  133. return seq_open(file, &ima_measurments_seqops);
  134. }
  135. static struct file_operations ima_measurements_ops = {
  136. .open = ima_measurements_open,
  137. .read = seq_read,
  138. .llseek = seq_lseek,
  139. .release = seq_release,
  140. };
  141. static void ima_print_digest(struct seq_file *m, u8 *digest)
  142. {
  143. int i;
  144. for (i = 0; i < IMA_DIGEST_SIZE; i++)
  145. seq_printf(m, "%02x", *(digest + i));
  146. }
  147. void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show)
  148. {
  149. struct ima_template_data *entry = e;
  150. int namelen;
  151. switch (show) {
  152. case IMA_SHOW_ASCII:
  153. ima_print_digest(m, entry->digest);
  154. seq_printf(m, " %s\n", entry->file_name);
  155. break;
  156. case IMA_SHOW_BINARY:
  157. ima_putc(m, entry->digest, IMA_DIGEST_SIZE);
  158. namelen = strlen(entry->file_name);
  159. ima_putc(m, &namelen, sizeof namelen);
  160. ima_putc(m, entry->file_name, namelen);
  161. default:
  162. break;
  163. }
  164. }
  165. /* print in ascii */
  166. static int ima_ascii_measurements_show(struct seq_file *m, void *v)
  167. {
  168. /* the list never shrinks, so we don't need a lock here */
  169. struct ima_queue_entry *qe = v;
  170. struct ima_template_entry *e;
  171. /* get entry */
  172. e = qe->entry;
  173. if (e == NULL)
  174. return -1;
  175. /* 1st: PCR used (config option) */
  176. seq_printf(m, "%2d ", CONFIG_IMA_MEASURE_PCR_IDX);
  177. /* 2nd: SHA1 template hash */
  178. ima_print_digest(m, e->digest);
  179. /* 3th: template name */
  180. seq_printf(m, " %s ", e->template_name);
  181. /* 4th: template specific data */
  182. ima_template_show(m, (struct ima_template_data *)&e->template,
  183. IMA_SHOW_ASCII);
  184. return 0;
  185. }
  186. static struct seq_operations ima_ascii_measurements_seqops = {
  187. .start = ima_measurements_start,
  188. .next = ima_measurements_next,
  189. .stop = ima_measurements_stop,
  190. .show = ima_ascii_measurements_show
  191. };
  192. static int ima_ascii_measurements_open(struct inode *inode, struct file *file)
  193. {
  194. return seq_open(file, &ima_ascii_measurements_seqops);
  195. }
  196. static struct file_operations ima_ascii_measurements_ops = {
  197. .open = ima_ascii_measurements_open,
  198. .read = seq_read,
  199. .llseek = seq_lseek,
  200. .release = seq_release,
  201. };
  202. static ssize_t ima_write_policy(struct file *file, const char __user *buf,
  203. size_t datalen, loff_t *ppos)
  204. {
  205. char *data;
  206. int rc;
  207. if (datalen >= PAGE_SIZE)
  208. return -ENOMEM;
  209. if (*ppos != 0) {
  210. /* No partial writes. */
  211. return -EINVAL;
  212. }
  213. data = kmalloc(datalen + 1, GFP_KERNEL);
  214. if (!data)
  215. return -ENOMEM;
  216. if (copy_from_user(data, buf, datalen)) {
  217. kfree(data);
  218. return -EFAULT;
  219. }
  220. *(data + datalen) = '\0';
  221. rc = ima_parse_add_rule(data);
  222. if (rc < 0) {
  223. datalen = -EINVAL;
  224. valid_policy = 0;
  225. }
  226. kfree(data);
  227. return datalen;
  228. }
  229. static struct dentry *ima_dir;
  230. static struct dentry *binary_runtime_measurements;
  231. static struct dentry *ascii_runtime_measurements;
  232. static struct dentry *runtime_measurements_count;
  233. static struct dentry *violations;
  234. static struct dentry *ima_policy;
  235. static atomic_t policy_opencount = ATOMIC_INIT(1);
  236. /*
  237. * ima_open_policy: sequentialize access to the policy file
  238. */
  239. int ima_open_policy(struct inode * inode, struct file * filp)
  240. {
  241. if (atomic_dec_and_test(&policy_opencount))
  242. return 0;
  243. return -EBUSY;
  244. }
  245. /*
  246. * ima_release_policy - start using the new measure policy rules.
  247. *
  248. * Initially, ima_measure points to the default policy rules, now
  249. * point to the new policy rules, and remove the securityfs policy file,
  250. * assuming a valid policy.
  251. */
  252. static int ima_release_policy(struct inode *inode, struct file *file)
  253. {
  254. if (!valid_policy) {
  255. ima_delete_rules();
  256. valid_policy = 1;
  257. atomic_set(&policy_opencount, 1);
  258. return 0;
  259. }
  260. ima_update_policy();
  261. securityfs_remove(ima_policy);
  262. ima_policy = NULL;
  263. return 0;
  264. }
  265. static struct file_operations ima_measure_policy_ops = {
  266. .open = ima_open_policy,
  267. .write = ima_write_policy,
  268. .release = ima_release_policy
  269. };
  270. int ima_fs_init(void)
  271. {
  272. ima_dir = securityfs_create_dir("ima", NULL);
  273. if (IS_ERR(ima_dir))
  274. return -1;
  275. binary_runtime_measurements =
  276. securityfs_create_file("binary_runtime_measurements",
  277. S_IRUSR | S_IRGRP, ima_dir, NULL,
  278. &ima_measurements_ops);
  279. if (IS_ERR(binary_runtime_measurements))
  280. goto out;
  281. ascii_runtime_measurements =
  282. securityfs_create_file("ascii_runtime_measurements",
  283. S_IRUSR | S_IRGRP, ima_dir, NULL,
  284. &ima_ascii_measurements_ops);
  285. if (IS_ERR(ascii_runtime_measurements))
  286. goto out;
  287. runtime_measurements_count =
  288. securityfs_create_file("runtime_measurements_count",
  289. S_IRUSR | S_IRGRP, ima_dir, NULL,
  290. &ima_measurements_count_ops);
  291. if (IS_ERR(runtime_measurements_count))
  292. goto out;
  293. violations =
  294. securityfs_create_file("violations", S_IRUSR | S_IRGRP,
  295. ima_dir, NULL, &ima_htable_violations_ops);
  296. if (IS_ERR(violations))
  297. goto out;
  298. ima_policy = securityfs_create_file("policy",
  299. S_IRUSR | S_IRGRP | S_IWUSR,
  300. ima_dir, NULL,
  301. &ima_measure_policy_ops);
  302. if (IS_ERR(ima_policy))
  303. goto out;
  304. return 0;
  305. out:
  306. securityfs_remove(runtime_measurements_count);
  307. securityfs_remove(ascii_runtime_measurements);
  308. securityfs_remove(binary_runtime_measurements);
  309. securityfs_remove(ima_dir);
  310. securityfs_remove(ima_policy);
  311. return -1;
  312. }
  313. void __exit ima_fs_cleanup(void)
  314. {
  315. securityfs_remove(violations);
  316. securityfs_remove(runtime_measurements_count);
  317. securityfs_remove(ascii_runtime_measurements);
  318. securityfs_remove(binary_runtime_measurements);
  319. securityfs_remove(ima_dir);
  320. securityfs_remove(ima_policy);
  321. }