mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Mickaël Salaün" <mic@digikod.net>
To: Mark Brown <broonie@kernel.org>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	 Linux Next Mailing List <linux-next@vger.kernel.org>,
	Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
Subject: Re: linux-next: manual merge of the landlock tree with the origin tree
Date: Mon, 19 Oct 2026 23:15:29 +0200	[thread overview]
Message-ID: <20261019.wivie2AeLei1@digikod.net> (raw)
In-Reply-To: <atZRsj4ON6zuh9XN@sirena.co.uk>

On Mon, Oct 19, 2026 at 06:21:54PM +0100, Mark Brown wrote:
> Hi all,
> 
> Today's linux-next merge of the landlock tree got a conflict in:
> 
>   security/landlock/domain.h
> 
> between commit:
> 
>   3d8cc52db2f86 ("landlock: Drop __counted_by from landlock_domain.handled_masks")

This commit was merged with v7.3-rc7

> 
> from the origin tree and commit:
> 
>   395c985dac578 ("landlock: Wrap per-layer access masks in struct layer_config")

This commit should no longer be in linux-next, it was a previous
mic/next branch.  The new mic/next branch now properly handles the
merge.

> 
> from the landlock tree.  I kept the __counted_by in the hope that the
> refactoring helped the compiler figure out what's going on.

The "Drop __counted_by" is correct and my new mic/next branch (from
Friday) is based on v7.3-rc7, so I guess the next-20261001/landlock
merge should just be removed.

> 
> I fixed it up (see below) and can carry the fix as necessary. This
> is now fixed as far as linux-next is concerned, but any non trivial
> conflicts should be mentioned to your upstream maintainer when your tree
> is submitted for merging.  You may also want to consider cooperating
> with the maintainer of the conflicting tree to minimise any particularly
> complex conflicts.
> 
> diff --combined security/landlock/domain.h
> index 428c1d9890dbf,60e8eb2d6ac27..0000000000000
> --- a/security/landlock/domain.h
> +++ b/security/landlock/domain.h
> @@@ -130,10 -130,15 +130,15 @@@ struct landlock_hierarchy 
>   		 */
>   		log_new_exec : 1;
>   	/**
> - 	 * @quiet_masks: Bitmasks of access that should be quieted (i.e. not
> + 	 * @quiet_access: Bitmasks of access that should be quieted (i.e. not
>   	 * logged) if the related object is marked as quiet.
>   	 */
> - 	struct access_masks quiet_masks;
> + 	struct access_masks quiet_access;
> + 	/**
> + 	 * @quiet_permission: Per-member quiet bitmasks for permission types in
> + 	 * this layer.
> + 	 */
> + 	struct permission_masks quiet_permission;
>   #endif /* CONFIG_SECURITY_LANDLOCK_LOG */
>   };
>   
> @@@ -217,7 -222,7 +222,7 @@@ struct landlock_domain 
>   		 * @work_free: Enables to free a domain within a lockless
>   		 * section.  This is only used by landlock_put_domain_deferred()
>   		 * when @usage reaches zero.  The fields @usage, @num_layers and
> - 		 * @handled_masks are then unused.
> + 		 * @layers are then unused.
>   		 */
>   		struct work_struct work_free;
>   		struct {
> @@@ -233,23 -238,16 +238,16 @@@
>   			 */
>   			u32 num_layers;
>   			/**
> - 			 * @handled_masks: Contains the subset of filesystem and
> - 			 * network actions that are restricted by a domain.  A
> - 			 * domain saves all layers of merged rulesets in a stack
> - 			 * (FAM), starting from the first layer to the last one.
> - 			 * These layers are used when merging rulesets, for user
> - 			 * space backward compatibility (i.e. future-proof), and
> - 			 * to properly handle merged rulesets without
> - 			 * overlapping access rights.  These layers are set once
> - 			 * and never changed for the lifetime of the domain.
> - 			 *
> - 			 * Not annotated with __counted_by(num_layers): clang
> - 			 * miscomputes the counter address for a FAM nested in
> - 			 * an anonymous struct within a union, which trips
> - 			 * FORTIFY:
> - 			 * https://github.com/llvm/llvm-project/pull/228309
> + 			 * @layers: Per-layer access configuration.  A domain
> + 			 * saves all layers of merged rulesets in a stack (FAM),
> + 			 * starting from the first layer to the last one.  These
> + 			 * layers are used when merging rulesets, for user space
> + 			 * backward compatibility (i.e. future-proof), and to
> + 			 * properly handle merged rulesets without overlapping
> + 			 * access rights.  These layers are set once and never
> + 			 * changed for the lifetime of the domain.
>   			 */
> - 			struct access_masks handled_masks[];
> + 			struct layer_config layers[] __counted_by(num_layers);
>   		};
>   	};
>   };
> @@@ -259,7 -257,7 +257,7 @@@ landlock_get_fs_access_mask(const struc
>   			    const u16 layer_level)
>   {
>   	/* Handles all initially denied by default access rights. */
> - 	return domain->handled_masks[layer_level].fs |
> + 	return domain->layers[layer_level].handled.fs |
>   	       _LANDLOCK_ACCESS_FS_INITIALLY_DENIED;
>   }
>   
> @@@ -267,14 -265,14 +265,14 @@@ static inline access_mask_
>   landlock_get_net_access_mask(const struct landlock_domain *const domain,
>   			     const u16 layer_level)
>   {
> - 	return domain->handled_masks[layer_level].net;
> + 	return domain->layers[layer_level].handled.net;
>   }
>   
>   static inline access_mask_t
>   landlock_get_scope_mask(const struct landlock_domain *const domain,
>   			const u16 layer_level)
>   {
> - 	return domain->handled_masks[layer_level].scope;
> + 	return domain->layers[layer_level].handled.scope;
>   }
>   
>   /**
> @@@ -293,7 -291,7 +291,7 @@@ landlock_union_access_masks(const struc
>   
>   	for (layer_level = 0; layer_level < domain->num_layers; layer_level++) {
>   		union access_masks_all layer = {
> - 			.masks = domain->handled_masks[layer_level],
> + 			.masks = domain->layers[layer_level].handled,
>   		};
>   
>   		matches.all |= layer.all;
> @@@ -329,4 -327,63 +327,63 @@@ static inline void landlock_get_domain(
>   		refcount_inc(&domain->usage);
>   }
>   
> + /**
> +  * landlock_permission_is_denied - Check if a permission request is denied
> +  *
> +  * @domain: The enforced domain.
> +  * @permission_bit: The LANDLOCK_PERMISSION_* flag to check.  Must have
> +  *                  exactly one bit set.
> +  * @request_value: Compact bitmask to look for (e.g. the result of
> +  *                 landlock_ns_type_to_bit()).  Must have exactly one bit set.
> +  *
> +  * Iterate from the youngest layer to the oldest.  For each layer that handles
> +  * @permission_bit, check whether @request_value is present in the layer's
> +  * allowed bitmask.  Return on the first (youngest) denying layer.
> +  *
> +  * Return: The youngest denying layer + 1, or 0 if allowed.
> +  */
> + static inline size_t
> + landlock_permission_is_denied(const struct landlock_domain *const domain,
> + 			      const access_mask_t permission_bit,
> + 			      const u64 request_value)
> + {
> + 	ssize_t layer;
> + 
> + 	BUILD_BUG_ON(sizeof(permission_bit) > sizeof(u32));
> + 
> + 	if (WARN_ON_ONCE(hweight32(permission_bit) != 1) ||
> + 	    WARN_ON_ONCE(hweight64(request_value) != 1))
> + 		return domain->num_layers;
> + 
> + 	for (layer = domain->num_layers - 1; layer >= 0; layer--) {
> + 		u64 allowed;
> + 
> + 		if (!(domain->layers[layer].handled.permissions &
> + 		      permission_bit))
> + 			continue;
> + 
> + 		/*
> + 		 * Current callers pass only permission types with an explicit
> + 		 * case below.  The default catches a new caller missing its
> + 		 * member mask.
> + 		 */
> + 		switch (permission_bit) {
> + 		case LANDLOCK_PERMISSION_NAMESPACE_USE:
> + 			allowed = domain->layers[layer].allowed.ns_types;
> + 			break;
> + 		case LANDLOCK_PERMISSION_CAPABILITY_USE:
> + 			allowed = domain->layers[layer].allowed.caps;
> + 			break;
> + 		default:
> + 			WARN_ONCE(1, "Unknown permission %u\n",
> + 				  (unsigned int)permission_bit);
> + 			return layer + 1;
> + 		}
> + 
> + 		if (!(allowed & request_value))
> + 			return layer + 1;
> + 	}
> + 	return 0;
> + }
> + 
>   #endif /* _SECURITY_LANDLOCK_DOMAIN_H */



      reply	other threads:[~2026-10-19 21:15 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-19 17:21 Mark Brown
2026-10-19 21:15 ` Mickaël Salaün [this message]

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=20261019.wivie2AeLei1@digikod.net \
    --to=mic@digikod.net \
    --cc=broonie@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-next@vger.kernel.org \
    --cc=ngocthang2710.1999@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

all inboxes | Powered by JetHome®