summaryrefslogtreecommitdiff
path: root/security/landlock/domain.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/landlock/domain.c')
-rw-r--r--security/landlock/domain.c44
1 files changed, 24 insertions, 20 deletions
diff --git a/security/landlock/domain.c b/security/landlock/domain.c
index a647b68e8d06..79cb3bbdf4c5 100644
--- a/security/landlock/domain.c
+++ b/security/landlock/domain.c
@@ -182,32 +182,36 @@ static void test_get_layer_deny_mask(struct kunit *const test)
deny_masks_t
landlock_get_deny_masks(const access_mask_t all_existing_optional_access,
const access_mask_t optional_access,
- const layer_mask_t (*const layer_masks)[],
- const size_t layer_masks_size)
+ const struct layer_access_masks *const masks)
{
const unsigned long access_opt = optional_access;
unsigned long access_bit;
deny_masks_t deny_masks = 0;
+ access_mask_t all_denied = 0;
/* This may require change with new object types. */
- WARN_ON_ONCE(access_opt !=
- (optional_access & all_existing_optional_access));
+ WARN_ON_ONCE(!access_mask_subset(optional_access,
+ all_existing_optional_access));
- if (WARN_ON_ONCE(!layer_masks))
+ if (WARN_ON_ONCE(!masks))
return 0;
if (WARN_ON_ONCE(!access_opt))
return 0;
- for_each_set_bit(access_bit, &access_opt, layer_masks_size) {
- const layer_mask_t mask = (*layer_masks)[access_bit];
+ for (ssize_t i = ARRAY_SIZE(masks->access) - 1; i >= 0; i--) {
+ const access_mask_t denied = masks->access[i] & optional_access;
+ const unsigned long newly_denied = denied & ~all_denied;
- if (!mask)
+ if (!newly_denied)
continue;
- /* __fls(1) == 0 */
- deny_masks |= get_layer_deny_mask(all_existing_optional_access,
- access_bit, __fls(mask));
+ for_each_set_bit(access_bit, &newly_denied,
+ 8 * sizeof(access_mask_t)) {
+ deny_masks |= get_layer_deny_mask(
+ all_existing_optional_access, access_bit, i);
+ }
+ all_denied |= denied;
}
return deny_masks;
}
@@ -216,28 +220,28 @@ landlock_get_deny_masks(const access_mask_t all_existing_optional_access,
static void test_landlock_get_deny_masks(struct kunit *const test)
{
- const layer_mask_t layers1[BITS_PER_TYPE(access_mask_t)] = {
- [BIT_INDEX(LANDLOCK_ACCESS_FS_EXECUTE)] = BIT_ULL(0) |
- BIT_ULL(9),
- [BIT_INDEX(LANDLOCK_ACCESS_FS_TRUNCATE)] = BIT_ULL(1),
- [BIT_INDEX(LANDLOCK_ACCESS_FS_IOCTL_DEV)] = BIT_ULL(2) |
- BIT_ULL(0),
+ const struct layer_access_masks layers1 = {
+ .access[0] = LANDLOCK_ACCESS_FS_EXECUTE |
+ LANDLOCK_ACCESS_FS_IOCTL_DEV,
+ .access[1] = LANDLOCK_ACCESS_FS_TRUNCATE,
+ .access[2] = LANDLOCK_ACCESS_FS_IOCTL_DEV,
+ .access[9] = LANDLOCK_ACCESS_FS_EXECUTE,
};
KUNIT_EXPECT_EQ(test, 0x1,
landlock_get_deny_masks(_LANDLOCK_ACCESS_FS_OPTIONAL,
LANDLOCK_ACCESS_FS_TRUNCATE,
- &layers1, ARRAY_SIZE(layers1)));
+ &layers1));
KUNIT_EXPECT_EQ(test, 0x20,
landlock_get_deny_masks(_LANDLOCK_ACCESS_FS_OPTIONAL,
LANDLOCK_ACCESS_FS_IOCTL_DEV,
- &layers1, ARRAY_SIZE(layers1)));
+ &layers1));
KUNIT_EXPECT_EQ(
test, 0x21,
landlock_get_deny_masks(_LANDLOCK_ACCESS_FS_OPTIONAL,
LANDLOCK_ACCESS_FS_TRUNCATE |
LANDLOCK_ACCESS_FS_IOCTL_DEV,
- &layers1, ARRAY_SIZE(layers1)));
+ &layers1));
}
#endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */