fs.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved.
  4. */
  5. #include <linux/dcache.h>
  6. #include <linux/security.h>
  7. #include "ipe.h"
  8. #include "fs.h"
  9. #include "eval.h"
  10. #include "policy.h"
  11. #include "audit.h"
  12. static struct dentry *root __ro_after_init;
  13. struct dentry *policy_root __ro_after_init;
  14. /**
  15. * setaudit() - Write handler for the securityfs node, "ipe/success_audit"
  16. * @f: Supplies a file structure representing the securityfs node.
  17. * @data: Supplies a buffer passed to the write syscall.
  18. * @len: Supplies the length of @data.
  19. * @offset: unused.
  20. *
  21. * Return:
  22. * * Length of buffer written - Success
  23. * * %-EPERM - Insufficient permission
  24. */
  25. static ssize_t setaudit(struct file *f, const char __user *data,
  26. size_t len, loff_t *offset)
  27. {
  28. int rc = 0;
  29. bool value;
  30. if (!file_ns_capable(f, &init_user_ns, CAP_MAC_ADMIN))
  31. return -EPERM;
  32. rc = kstrtobool_from_user(data, len, &value);
  33. if (rc)
  34. return rc;
  35. WRITE_ONCE(success_audit, value);
  36. return len;
  37. }
  38. /**
  39. * getaudit() - Read handler for the securityfs node, "ipe/success_audit"
  40. * @f: Supplies a file structure representing the securityfs node.
  41. * @data: Supplies a buffer passed to the read syscall.
  42. * @len: Supplies the length of @data.
  43. * @offset: unused.
  44. *
  45. * Return: Length of buffer written
  46. */
  47. static ssize_t getaudit(struct file *f, char __user *data,
  48. size_t len, loff_t *offset)
  49. {
  50. const char *result;
  51. result = ((READ_ONCE(success_audit)) ? "1" : "0");
  52. return simple_read_from_buffer(data, len, offset, result, 1);
  53. }
  54. /**
  55. * setenforce() - Write handler for the securityfs node, "ipe/enforce"
  56. * @f: Supplies a file structure representing the securityfs node.
  57. * @data: Supplies a buffer passed to the write syscall.
  58. * @len: Supplies the length of @data.
  59. * @offset: unused.
  60. *
  61. * Return:
  62. * * Length of buffer written - Success
  63. * * %-EPERM - Insufficient permission
  64. */
  65. static ssize_t setenforce(struct file *f, const char __user *data,
  66. size_t len, loff_t *offset)
  67. {
  68. int rc = 0;
  69. bool new_value, old_value;
  70. if (!file_ns_capable(f, &init_user_ns, CAP_MAC_ADMIN))
  71. return -EPERM;
  72. old_value = READ_ONCE(enforce);
  73. rc = kstrtobool_from_user(data, len, &new_value);
  74. if (rc)
  75. return rc;
  76. if (new_value != old_value) {
  77. ipe_audit_enforce(new_value, old_value);
  78. WRITE_ONCE(enforce, new_value);
  79. }
  80. return len;
  81. }
  82. /**
  83. * getenforce() - Read handler for the securityfs node, "ipe/enforce"
  84. * @f: Supplies a file structure representing the securityfs node.
  85. * @data: Supplies a buffer passed to the read syscall.
  86. * @len: Supplies the length of @data.
  87. * @offset: unused.
  88. *
  89. * Return: Length of buffer written
  90. */
  91. static ssize_t getenforce(struct file *f, char __user *data,
  92. size_t len, loff_t *offset)
  93. {
  94. const char *result;
  95. result = ((READ_ONCE(enforce)) ? "1" : "0");
  96. return simple_read_from_buffer(data, len, offset, result, 1);
  97. }
  98. /**
  99. * new_policy() - Write handler for the securityfs node, "ipe/new_policy".
  100. * @f: Supplies a file structure representing the securityfs node.
  101. * @data: Supplies a buffer passed to the write syscall.
  102. * @len: Supplies the length of @data.
  103. * @offset: unused.
  104. *
  105. * Return:
  106. * * Length of buffer written - Success
  107. * * %-EPERM - Insufficient permission
  108. * * %-ENOMEM - Out of memory (OOM)
  109. * * %-EBADMSG - Policy is invalid
  110. * * %-ERANGE - Policy version number overflow
  111. * * %-EINVAL - Policy version parsing error
  112. * * %-EEXIST - Same name policy already deployed
  113. * * %-ENOKEY - Policy signing key not found
  114. * * %-EKEYREJECTED - Policy signature verification failed
  115. */
  116. static ssize_t new_policy(struct file *f, const char __user *data,
  117. size_t len, loff_t *offset)
  118. {
  119. struct ipe_policy *p = NULL;
  120. char *copy = NULL;
  121. int rc = 0;
  122. if (!file_ns_capable(f, &init_user_ns, CAP_MAC_ADMIN)) {
  123. rc = -EPERM;
  124. goto out;
  125. }
  126. copy = memdup_user_nul(data, len);
  127. if (IS_ERR(copy)) {
  128. rc = PTR_ERR(copy);
  129. copy = NULL;
  130. goto out;
  131. }
  132. p = ipe_new_policy(NULL, 0, copy, len);
  133. if (IS_ERR(p)) {
  134. rc = PTR_ERR(p);
  135. goto out;
  136. }
  137. rc = ipe_new_policyfs_node(p);
  138. if (rc)
  139. goto out;
  140. out:
  141. kfree(copy);
  142. if (rc < 0) {
  143. ipe_free_policy(p);
  144. ipe_audit_policy_load(ERR_PTR(rc));
  145. } else {
  146. ipe_audit_policy_load(p);
  147. }
  148. return (rc < 0) ? rc : len;
  149. }
  150. static const struct file_operations np_fops = {
  151. .write = new_policy,
  152. };
  153. static const struct file_operations audit_fops = {
  154. .write = setaudit,
  155. .read = getaudit,
  156. };
  157. static const struct file_operations enforce_fops = {
  158. .write = setenforce,
  159. .read = getenforce,
  160. };
  161. /**
  162. * ipe_init_securityfs() - Initialize IPE's securityfs tree at fsinit.
  163. *
  164. * Return: %0 on success. If an error occurs, the function will return
  165. * the -errno.
  166. */
  167. int __init ipe_init_securityfs(void)
  168. {
  169. int rc = 0;
  170. struct ipe_policy *ap;
  171. struct dentry *dentry;
  172. if (!ipe_enabled)
  173. return -EOPNOTSUPP;
  174. root = securityfs_create_dir("ipe", NULL);
  175. if (IS_ERR(root))
  176. return PTR_ERR(root);
  177. dentry = securityfs_create_file("success_audit", 0600, root,
  178. NULL, &audit_fops);
  179. if (IS_ERR(dentry)) {
  180. rc = PTR_ERR(dentry);
  181. goto err;
  182. }
  183. dentry = securityfs_create_file("enforce", 0600, root, NULL,
  184. &enforce_fops);
  185. if (IS_ERR(dentry)) {
  186. rc = PTR_ERR(dentry);
  187. goto err;
  188. }
  189. policy_root = securityfs_create_dir("policies", root);
  190. if (IS_ERR(policy_root)) {
  191. rc = PTR_ERR(policy_root);
  192. goto err;
  193. }
  194. ap = rcu_access_pointer(ipe_active_policy);
  195. if (ap) {
  196. rc = ipe_new_policyfs_node(ap);
  197. if (rc)
  198. goto err;
  199. }
  200. dentry = securityfs_create_file("new_policy", 0200, root, NULL, &np_fops);
  201. if (IS_ERR(dentry)) {
  202. rc = PTR_ERR(dentry);
  203. goto err;
  204. }
  205. return 0;
  206. err:
  207. securityfs_remove(root);
  208. return rc;
  209. }