fs.c 5.7 KB

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