From: "Mickaël Salaün" <mic@digikod.net>
To: Tingmao Wang <m@maowtm.org>
Cc: "Günther Noack" <gnoack3000@gmail.com>,
"Justin Suess" <utilityemal77@gmail.com>,
"Jan Kara" <jack@suse.cz>, "Abhinav Saxena" <xandfury@gmail.com>,
linux-security-module@vger.kernel.org
Subject: Re: [PATCH v8 1/9] landlock: Add a place for flags to layer rules
Date: Sun, 24 May 2026 22:35:05 +0200 [thread overview]
Message-ID: <20260524.eFiz4hahrami@digikod.net> (raw)
In-Reply-To: <617fdd53-6612-4f6f-b0e0-16d85985487b@maowtm.org>
On Sun, May 24, 2026 at 02:29:40AM +0100, Tingmao Wang wrote:
> On 5/23/26 21:48, Mickaël Salaün wrote:
> > This patch doesn't build.
>
> Missed a hunk in this patch (ended up in the next one), will add.
>
> >> @@ -797,20 +803,28 @@ is_access_to_paths_allowed(const struct landlock_ruleset *const domain,
> >> }
> >>
> >> if (unlikely(dentry_child1)) {
> >> + /*
> >> + * Get the layer masks for the child dentries for use by domain
> >> + * check later. The rule_flags for child1 should have been
> >> + * included in rule_flags_parent1 already (cf.
> >> + * collect_domain_accesses), and is not relevant for domain check,
> >> + * so we don't have to pass it to landlock_unmask_layers.
> >> + */
> >> if (landlock_init_layer_masks(domain, LANDLOCK_MASK_ACCESS_FS,
> >> &_layer_masks_child1,
> >> LANDLOCK_KEY_INODE))
> >> landlock_unmask_layers(find_rule(domain, dentry_child1),
> >> - &_layer_masks_child1);
> >> + &_layer_masks_child1, NULL);
> >> layer_masks_child1 = &_layer_masks_child1;
> >> child1_is_directory = d_is_dir(dentry_child1);
> >> }
> >> if (unlikely(dentry_child2)) {
> >> + /* See above comment for why NULL is passed as rule_flags_masks. */
> >
> > rule_flags_masks doesn't exist.
>
> I guess I was probably referring to the rule_flags argument - will fix.
>
> >> [...]
> >> @@ -647,9 +648,14 @@ bool landlock_unmask_layers(const struct landlock_rule *const rule,
> >> */
> >> for (size_t i = 0; i < rule->num_layers; i++) {
> >> const struct landlock_layer *const layer = &rule->layers[i];
> >> + const layer_mask_t layer_bit = BIT_ULL(layer->level - 1);
> >>
> >
> >> /* Clear the bits where the layer in the rule grants access. */
> >> masks->access[layer->level - 1] &= ~layer->access;
> >> +
> >> + /* Collect rule flags for each layer. */
> >> + if (rule_flags && layer->flags.quiet)
> >> + rule_flags->quiet_masks |= layer_bit;
> >
> > Why not store the quiet bit in masks? That would not only be "access"
> > bits anymore but it makes sense to store all this bits it the same
> > place.
> >
> > We should then probably rename struct layer_access_masks to just struct
> > layer_masks.
> >
> > We need to be careful to not increase too much the size of this struct
> > though while keeping the [LANDLOCK_MAX_NUM_LAYERS] approach if possible
> > (see Günther's commit that added it).
>
> Most uses of struct layer_access_masks do not actually care about the rule
> flags tho, e.g. in unmask_scoped_access, scope_to_request, or may_refer.
> Such a rename would touch 31 places (and only a few of them would actually
> touch the quiet flag).
Most of these places are tests.
>
> If we want to refactor to make this be in the layer_access_masks (then
> rename it), I guess there are 3 options, which do you prefer?
>
> 1. Add a u16 bitfield for which layers are quieted. Future rule flags
> will be additional bitfields. struct layer_masks becomes 68 bytes (+4).
>
> struct layer_masks {
> access_mask_t access[LANDLOCK_MAX_NUM_LAYERS];
> layer_mask_t quiet_layers;
> };
>
> 2. Make the [LANDLOCK_MAX_NUM_LAYERS] array store both the access mask and
> the quiet bit (or more bits for future rule flags). Size of struct stays
> the same.
>
> static_assert(LANDLOCK_NUM_ACCESS_NET <= LANDLOCK_NUM_ACCESS_FS);
> static_assert(LANDLOCK_NUM_SCOPE <= LANDLOCK_NUM_ACCESS_FS);
> struct layer_mask {
> access_mask_t access:LANDLOCK_NUM_ACCESS_FS;
> bool quiet:1;
> };
Yes, like Justin, I prefer this approach too. Some improvements:
// In limits.h:
#define LANDLOCK_MAX_NUM_ACCESSES \
MAX(LANDLOCK_NUM_ACCESS_FS, LANDLOCK_NUM_ACCESS_NET)
// In access.h:
struct layer_mask {
access_mask_t access:LANDLOCK_MAX_NUM_ACCESSES;
#ifdef CONFIG_AUDIT
bool quiet:1; // I'm not sure if using bool would work for all
// architectures though, but we can make sure with the following
// assert.
#endif /* CONFIG_AUDIT */
};
static_assert(sizeof(struct layer_mask), sizeof(access_mask_t));
> struct layer_masks {
> struct layer_mask layer[LANDLOCK_MAX_NUM_LAYERS];
> };
>
> (Maybe we can just make struct layer_masks a typedef to
> layer_mask[LANDLOCK_MAX_NUM_LAYERS] instead? But currently not sure if
> there are any gotchas with a typedef like that)
The only typedefs used in Landlock are for potentially growing types. So
no need for typedef here.
>
> 3. Mirror layer_access_masks::access[] - add a
> rule_flags[LANDLOCK_MAX_NUM_LAYERS] too. struct layer_masks becomes 80
> bytes (+16).
>
> struct rule_flags {
> bool quiet:1;
> };
> struct layer_masks {
> /**
> * @access: The unfulfilled access rights for each layer.
> */
> access_mask_t access[LANDLOCK_MAX_NUM_LAYERS];
> struct rule_flags rule_flags[LANDLOCK_MAX_NUM_LAYERS];
> };
>
> (3 seems very wasteful to me)
>
next prev parent reply other threads:[~2026-05-24 20:35 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-06 15:52 [PATCH v8 0/9] Implement LANDLOCK_ADD_RULE_QUIET Tingmao Wang
2026-04-06 15:52 ` [PATCH v8 1/9] landlock: Add a place for flags to layer rules Tingmao Wang
2026-05-23 20:48 ` Mickaël Salaün
2026-05-24 1:29 ` Tingmao Wang
2026-05-24 14:46 ` Justin Suess
2026-05-24 18:20 ` Tingmao Wang
2026-05-24 22:08 ` Justin Suess
2026-05-25 20:39 ` Mickaël Salaün
2026-05-24 20:35 ` Mickaël Salaün [this message]
2026-04-06 15:52 ` [PATCH v8 2/9] landlock: Add API support and docs for the quiet flags Tingmao Wang
2026-05-24 20:35 ` Mickaël Salaün
2026-04-06 15:52 ` [PATCH v8 3/9] landlock: Suppress logging when quiet flag is present Tingmao Wang
2026-05-25 20:40 ` Mickaël Salaün
2026-04-06 15:52 ` [PATCH v8 4/9] samples/landlock: Add quiet flag support to sandboxer Tingmao Wang
2026-04-06 15:52 ` [PATCH v8 5/9] selftests/landlock: Replace hard-coded 16 with a constant Tingmao Wang
2026-04-06 15:52 ` [PATCH v8 6/9] selftests/landlock: add tests for quiet flag with fs rules Tingmao Wang
2026-04-06 15:52 ` [PATCH v8 7/9] selftests/landlock: add tests for quiet flag with net rules Tingmao Wang
2026-04-06 15:52 ` [PATCH v8 8/9] selftests/landlock: Add tests for quiet flag with scope Tingmao Wang
2026-04-06 15:52 ` [PATCH v8 9/9] selftests/landlock: Add tests for invalid use of quiet flag Tingmao Wang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260524.eFiz4hahrami@digikod.net \
--to=mic@digikod.net \
--cc=gnoack3000@gmail.com \
--cc=jack@suse.cz \
--cc=linux-security-module@vger.kernel.org \
--cc=m@maowtm.org \
--cc=utilityemal77@gmail.com \
--cc=xandfury@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox