ima.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2021 Microsoft Corporation
  4. *
  5. * Author: Lakshmi Ramasubramanian (nramas@linux.microsoft.com)
  6. *
  7. * Measure critical data structures maintained by SELinux
  8. * using IMA subsystem.
  9. */
  10. #include <linux/vmalloc.h>
  11. #include <linux/ima.h>
  12. #include "security.h"
  13. #include "ima.h"
  14. /*
  15. * selinux_ima_collect_state - Read selinux configuration settings
  16. *
  17. * On success returns the configuration settings string.
  18. * On error, returns NULL.
  19. */
  20. static char *selinux_ima_collect_state(void)
  21. {
  22. const char *on = "=1;", *off = "=0;";
  23. char *buf;
  24. int buf_len, len, i, rc;
  25. buf_len = strlen("initialized=0;enforcing=0;checkreqprot=0;") + 1;
  26. len = strlen(on);
  27. for (i = 0; i < __POLICYDB_CAP_MAX; i++)
  28. buf_len += strlen(selinux_policycap_names[i]) + len;
  29. buf = kzalloc(buf_len, GFP_KERNEL);
  30. if (!buf)
  31. return NULL;
  32. rc = strscpy(buf, "initialized", buf_len);
  33. WARN_ON(rc < 0);
  34. rc = strlcat(buf, selinux_initialized() ? on : off, buf_len);
  35. WARN_ON(rc >= buf_len);
  36. rc = strlcat(buf, "enforcing", buf_len);
  37. WARN_ON(rc >= buf_len);
  38. rc = strlcat(buf, enforcing_enabled() ? on : off, buf_len);
  39. WARN_ON(rc >= buf_len);
  40. rc = strlcat(buf, "checkreqprot", buf_len);
  41. WARN_ON(rc >= buf_len);
  42. rc = strlcat(buf, checkreqprot_get() ? on : off, buf_len);
  43. WARN_ON(rc >= buf_len);
  44. for (i = 0; i < __POLICYDB_CAP_MAX; i++) {
  45. rc = strlcat(buf, selinux_policycap_names[i], buf_len);
  46. WARN_ON(rc >= buf_len);
  47. rc = strlcat(buf, selinux_state.policycap[i] ? on : off,
  48. buf_len);
  49. WARN_ON(rc >= buf_len);
  50. }
  51. return buf;
  52. }
  53. /*
  54. * selinux_ima_measure_state_locked - Measure SELinux state and hash of policy
  55. */
  56. void selinux_ima_measure_state_locked(void)
  57. {
  58. char *state_str = NULL;
  59. void *policy = NULL;
  60. size_t policy_len;
  61. int rc = 0;
  62. lockdep_assert_held(&selinux_state.policy_mutex);
  63. state_str = selinux_ima_collect_state();
  64. if (!state_str) {
  65. pr_err("SELinux: %s: failed to read state.\n", __func__);
  66. return;
  67. }
  68. ima_measure_critical_data("selinux", "selinux-state",
  69. state_str, strlen(state_str), false,
  70. NULL, 0);
  71. kfree(state_str);
  72. /*
  73. * Measure SELinux policy only after initialization is completed.
  74. */
  75. if (!selinux_initialized())
  76. return;
  77. rc = security_read_state_kernel(&policy, &policy_len);
  78. if (rc) {
  79. pr_err("SELinux: %s: failed to read policy %d.\n", __func__, rc);
  80. return;
  81. }
  82. ima_measure_critical_data("selinux", "selinux-policy-hash",
  83. policy, policy_len, true,
  84. NULL, 0);
  85. vfree(policy);
  86. }
  87. /*
  88. * selinux_ima_measure_state - Measure SELinux state and hash of policy
  89. */
  90. void selinux_ima_measure_state(void)
  91. {
  92. lockdep_assert_not_held(&selinux_state.policy_mutex);
  93. mutex_lock(&selinux_state.policy_mutex);
  94. selinux_ima_measure_state_locked();
  95. mutex_unlock(&selinux_state.policy_mutex);
  96. }