domain.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Landlock - Domain management
  4. *
  5. * Copyright © 2016-2020 Mickaël Salaün <mic@digikod.net>
  6. * Copyright © 2018-2020 ANSSI
  7. * Copyright © 2024-2025 Microsoft Corporation
  8. */
  9. #include <kunit/test.h>
  10. #include <linux/bitops.h>
  11. #include <linux/bits.h>
  12. #include <linux/cred.h>
  13. #include <linux/file.h>
  14. #include <linux/mm.h>
  15. #include <linux/path.h>
  16. #include <linux/pid.h>
  17. #include <linux/sched.h>
  18. #include <linux/signal.h>
  19. #include <linux/uidgid.h>
  20. #include "access.h"
  21. #include "common.h"
  22. #include "domain.h"
  23. #include "id.h"
  24. #ifdef CONFIG_AUDIT
  25. /**
  26. * get_current_exe - Get the current's executable path, if any
  27. *
  28. * @exe_str: Returned pointer to a path string with a lifetime tied to the
  29. * returned buffer, if any.
  30. * @exe_size: Returned size of @exe_str (including the trailing null
  31. * character), if any.
  32. *
  33. * Returns: A pointer to an allocated buffer where @exe_str point to, %NULL if
  34. * there is no executable path, or an error otherwise.
  35. */
  36. static const void *get_current_exe(const char **const exe_str,
  37. size_t *const exe_size)
  38. {
  39. const size_t buffer_size = LANDLOCK_PATH_MAX_SIZE;
  40. struct mm_struct *mm = current->mm;
  41. struct file *file __free(fput) = NULL;
  42. char *buffer __free(kfree) = NULL;
  43. const char *exe;
  44. ssize_t size;
  45. if (!mm)
  46. return NULL;
  47. file = get_mm_exe_file(mm);
  48. if (!file)
  49. return NULL;
  50. buffer = kmalloc(buffer_size, GFP_KERNEL);
  51. if (!buffer)
  52. return ERR_PTR(-ENOMEM);
  53. exe = d_path(&file->f_path, buffer, buffer_size);
  54. if (WARN_ON_ONCE(IS_ERR(exe)))
  55. /* Should never happen according to LANDLOCK_PATH_MAX_SIZE. */
  56. return ERR_CAST(exe);
  57. size = buffer + buffer_size - exe;
  58. if (WARN_ON_ONCE(size <= 0))
  59. return ERR_PTR(-ENAMETOOLONG);
  60. *exe_size = size;
  61. *exe_str = exe;
  62. return no_free_ptr(buffer);
  63. }
  64. /*
  65. * Returns: A newly allocated object describing a domain, or an error
  66. * otherwise.
  67. */
  68. static struct landlock_details *get_current_details(void)
  69. {
  70. /* Cf. audit_log_d_path_exe() */
  71. static const char null_path[] = "(null)";
  72. const char *path_str = null_path;
  73. size_t path_size = sizeof(null_path);
  74. const void *buffer __free(kfree) = NULL;
  75. struct landlock_details *details;
  76. buffer = get_current_exe(&path_str, &path_size);
  77. if (IS_ERR(buffer))
  78. return ERR_CAST(buffer);
  79. /*
  80. * Create the new details according to the path's length. Do not
  81. * allocate with GFP_KERNEL_ACCOUNT because it is independent from the
  82. * caller.
  83. */
  84. details = kzalloc_flex(*details, exe_path, path_size);
  85. if (!details)
  86. return ERR_PTR(-ENOMEM);
  87. memcpy(details->exe_path, path_str, path_size);
  88. details->pid = get_pid(task_tgid(current));
  89. details->uid = from_kuid(&init_user_ns, current_uid());
  90. get_task_comm(details->comm, current);
  91. return details;
  92. }
  93. /**
  94. * landlock_init_hierarchy_log - Partially initialize landlock_hierarchy
  95. *
  96. * @hierarchy: The hierarchy to initialize.
  97. *
  98. * The current task is referenced as the domain that is enforcing the
  99. * restriction. The subjective credentials must not be in an overridden state.
  100. *
  101. * @hierarchy->parent and @hierarchy->usage should already be set.
  102. */
  103. int landlock_init_hierarchy_log(struct landlock_hierarchy *const hierarchy)
  104. {
  105. struct landlock_details *details;
  106. details = get_current_details();
  107. if (IS_ERR(details))
  108. return PTR_ERR(details);
  109. hierarchy->details = details;
  110. hierarchy->id = landlock_get_id_range(1);
  111. hierarchy->log_status = LANDLOCK_LOG_PENDING;
  112. hierarchy->log_same_exec = true;
  113. hierarchy->log_new_exec = false;
  114. atomic64_set(&hierarchy->num_denials, 0);
  115. return 0;
  116. }
  117. static deny_masks_t
  118. get_layer_deny_mask(const access_mask_t all_existing_optional_access,
  119. const unsigned long access_bit, const size_t layer)
  120. {
  121. unsigned long access_weight;
  122. /* This may require change with new object types. */
  123. WARN_ON_ONCE(all_existing_optional_access !=
  124. _LANDLOCK_ACCESS_FS_OPTIONAL);
  125. if (WARN_ON_ONCE(layer >= LANDLOCK_MAX_NUM_LAYERS))
  126. return 0;
  127. access_weight = hweight_long(all_existing_optional_access &
  128. GENMASK(access_bit, 0));
  129. if (WARN_ON_ONCE(access_weight < 1))
  130. return 0;
  131. return layer
  132. << ((access_weight - 1) * HWEIGHT(LANDLOCK_MAX_NUM_LAYERS - 1));
  133. }
  134. #ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST
  135. static void test_get_layer_deny_mask(struct kunit *const test)
  136. {
  137. const unsigned long truncate = BIT_INDEX(LANDLOCK_ACCESS_FS_TRUNCATE);
  138. const unsigned long ioctl_dev = BIT_INDEX(LANDLOCK_ACCESS_FS_IOCTL_DEV);
  139. KUNIT_EXPECT_EQ(test, 0,
  140. get_layer_deny_mask(_LANDLOCK_ACCESS_FS_OPTIONAL,
  141. truncate, 0));
  142. KUNIT_EXPECT_EQ(test, 0x3,
  143. get_layer_deny_mask(_LANDLOCK_ACCESS_FS_OPTIONAL,
  144. truncate, 3));
  145. KUNIT_EXPECT_EQ(test, 0,
  146. get_layer_deny_mask(_LANDLOCK_ACCESS_FS_OPTIONAL,
  147. ioctl_dev, 0));
  148. KUNIT_EXPECT_EQ(test, 0xf0,
  149. get_layer_deny_mask(_LANDLOCK_ACCESS_FS_OPTIONAL,
  150. ioctl_dev, 15));
  151. }
  152. #endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */
  153. deny_masks_t
  154. landlock_get_deny_masks(const access_mask_t all_existing_optional_access,
  155. const access_mask_t optional_access,
  156. const struct layer_access_masks *const masks)
  157. {
  158. const unsigned long access_opt = optional_access;
  159. unsigned long access_bit;
  160. deny_masks_t deny_masks = 0;
  161. access_mask_t all_denied = 0;
  162. /* This may require change with new object types. */
  163. WARN_ON_ONCE(!access_mask_subset(optional_access,
  164. all_existing_optional_access));
  165. if (WARN_ON_ONCE(!masks))
  166. return 0;
  167. if (WARN_ON_ONCE(!access_opt))
  168. return 0;
  169. for (ssize_t i = ARRAY_SIZE(masks->access) - 1; i >= 0; i--) {
  170. const access_mask_t denied = masks->access[i] & optional_access;
  171. const unsigned long newly_denied = denied & ~all_denied;
  172. if (!newly_denied)
  173. continue;
  174. for_each_set_bit(access_bit, &newly_denied,
  175. 8 * sizeof(access_mask_t)) {
  176. deny_masks |= get_layer_deny_mask(
  177. all_existing_optional_access, access_bit, i);
  178. }
  179. all_denied |= denied;
  180. }
  181. return deny_masks;
  182. }
  183. #ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST
  184. static void test_landlock_get_deny_masks(struct kunit *const test)
  185. {
  186. const struct layer_access_masks layers1 = {
  187. .access[0] = LANDLOCK_ACCESS_FS_EXECUTE |
  188. LANDLOCK_ACCESS_FS_IOCTL_DEV,
  189. .access[1] = LANDLOCK_ACCESS_FS_TRUNCATE,
  190. .access[2] = LANDLOCK_ACCESS_FS_IOCTL_DEV,
  191. .access[9] = LANDLOCK_ACCESS_FS_EXECUTE,
  192. };
  193. KUNIT_EXPECT_EQ(test, 0x1,
  194. landlock_get_deny_masks(_LANDLOCK_ACCESS_FS_OPTIONAL,
  195. LANDLOCK_ACCESS_FS_TRUNCATE,
  196. &layers1));
  197. KUNIT_EXPECT_EQ(test, 0x20,
  198. landlock_get_deny_masks(_LANDLOCK_ACCESS_FS_OPTIONAL,
  199. LANDLOCK_ACCESS_FS_IOCTL_DEV,
  200. &layers1));
  201. KUNIT_EXPECT_EQ(
  202. test, 0x21,
  203. landlock_get_deny_masks(_LANDLOCK_ACCESS_FS_OPTIONAL,
  204. LANDLOCK_ACCESS_FS_TRUNCATE |
  205. LANDLOCK_ACCESS_FS_IOCTL_DEV,
  206. &layers1));
  207. }
  208. #endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */
  209. #ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST
  210. static struct kunit_case test_cases[] = {
  211. /* clang-format off */
  212. KUNIT_CASE(test_get_layer_deny_mask),
  213. KUNIT_CASE(test_landlock_get_deny_masks),
  214. {}
  215. /* clang-format on */
  216. };
  217. static struct kunit_suite test_suite = {
  218. .name = "landlock_domain",
  219. .test_cases = test_cases,
  220. };
  221. kunit_test_suite(test_suite);
  222. #endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */
  223. #endif /* CONFIG_AUDIT */