[PATCH v2 6/6] Implement quiet for optional accesses
Mickaël Salaün
mic at digikod.net
Mon Oct 20 20:11:23 UTC 2025
On Sun, Oct 19, 2025 at 06:45:55PM +0100, Tingmao Wang wrote:
> On 10/15/25 20:09, Mickaël Salaün wrote:
> > [...]
> > On Sun, Oct 05, 2025 at 06:55:29PM +0100, Tingmao Wang wrote:
> >> [..]
> >> diff --git a/security/landlock/domain.c b/security/landlock/domain.c
> >> index a647b68e8d06..0f611ad516be 100644
> >> --- a/security/landlock/domain.c
> >> +++ b/security/landlock/domain.c
> >> @@ -212,6 +212,29 @@ landlock_get_deny_masks(const access_mask_t all_existing_optional_access,
> >> return deny_masks;
> >> }
> >>
> >
> > Just using u8 is confusing. Please document what is the "type" of the
> > returned value, and use a dedicated typedef instead of u8 (see my other
> > comment about static_assert). This typedef should probably be named
> > optional_access_t and have a size less or equal to access_t's one.
> >
> >> +u8 landlock_get_quiet_optional_accesses(
> >> + const access_mask_t all_existing_optional_access,
> >> + const deny_masks_t deny_masks,
> >> + const struct collected_rule_flags rule_flags)
> >> +{
> >> + const unsigned long access_opt = all_existing_optional_access;
> >> + size_t access_index = 0;
> >> + unsigned long access_bit;
> >> + u8 quiet_optional_accesses = 0;
> >
> > As for deny_masks_t, we should define an "optional_access_t" type with
> > appropriate safeguard to guarantee that it can always hold all optional
> > access rights (see static_assert for deny_masks_t in access.h).
> >
> > We should also copy the WARN_ON_ONCE() check from
> > get_layer_from_deny_masks().
>
> I don't see how that WARN_ON_ONCE is applicable here since we're no longer
> dealing with the `optional_access`... Can you clarify?
WARN_ON_ONCE(access_opt != _LANDLOCK_ACCESS_FS_OPTIONAL);
>
> >
> >> [...]
> >> @@ -80,13 +88,24 @@ struct landlock_file_security {
> >> struct landlock_cred_security fown_subject;
> >> };
> >>
> >> -#ifdef CONFIG_AUDIT
> >> +static void build_check_file_security(void)
> >
> > You can move this function to fs.c and call it in
> > hook_file_alloc_security() instead.
> >
> >> +{
> >> + const struct landlock_file_security file_sec = {
> >> + .quiet_optional_accesses = ~0,
> >> + .fown_layer = ~0,
> >> + };
> >> +
> >> + /*
> >> + * Make sure quiet_optional_accesses has enough bits to cover all
> >> + * optional accesses
> >> + */
> >> + BUILD_BUG_ON(__const_hweight8(file_sec.quiet_optional_accesses) <
> >
> > We should be able to use HWEIGHT() instead.
>
> I tried it and unfortunately it doesn't seem to work :(
>
> security/landlock/fs.c: In function ‘build_check_file_security’:
> ./include/linux/compiler.h:201:82: error: expression in static assertion is not constant
> 201 | #define __BUILD_BUG_ON_ZERO_MSG(e, msg, ...) ((int)sizeof(struct {_Static_assert(!(e), msg);}))
> | ^~~~
> ././include/linux/compiler_types.h:577:23: note: in definition of macro ‘__compiletime_assert’
> 577 | if (!(condition)) \
> | ^~~~~~~~~
> ././include/linux/compiler_types.h:597:9: note: in expansion of macro ‘_compiletime_assert’
> 597 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
> | ^~~~~~~~~~~~~~~~~~~
> ./include/linux/build_bug.h:39:37: note: in expansion of macro ‘compiletime_assert’
> 39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> | ^~~~~~~~~~~~~~~~~~
> ./include/linux/build_bug.h:50:9: note: in expansion of macro ‘BUILD_BUG_ON_MSG’
> 50 | BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
> | ^~~~~~~~~~~~~~~~
> security/landlock/fs.c:1769:9: note: in expansion of macro ‘BUILD_BUG_ON’
> 1769 | BUILD_BUG_ON(HWEIGHT(file_sec.quiet_optional_accesses) <
> | ^~~~~~~~~~~~
> ./include/linux/build_bug.h:17:9: note: in expansion of macro ‘__BUILD_BUG_ON_ZERO_MSG’
> 17 | __BUILD_BUG_ON_ZERO_MSG(e, ##__VA_ARGS__, #e " is true")
> | ^~~~~~~~~~~~~~~~~~~~~~~
> ./include/asm-generic/bitops/const_hweight.h:37:23: note: in expansion of macro ‘BUILD_BUG_ON_ZERO’
> 37 | #define HWEIGHT64(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight64(w))
> | ^~~~~~~~~~~~~~~~~
> ./include/asm-generic/bitops/const_hweight.h:42:22: note: in expansion of macro ‘HWEIGHT64’
> 42 | #define HWEIGHT(w) HWEIGHT64((u64)w)
> | ^~~~~~~~~
> security/landlock/fs.c:1769:22: note: in expansion of macro ‘HWEIGHT’
> 1769 | BUILD_BUG_ON(HWEIGHT(file_sec.quiet_optional_accesses) <
> | ^~~~~~~
>
Indeed, it works with Clang but not GCC.
Consistently always using __const_hweight64() might help avoid future
issue if quiet_optional_accesses grows more than 8 bits though.
> >
> >> + __const_hweight64(_LANDLOCK_ACCESS_FS_OPTIONAL));
> >> + /* Makes sure all layers can be identified. */
> >> + BUILD_BUG_ON(file_sec.fown_layer < LANDLOCK_MAX_NUM_LAYERS - 1);
> >> +}
> >>
> >> -/* 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 */
> >> +#ifdef CONFIG_AUDIT
> >>
> >> #endif /* CONFIG_AUDIT */
> >>
> >> @@ -107,6 +126,7 @@ struct landlock_superblock_security {
> >> static inline struct landlock_file_security *
> >> landlock_file(const struct file *const file)
> >> {
> >> + build_check_file_security();
> >> return file->f_security + landlock_blob_sizes.lbs_file;
> >> }
> >>
> >> --
> >> 2.51.0
>
More information about the Linux-security-module-archive
mailing list