diff options
author | Mickaël Salaün <mic@digikod.net> | 2022-05-06 18:10:54 +0200 |
---|---|---|
committer | Mickaël Salaün <mic@digikod.net> | 2022-05-23 13:27:57 +0200 |
commit | 8ba0005ff418ec356e176b26eaa04a6ac755d05b (patch) | |
tree | dc29bec751ad38098161896f30da8dcd7933bee4 /security/landlock/ruleset.h | |
parent | 2cd7cd6eed88b8383cfddce589afe9c0ae1d19b4 (diff) | |
download | linux-8ba0005ff418ec356e176b26eaa04a6ac755d05b.tar.gz |
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 'security/landlock/ruleset.h')
-rw-r--r-- | security/landlock/ruleset.h | 2 |
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. */ |