[PATCH v10 3/9] landlock: Suppress logging when quiet flag is present
Tingmao Wang
m at maowtm.org
Fri Jun 12 01:11:34 UTC 2026
On 6/8/26 23:41, Mickaël Salaün wrote:
> On Mon, Jun 01, 2026 at 01:00:37AM +0100, Tingmao Wang wrote:
>> [...]
>> @@ -265,20 +268,33 @@ get_layer_from_deny_masks(access_mask_t *const access_request,
>> BITS_PER_TYPE(access_mask_t)) {
>> if (access_req & BIT(access_bit)) {
>> const size_t layer =
>> - (deny_masks >> (access_index * 4)) &
>> + (deny_masks >>
>> + (access_index *
>> + HWEIGHT(LANDLOCK_MAX_NUM_LAYERS - 1))) &
>> (LANDLOCK_MAX_NUM_LAYERS - 1);
>> + const bool layer_has_quiet =
>> + !!(quiet_optional_accesses & BIT(access_index));
>>
>> if (layer > youngest_layer) {
>> youngest_layer = layer;
>> missing = BIT(access_bit);
>> + should_quiet = layer_has_quiet;
>> } else if (layer == youngest_layer) {
>> missing |= BIT(access_bit);
>> + /*
>> + * Whether the layer has rules with quiet flag covering
>> + * the file accessed does not depend on the access, and so
>> + * the following WARN_ON_ONCE() should not fail.
>> + */
>> + WARN_ON_ONCE(should_quiet && !layer_has_quiet);
>
> WARN_ON_ONCE(should_quiet != layer_has_quiet);
That will fail when layer 0 has quiet flag on the object, at which point
since youngest_layer starts from 0, we will reach this branch with
should_quiet initialized earlier to false, but layer_has_quiet == true.
Also, if should_quiet != layer_has_quiet is always false here, then the
next line is not necessary.
>
>> + should_quiet = layer_has_quiet;
Would it be clearer to do should_quiet |= layer_has_quiet, mimicking the
"missing |= BIT(access_bit)"? (The result is the same)
>> }
>> }
>> access_index++;
>> }
>>
>> *access_request = missing;
>> + *quiet = should_quiet;
>> return youngest_layer;
>> }
>>
>> [...]
>> diff --git a/security/landlock/fs.h b/security/landlock/fs.h
>> index cb7e654933ac..d0fca7da2466 100644
>> --- a/security/landlock/fs.h
>> +++ b/security/landlock/fs.h
>> @@ -63,11 +63,20 @@ struct landlock_file_security {
>> * _LANDLOCK_ACCESS_FS_OPTIONAL).
>> */
>> deny_masks_t deny_masks;
>> + /**
>> + * @quiet_optional_accesses: Stores which optional accesses are
>> + * covered by quiet rules within the layer referred to in deny_masks,
>> + * one access per bit. Does not take into account whether the quiet
>> + * access bits are actually set in the layer's corresponding
>> + * landlock_hierarchy.
>> + */
>> + optional_access_t quiet_optional_accesses
>> + : HWEIGHT(_LANDLOCK_ACCESS_FS_OPTIONAL);
>> /**
>> * @fown_layer: Layer level of @fown_subject->domain with
>> * LANDLOCK_SCOPE_SIGNAL.
>> */
>> - u8 fown_layer;
>> + u8 fown_layer : 4;
>
> Please don't hardcode such size.
>
> Anyway, fown_layer can be updated concurrently (holding a lock), so we
> should not convert it to a bitfield.
>
>> #endif /* CONFIG_AUDIT */
>>
>> /**
>
>> @@ -82,12 +91,6 @@ struct landlock_file_security {
>>
>> #ifdef CONFIG_AUDIT
>>
>> -/* Makes sure all layers can be identified. */
>> -/* clang-format off */
>> -static_assert((typeof_member(struct landlock_file_security, fown_layer))~0 >=
>> - LANDLOCK_MAX_NUM_LAYERS);
>> -/* clang-format off */
>> -
>> #endif /* CONFIG_AUDIT */
>
> Remaining useless ifdef/endif.
Since we are not using bitfield for fown_layer anymore, I've also turned
quiet_optional_accesses (u8) into a non-bitfield. Then I reverted this
deletion and added
static_assert((typeof_member(struct landlock_file_security,
quiet_optional_accesses)) ~0 >=
HWEIGHT(_LANDLOCK_ACCESS_FS_OPTIONAL));
>
>> [...]
More information about the Linux-security-module-archive
mailing list