ima.c 2.9 KB

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