aboutsummaryrefslogtreecommitdiffstats
path: root/security/landlock/ruleset.h
diff options
context:
space:
mode:
authorMickaël Salaün <mic@digikod.net>2022-05-06 18:10:54 +0200
committerMickaël Salaün <mic@digikod.net>2022-05-23 13:27:57 +0200
commit8ba0005ff418ec356e176b26eaa04a6ac755d05b (patch)
treedc29bec751ad38098161896f30da8dcd7933bee4 /security/landlock/ruleset.h
parentlandlock: Create find_rule() from unmask_layers() (diff)
downloadlinux-dev-8ba0005ff418ec356e176b26eaa04a6ac755d05b.tar.xz
linux-dev-8ba0005ff418ec356e176b26eaa04a6ac755d05b.zip
landlock: Fix same-layer rule unions
The original behavior was to check if the full set of requested accesses was allowed by at least a rule of every relevant layer. This didn't take into account requests for multiple accesses and same-layer rules allowing the union of these accesses in a complementary way. As a result, multiple accesses requested on a file hierarchy matching rules that, together, allowed these accesses, but without a unique rule allowing all of them, was illegitimately denied. This case should be rare in practice and it can only be triggered by the path_rename or file_open hook implementations. For instance, if, for the same layer, a rule allows execution beneath /a/b and another rule allows read beneath /a, requesting access to read and execute at the same time for /a/b should be allowed for this layer. This was an inconsistency because the union of same-layer rule accesses was already allowed if requested once at a time anyway. This fix changes the way allowed accesses are gathered over a path walk. To take into account all these rule accesses, we store in a matrix all layer granting the set of requested accesses, according to the handled accesses. To avoid heap allocation, we use an array on the stack which is 2*13 bytes. A following commit bringing the LANDLOCK_ACCESS_FS_REFER access right will increase this size to reach 112 bytes (2*14*4) in case of link or rename actions. Add a new layout1.layer_rule_unions test to check that accesses from different rules pertaining to the same layer are ORed in a file hierarchy. Also test that it is not the case for rules from different layers. Reviewed-by: Paul Moore <paul@paul-moore.com> Link: https://lore.kernel.org/r/20220506161102.525323-5-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün <mic@digikod.net>
Diffstat (limited to '')
-rw-r--r--security/landlock/ruleset.h2
1 files changed, 2 insertions, 0 deletions
diff --git a/security/landlock/ruleset.h b/security/landlock/ruleset.h
index 521af2848951..d43231b783e4 100644
--- a/security/landlock/ruleset.h
+++ b/security/landlock/ruleset.h
@@ -22,6 +22,8 @@
typedef u16 access_mask_t;
/* Makes sure all filesystem access rights can be stored. */
static_assert(BITS_PER_TYPE(access_mask_t) >= LANDLOCK_NUM_ACCESS_FS);
+/* Makes sure for_each_set_bit() and for_each_clear_bit() calls are OK. */
+static_assert(sizeof(unsigned long) >= sizeof(access_mask_t));
typedef u16 layer_mask_t;
/* Makes sure all layers can be checked. */