All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Konstantin Meskhidze (A)" <konstantin.meskhidze@huawei.com>
To: "Mickaël Salaün" <mic@digikod.net>
Cc: <artem.kuzin@huawei.com>, <gnoack3000@gmail.com>,
	<willemdebruijn.kernel@gmail.com>,
	<linux-security-module@vger.kernel.org>, <netdev@vger.kernel.org>,
	<netfilter-devel@vger.kernel.org>
Subject: Re: [PATCH] landlock: Allow filesystem layout changes for domains without such rule type
Date: Mon, 28 Nov 2022 06:02:02 +0300	[thread overview]
Message-ID: <1956e8c2-fd4c-898e-dd0f-22ad20a69740@huawei.com> (raw)
In-Reply-To: <20221117185509.702361-1-mic@digikod.net>



11/17/2022 9:55 PM, Mickaël Salaün пишет:
> Allow mount point and root directory changes when there is no filesystem
> rule tied to the current Landlock domain.  This doesn't change anything
> for now because a domain must have at least a (filesystem) rule, but
> this will change when other rule types will come.  For instance, a
> domain only restricting the network should have no impact on filesystem
> restrictions.
> 
> Add a new get_current_fs_domain() helper to quickly check filesystem
> rule existence for all filesystem LSM hooks.

   Ok. I got it.
   Do I need also to add a new network helper:
   like landlock_get_raw_net_access_mask?
> 
> Remove unnecessary inlining.

   Ok.
> 
> Signed-off-by: Mickaël Salaün <mic@digikod.net>
> ---
>   security/landlock/fs.c       | 73 ++++++++++++++++++------------------
>   security/landlock/ruleset.h  | 25 +++++++++++-
>   security/landlock/syscalls.c |  6 +--
>   3 files changed, 62 insertions(+), 42 deletions(-)
> 
> diff --git a/security/landlock/fs.c b/security/landlock/fs.c
> index 0d57c6479d29..0ae54a639e16 100644
> --- a/security/landlock/fs.c
> +++ b/security/landlock/fs.c
> @@ -150,16 +150,6 @@ static struct landlock_object *get_inode_object(struct inode *const inode)
>   	LANDLOCK_ACCESS_FS_TRUNCATE)
>   /* clang-format on */
>   
> -/*
> - * All access rights that are denied by default whether they are handled or not
> - * by a ruleset/layer.  This must be ORed with all ruleset->fs_access_masks[]
> - * entries when we need to get the absolute handled access masks.
> - */
> -/* clang-format off */
> -#define ACCESS_INITIALLY_DENIED ( \
> -	LANDLOCK_ACCESS_FS_REFER)
> -/* clang-format on */
> -
>   /*
>    * @path: Should have been checked by get_path_from_fd().
>    */
> @@ -179,8 +169,7 @@ int landlock_append_fs_rule(struct landlock_ruleset *const ruleset,
>   
>   	/* Transforms relative access rights to absolute ones. */
>   	access_rights |= LANDLOCK_MASK_ACCESS_FS &
> -			 ~(landlock_get_fs_access_mask(ruleset, 0) |
> -			   ACCESS_INITIALLY_DENIED);
> +			 ~landlock_get_fs_access_mask(ruleset, 0);
>   	object = get_inode_object(d_backing_inode(path->dentry));
>   	if (IS_ERR(object))
>   		return PTR_ERR(object);
> @@ -287,14 +276,15 @@ static inline bool is_nouser_or_private(const struct dentry *dentry)
>   		unlikely(IS_PRIVATE(d_backing_inode(dentry))));
>   }
>   
> -static inline access_mask_t
> -get_handled_accesses(const struct landlock_ruleset *const domain)
> +static access_mask_t
> +get_raw_handled_fs_accesses(const struct landlock_ruleset *const domain)
>   {
> -	access_mask_t access_dom = ACCESS_INITIALLY_DENIED;
> +	access_mask_t access_dom = 0;
>   	size_t layer_level;
>   
>   	for (layer_level = 0; layer_level < domain->num_layers; layer_level++)
> -		access_dom |= landlock_get_fs_access_mask(domain, layer_level);
> +		access_dom |=
> +			landlock_get_raw_fs_access_mask(domain, layer_level);
>   	return access_dom & LANDLOCK_MASK_ACCESS_FS;
>   }
>   
> @@ -331,13 +321,8 @@ init_layer_masks(const struct landlock_ruleset *const domain,
>   
>   		for_each_set_bit(access_bit, &access_req,
>   				 ARRAY_SIZE(*layer_masks)) {
> -			/*
> -			 * Artificially handles all initially denied by default
> -			 * access rights.
> -			 */
>   			if (BIT_ULL(access_bit) &
> -			    (landlock_get_fs_access_mask(domain, layer_level) |
> -			     ACCESS_INITIALLY_DENIED)) {
> +			    landlock_get_fs_access_mask(domain, layer_level)) {
>   				(*layer_masks)[access_bit] |=
>   					BIT_ULL(layer_level);
>   				handled_accesses |= BIT_ULL(access_bit);
> @@ -347,6 +332,24 @@ init_layer_masks(const struct landlock_ruleset *const domain,
>   	return handled_accesses;
>   }
>   
> +static access_mask_t
> +get_handled_fs_accesses(const struct landlock_ruleset *const domain)
> +{
> +	/* Handles all initially denied by default access rights. */
> +	return get_raw_handled_fs_accesses(domain) | ACCESS_FS_INITIALLY_DENIED;
> +}
> +
> +static const struct landlock_ruleset *get_current_fs_domain(void)
> +{
> +	const struct landlock_ruleset *const dom =
> +		landlock_get_current_domain();
> +
> +	if (!dom || !get_raw_handled_fs_accesses(dom))
> +		return NULL;
> +
> +	return dom;
> +}
> +
>   /*
>    * Check that a destination file hierarchy has more restrictions than a source
>    * file hierarchy.  This is only used for link and rename actions.
> @@ -519,7 +522,7 @@ static bool is_access_to_paths_allowed(
>   		 * a superset of the meaningful requested accesses).
>   		 */
>   		access_masked_parent1 = access_masked_parent2 =
> -			get_handled_accesses(domain);
> +			get_handled_fs_accesses(domain);
>   		is_dom_check = true;
>   	} else {
>   		if (WARN_ON_ONCE(dentry_child1 || dentry_child2))
> @@ -648,11 +651,10 @@ static inline int check_access_path(const struct landlock_ruleset *const domain,
>   	return -EACCES;
>   }
>   
> -static inline int current_check_access_path(const struct path *const path,
> +static int current_check_access_path(const struct path *const path,
>   					    const access_mask_t access_request)
>   {
> -	const struct landlock_ruleset *const dom =
> -		landlock_get_current_domain();
> +	const struct landlock_ruleset *const dom = get_current_fs_domain();
>   
>   	if (!dom)
>   		return 0;
> @@ -815,8 +817,7 @@ static int current_check_refer_path(struct dentry *const old_dentry,
>   				    struct dentry *const new_dentry,
>   				    const bool removable, const bool exchange)
>   {
> -	const struct landlock_ruleset *const dom =
> -		landlock_get_current_domain();
> +	const struct landlock_ruleset *const dom = get_current_fs_domain();
>   	bool allow_parent1, allow_parent2;
>   	access_mask_t access_request_parent1, access_request_parent2;
>   	struct path mnt_dir;
> @@ -1050,7 +1051,7 @@ static int hook_sb_mount(const char *const dev_name,
>   			 const struct path *const path, const char *const type,
>   			 const unsigned long flags, void *const data)
>   {
> -	if (!landlock_get_current_domain())
> +	if (!get_current_fs_domain())
>   		return 0;
>   	return -EPERM;
>   }
> @@ -1058,7 +1059,7 @@ static int hook_sb_mount(const char *const dev_name,
>   static int hook_move_mount(const struct path *const from_path,
>   			   const struct path *const to_path)
>   {
> -	if (!landlock_get_current_domain())
> +	if (!get_current_fs_domain())
>   		return 0;
>   	return -EPERM;
>   }
> @@ -1069,14 +1070,14 @@ static int hook_move_mount(const struct path *const from_path,
>    */
>   static int hook_sb_umount(struct vfsmount *const mnt, const int flags)
>   {
> -	if (!landlock_get_current_domain())
> +	if (!get_current_fs_domain())
>   		return 0;
>   	return -EPERM;
>   }
>   
>   static int hook_sb_remount(struct super_block *const sb, void *const mnt_opts)
>   {
> -	if (!landlock_get_current_domain())
> +	if (!get_current_fs_domain())
>   		return 0;
>   	return -EPERM;
>   }
> @@ -1092,7 +1093,7 @@ static int hook_sb_remount(struct super_block *const sb, void *const mnt_opts)
>   static int hook_sb_pivotroot(const struct path *const old_path,
>   			     const struct path *const new_path)
>   {
> -	if (!landlock_get_current_domain())
> +	if (!get_current_fs_domain())
>   		return 0;
>   	return -EPERM;
>   }
> @@ -1128,8 +1129,7 @@ static int hook_path_mknod(const struct path *const dir,
>   			   struct dentry *const dentry, const umode_t mode,
>   			   const unsigned int dev)
>   {
> -	const struct landlock_ruleset *const dom =
> -		landlock_get_current_domain();
> +	const struct landlock_ruleset *const dom = get_current_fs_domain();
>   
>   	if (!dom)
>   		return 0;
> @@ -1208,8 +1208,7 @@ static int hook_file_open(struct file *const file)
>   	layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = {};
>   	access_mask_t open_access_request, full_access_request, allowed_access;
>   	const access_mask_t optional_access = LANDLOCK_ACCESS_FS_TRUNCATE;
> -	const struct landlock_ruleset *const dom =
> -		landlock_get_current_domain();
> +	const struct landlock_ruleset *const dom = get_current_fs_domain();
>   
>   	if (!dom)
>   		return 0;
> diff --git a/security/landlock/ruleset.h b/security/landlock/ruleset.h
> index f2ad932d396c..ca46393ef3bb 100644
> --- a/security/landlock/ruleset.h
> +++ b/security/landlock/ruleset.h
> @@ -15,10 +15,21 @@
>   #include <linux/rbtree.h>
>   #include <linux/refcount.h>
>   #include <linux/workqueue.h>
> +#include <uapi/linux/landlock.h>
>   
>   #include "limits.h"
>   #include "object.h"
>   
> +/*
> + * All access rights that are denied by default whether they are handled or not
> + * by a ruleset/layer.  This must be ORed with all ruleset->access_masks[]
> + * entries when we need to get the absolute handled access masks.
> + */
> +/* clang-format off */
> +#define ACCESS_FS_INITIALLY_DENIED ( \
> +	LANDLOCK_ACCESS_FS_REFER)
> +/* clang-format on */
> +
>   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);
> @@ -197,11 +208,21 @@ landlock_add_fs_access_mask(struct landlock_ruleset *const ruleset,
>   }
>   
>   static inline access_mask_t
> -landlock_get_fs_access_mask(const struct landlock_ruleset *const ruleset,
> -			    const u16 layer_level)
> +landlock_get_raw_fs_access_mask(const struct landlock_ruleset *const ruleset,
> +				const u16 layer_level)
>   {
>   	return (ruleset->access_masks[layer_level] >>
>   		LANDLOCK_SHIFT_ACCESS_FS) &
>   	       LANDLOCK_MASK_ACCESS_FS;
>   }
> +
> +static inline access_mask_t
> +landlock_get_fs_access_mask(const struct landlock_ruleset *const ruleset,
> +			    const u16 layer_level)
> +{
> +	/* Handles all initially denied by default access rights. */
> +	return landlock_get_raw_fs_access_mask(ruleset, layer_level) |
> +	       ACCESS_FS_INITIALLY_DENIED;
> +}
> +
>   #endif /* _SECURITY_LANDLOCK_RULESET_H */
> diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c
> index 71aca7f990bc..d35cd5d304db 100644
> --- a/security/landlock/syscalls.c
> +++ b/security/landlock/syscalls.c
> @@ -310,6 +310,7 @@ SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd,
>   	struct path path;
>   	struct landlock_ruleset *ruleset;
>   	int res, err;
> +	access_mask_t mask;
>   
>   	if (!landlock_initialized)
>   		return -EOPNOTSUPP;
> @@ -348,9 +349,8 @@ SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd,
>   	 * Checks that allowed_access matches the @ruleset constraints
>   	 * (ruleset->access_masks[0] is automatically upgraded to 64-bits).
>   	 */
> -	if ((path_beneath_attr.allowed_access |
> -	     landlock_get_fs_access_mask(ruleset, 0)) !=
> -	    landlock_get_fs_access_mask(ruleset, 0)) {
> +	mask = landlock_get_raw_fs_access_mask(ruleset, 0);
> +	if ((path_beneath_attr.allowed_access | mask) != mask) {
>   		err = -EINVAL;
>   		goto out_put_ruleset;
>   	}

  parent reply	other threads:[~2022-11-28  3:02 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-21 15:26 [PATCH v8 00/12] Network support for Landlock Konstantin Meskhidze
2022-10-21 15:26 ` [PATCH v8 01/12] landlock: Make ruleset's access masks more generic Konstantin Meskhidze
2022-11-17 18:41   ` Mickaël Salaün
2022-11-28  2:53     ` Konstantin Meskhidze (A)
2022-11-28 20:22       ` Mickaël Salaün
2022-12-02  2:49         ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 02/12] landlock: Refactor landlock_find_rule/insert_rule Konstantin Meskhidze
2022-11-17 18:41   ` Mickaël Salaün
2022-11-17 18:55     ` [PATCH] landlock: Allow filesystem layout changes for domains without such rule type Mickaël Salaün
2022-11-18  9:16       ` Mickaël Salaün
2022-11-28  3:04         ` Konstantin Meskhidze (A)
2022-11-28 20:23           ` Mickaël Salaün
2022-12-02  2:50             ` Konstantin Meskhidze (A)
2022-12-24  3:10             ` Konstantin Meskhidze (A)
2022-12-26 21:24               ` Mickaël Salaün
2022-12-27  1:47                 ` Konstantin Meskhidze (A)
2022-11-28  3:02       ` Konstantin Meskhidze (A) [this message]
2022-11-28 20:25         ` Mickaël Salaün
2022-12-02  2:51           ` Konstantin Meskhidze (A)
2022-11-22 17:17     ` [PATCH v8 02/12] landlock: Refactor landlock_find_rule/insert_rule Mickaël Salaün
2022-11-28  3:06       ` Konstantin Meskhidze (A)
2022-11-28  2:58     ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 03/12] landlock: Refactor merge/inherit_ruleset functions Konstantin Meskhidze
2022-11-17 18:41   ` Mickaël Salaün
2022-11-28  3:07     ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 04/12] landlock: Move unmask_layers() and init_layer_masks() Konstantin Meskhidze
2022-11-17 18:42   ` Mickaël Salaün
2022-11-28  3:25     ` Konstantin Meskhidze (A)
2022-11-28 20:25       ` Mickaël Salaün
2022-12-02  2:52         ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 05/12] landlock: Refactor " Konstantin Meskhidze
2022-11-17 18:42   ` Mickaël Salaün
2022-11-28  3:30     ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 06/12] landlock: Refactor landlock_add_rule() syscall Konstantin Meskhidze
2022-11-17 18:42   ` Mickaël Salaün
2022-11-28  3:32     ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 07/12] landlock: Add network rules support Konstantin Meskhidze
2022-11-17 18:43   ` Mickaël Salaün
2022-11-28  4:01     ` Konstantin Meskhidze (A)
2022-11-28 20:26       ` Mickaël Salaün
2022-12-02  2:54         ` Konstantin Meskhidze (A)
2023-01-03 12:44     ` Konstantin Meskhidze (A)
2023-01-04 11:41     ` Konstantin Meskhidze (A)
2023-01-06 19:22       ` Mickaël Salaün
2023-01-09  7:59         ` Konstantin Meskhidze (A)
2023-01-09  8:58           ` Dan Carpenter
2023-01-09  9:26             ` Konstantin Meskhidze (A)
2023-01-09 10:20               ` Dan Carpenter
2023-01-09 11:39                 ` Konstantin Meskhidze (A)
2023-01-09 11:53                   ` Dan Carpenter
2023-01-09 12:18                     ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 08/12] landlock: Implement TCP network hooks Konstantin Meskhidze
2022-11-17 18:43   ` Mickaël Salaün
2022-11-28  8:21     ` Konstantin Meskhidze (A)
2022-11-28 21:00       ` Mickaël Salaün
2022-12-02  3:13         ` Konstantin Meskhidze (A)
2022-12-02 13:01           ` Mickaël Salaün
2022-12-05  2:55             ` Konstantin Meskhidze (A)
2022-12-05 13:18               ` Mickaël Salaün
2023-01-05  8:57     ` Konstantin Meskhidze (A)
2023-01-06 19:30       ` Mickaël Salaün
2023-01-09  8:07         ` Konstantin Meskhidze (A)
2023-01-09 12:38           ` Mickaël Salaün
2023-01-10  4:45             ` Konstantin Meskhidze (A)
2023-01-10 17:24               ` Mickaël Salaün
2023-01-11  1:54                 ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 09/12] selftests/landlock: Share enforce_ruleset() Konstantin Meskhidze
2022-11-17 18:43   ` Mickaël Salaün
2022-11-28  4:02     ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 10/12] selftests/landlock: Add 10 new test suites dedicated to network Konstantin Meskhidze
2023-01-09 12:46   ` Mickaël Salaün
2023-01-10  5:03     ` Konstantin Meskhidze (A)
2023-01-10 17:40       ` Mickaël Salaün
2023-01-11  1:52         ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 11/12] samples/landlock: Add network demo Konstantin Meskhidze
2022-11-16 14:25   ` Mickaël Salaün
2022-11-28  2:49     ` Konstantin Meskhidze (A)
2022-11-28 20:26       ` Mickaël Salaün
2022-12-02  2:48         ` Konstantin Meskhidze (A)
2023-01-05  3:46     ` Konstantin Meskhidze (A)
2023-01-06 19:34       ` Mickaël Salaün
2023-01-09  7:57         ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 12/12] landlock: Document Landlock's network support Konstantin Meskhidze
2022-11-17 18:44   ` Mickaël Salaün
2022-11-28  6:44     ` Konstantin Meskhidze (A)
2022-11-28 20:26       ` Mickaël Salaün
2022-12-02  3:14         ` Konstantin Meskhidze (A)

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=1956e8c2-fd4c-898e-dd0f-22ad20a69740@huawei.com \
    --to=konstantin.meskhidze@huawei.com \
    --cc=artem.kuzin@huawei.com \
    --cc=gnoack3000@gmail.com \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mic@digikod.net \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=willemdebruijn.kernel@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.