Re: [PATCH v10 17/27] ima: Add functions for creating and freeing of an ima_namespace

Mimi Zohar <[email protected]>
Newsgroups dev.linux.lists.containers,org.kernel.vger.linux-integrity,org.kernel.vger.linux-kernel,org.kernel.vger.linux-security-module
Message-ID <[email protected]>
On Tue, 2022-02-01 at 15:37 -0500, Stefan Berger wrote:
> Implement create_ima_ns() to create an empty ima_namespace. Defer its
> initialization to a later point outside this function. Implement
> free_ima_ns() to free it.
> 
> Signed-off-by: Stefan Berger <[email protected]>
> Acked-by: Christian Brauner <[email protected]>
> 
> ---
> v9:
>  - Set user_ns->ims_ns = NULL in free_ima_ns()
>  - Refactored create_ima_ns() to defer initialization
>  - Removed pr_debug functions
> ---
>  include/linux/ima.h                      | 13 ++++++
>  security/integrity/ima/Makefile          |  1 +
>  security/integrity/ima/ima.h             | 15 +++++++
>  security/integrity/ima/ima_init_ima_ns.c |  2 +-
>  security/integrity/ima/ima_ns.c          | 53 ++++++++++++++++++++++++
>  5 files changed, 83 insertions(+), 1 deletion(-)
>  create mode 100644 security/integrity/ima/ima_ns.c
> 
> diff --git a/include/linux/ima.h b/include/linux/ima.h
> index 0cf2a80c8b35..964a08702573 100644
> --- a/include/linux/ima.h
> +++ b/include/linux/ima.h
> @@ -220,4 +220,17 @@ static inline bool ima_appraise_signature(enum kernel_read_file_id func)
>  	return false;
>  }
>  #endif /* CONFIG_IMA_APPRAISE && CONFIG_INTEGRITY_TRUSTED_KEYRING */
> +
> +#ifdef CONFIG_IMA_NS
> +
> +void free_ima_ns(struct user_namespace *ns);
> +
> +#else
> +
> +static inline void free_ima_ns(struct user_namespace *user_ns)
> +{
> +}
> +
> +#endif /* CONFIG_IMA_NS */
> +
>  #endif /* _LINUX_IMA_H */
> diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
> index f8a5e5f3975d..b86a35fbed60 100644
> --- a/security/integrity/ima/Makefile
> +++ b/security/integrity/ima/Makefile
> @@ -14,6 +14,7 @@ ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o
>  ima-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o
>  ima-$(CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS) += ima_asymmetric_keys.o
>  ima-$(CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS) += ima_queue_keys.o
> +ima-$(CONFIG_IMA_NS) += ima_ns.o
>  
>  ifeq ($(CONFIG_EFI),y)
>  ima-$(CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT) += ima_efi.o
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index 8c757223d549..751e936a6311 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -167,6 +167,7 @@ extern bool ima_canonical_fmt;
>  int ima_init(void);
>  int ima_fs_init(void);
>  int ima_ns_init(void);
> +int ima_init_namespace(struct ima_namespace *ns);
>  int ima_add_template_entry(struct ima_namespace *ns,
>  			   struct ima_template_entry *entry, int violation,
>  			   const char *op, struct inode *inode,
> @@ -502,4 +503,18 @@ static inline struct ima_namespace
>  	return NULL;
>  }
>  
> +#ifdef CONFIG_IMA_NS
> +
> +struct ima_namespace *create_ima_ns(void);
> +
> +#else
> +
> +static inline struct ima_namespace *create_ima_ns(void)
> +{
> +	WARN(1, "Cannot create an IMA namespace\n");
> +	return ERR_PTR(-EFAULT);
> +}
> +
> +#endif /* CONFIG_IMA_NS */
> +
>  #endif /* __LINUX_IMA_H */
> diff --git a/security/integrity/ima/ima_init_ima_ns.c b/security/integrity/ima/ima_init_ima_ns.c
> index 1cba545ae477..166dab4a3126 100644
> --- a/security/integrity/ima/ima_init_ima_ns.c
> +++ b/security/integrity/ima/ima_init_ima_ns.c
> @@ -8,7 +8,7 @@
>  
>  #include "ima.h"
>  
> -static int ima_init_namespace(struct ima_namespace *ns)
> +int ima_init_namespace(struct ima_namespace *ns)
>  {
>  	int rc;
>  
> diff --git a/security/integrity/ima/ima_ns.c b/security/integrity/ima/ima_ns.c
> new file mode 100644
> index 000000000000..b3b81a1e313e
> --- /dev/null
> +++ b/security/integrity/ima/ima_ns.c
> @@ -0,0 +1,53 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2016-2021 IBM Corporation
> + * Author:
> + *  Yuqiong Sun <[email protected]>
> + *  Stefan Berger <[email protected]>
> + */
> +
> +#include <linux/ima.h>
> +
> +#include "ima.h"
> +
> +static struct kmem_cache *imans_cachep;
> +
> +struct ima_namespace *create_ima_ns(void)
> +{
> +	struct ima_namespace *ns;
> +
> +	ns = kmem_cache_zalloc(imans_cachep, GFP_KERNEL);
> +	if (!ns)
> +		return ERR_PTR(-ENOMEM);
> +
> +	return ns;
> +}
> +
> +/* destroy_ima_ns() must only be called after ima_init_namespace() was called */
> +static void destroy_ima_ns(struct ima_namespace *ns)
> +{
> +	unregister_blocking_lsm_notifier(&ns->ima_lsm_policy_notifier);
> +	kfree(ns->arch_policy_entry);

Oh!  Here's the missing free of the architecture specific rules
(comment on 16/27).  Even if these rules have already been freed after
a custom policy is loaded, I guess it is safe to free them again.

Reviewed-by: Mimi Zohar <[email protected]>

> +	ima_free_policy_rules(ns);
> +}
> +
> +void free_ima_ns(struct user_namespace *user_ns)
> +{
> +	struct ima_namespace *ns = user_ns->ima_ns;
> +
> +	if (!ns || WARN_ON(ns == &init_ima_ns))
> +		return;
> +
> +	destroy_ima_ns(ns);
> +
> +	kmem_cache_free(imans_cachep, ns);
> +
> +	user_ns->ima_ns = NULL;
> +}
> +
> +static int __init imans_cache_init(void)
> +{
> +	imans_cachep = KMEM_CACHE(ima_namespace, SLAB_PANIC);
> +	return 0;
> +}
> +subsys_initcall(imans_cache_init)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.