[PATCH v9 19/25] integrity: Move integrity_kernel_module_request() to IMA

Stefan Berger stefanb at linux.ibm.com
Mon Feb 12 17:37:20 UTC 2024



On 1/15/24 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu at huawei.com>
> 
> In preparation for removing the 'integrity' LSM, move
> integrity_kernel_module_request() to IMA, and rename it to
> ima_kernel_module_request().
> 
> Compile it conditionally if CONFIG_INTEGRITY_ASYMMETRIC_KEYS is enabled,
> and call it from security.c (removed afterwards with the move of IMA to the
> LSM infrastructure).
> 
> Adding this hook cannot be avoided, since IMA has no control on the flags
> passed to crypto_alloc_sig() in public_key_verify_signature(), and thus
> cannot pass CRYPTO_NOLOAD, which solved the problem for EVM hashing with
> commit e2861fa71641 ("evm: Don't deadlock if a crypto algorithm is
> unavailable").
> 
> EVM alone does not need to implement this hook, first because there is no
> mutex to deadlock, and second because even if it had it, there should be a
> recursive call. However, since verification from EVM can be initiated only
> by setting inode metadata, deadlock would occur if modprobe would do the
> same while loading a kernel module (which is unlikely).
> 
> Signed-off-by: Roberto Sassu <roberto.sassu at huawei.com>
> ---
>   include/linux/ima.h                    | 10 +++++++++
>   include/linux/integrity.h              | 13 ------------
>   security/integrity/digsig_asymmetric.c | 23 --------------------
>   security/integrity/ima/ima_main.c      | 29 ++++++++++++++++++++++++++
>   security/security.c                    |  2 +-
>   5 files changed, 40 insertions(+), 37 deletions(-)
> 
> diff --git a/include/linux/ima.h b/include/linux/ima.h
> index 31ef6c3c3207..0f9af283cbc8 100644
> --- a/include/linux/ima.h
> +++ b/include/linux/ima.h
> @@ -256,4 +256,14 @@ static inline bool ima_appraise_signature(enum kernel_read_file_id func)
>   	return false;
>   }
>   #endif /* CONFIG_IMA_APPRAISE && CONFIG_INTEGRITY_TRUSTED_KEYRING */
> +
> +#if defined(CONFIG_IMA) && defined(CONFIG_INTEGRITY_ASYMMETRIC_KEYS)
> +extern int ima_kernel_module_request(char *kmod_name);
> +#else
> +static inline int ima_kernel_module_request(char *kmod_name)
> +{
> +	return 0;
> +}
> +
> +#endif
>   #endif /* _LINUX_IMA_H */
> diff --git a/include/linux/integrity.h b/include/linux/integrity.h
> index 2ea0f2f65ab6..ef0f63ef5ebc 100644
> --- a/include/linux/integrity.h
> +++ b/include/linux/integrity.h
> @@ -42,17 +42,4 @@ static inline void integrity_load_keys(void)
>   }
>   #endif /* CONFIG_INTEGRITY */
>   
> -#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
> -
> -extern int integrity_kernel_module_request(char *kmod_name);
> -
> -#else
> -
> -static inline int integrity_kernel_module_request(char *kmod_name)
> -{
> -	return 0;
> -}
> -
> -#endif /* CONFIG_INTEGRITY_ASYMMETRIC_KEYS */
> -
>   #endif /* _LINUX_INTEGRITY_H */
> diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
> index 895f4b9ce8c6..de603cf42ac7 100644
> --- a/security/integrity/digsig_asymmetric.c
> +++ b/security/integrity/digsig_asymmetric.c
> @@ -132,26 +132,3 @@ int asymmetric_verify(struct key *keyring, const char *sig,
>   	pr_debug("%s() = %d\n", __func__, ret);
>   	return ret;
>   }
> -
> -/**
> - * integrity_kernel_module_request - prevent crypto-pkcs1pad(rsa,*) requests
> - * @kmod_name: kernel module name
> - *
> - * We have situation, when public_key_verify_signature() in case of RSA
> - * algorithm use alg_name to store internal information in order to
> - * construct an algorithm on the fly, but crypto_larval_lookup() will try
> - * to use alg_name in order to load kernel module with same name.
> - * Since we don't have any real "crypto-pkcs1pad(rsa,*)" kernel modules,
> - * we are safe to fail such module request from crypto_larval_lookup().
> - *
> - * In this way we prevent modprobe execution during digsig verification
> - * and avoid possible deadlock if modprobe and/or it's dependencies
> - * also signed with digsig.
> - */
> -int integrity_kernel_module_request(char *kmod_name)
> -{
> -	if (strncmp(kmod_name, "crypto-pkcs1pad(rsa,", 20) == 0)
> -		return -EINVAL;
> -
> -	return 0;
> -}
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index 02021ee467d3..908fa026ec58 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -1091,6 +1091,35 @@ int ima_measure_critical_data(const char *event_label,
>   }
>   EXPORT_SYMBOL_GPL(ima_measure_critical_data);
>   
> +#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
> +
> +/**
> + * ima_kernel_module_request - Prevent crypto-pkcs1pad(rsa,*) requests
> + * @kmod_name: kernel module name
> + *
> + * We have situation, when public_key_verify_signature() in case of RSA > + * algorithm use alg_name to store internal information in order to
> + * construct an algorithm on the fly, but crypto_larval_lookup() will try
> + * to use alg_name in order to load kernel module with same name.
> + * Since we don't have any real "crypto-pkcs1pad(rsa,*)" kernel modules,
> + * we are safe to fail such module request from crypto_larval_lookup().
> + *
> + * In this way we prevent modprobe execution during digsig verification
> + * and avoid possible deadlock if modprobe and/or it's dependencies
> + * also signed with digsig.

This text needs to some reformulation at some point..

> + *
> + * Return: Zero if it is safe to load the kernel module, -EINVAL otherwise.
> + */
> +int ima_kernel_module_request(char *kmod_name)
> +{
> +	if (strncmp(kmod_name, "crypto-pkcs1pad(rsa,", 20) == 0)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +#endif /* CONFIG_INTEGRITY_ASYMMETRIC_KEYS */
> +
>   static int __init init_ima(void)
>   {
>   	int error;
> diff --git a/security/security.c b/security/security.c
> index d2a1226e6e69..6c6571a141a1 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -3255,7 +3255,7 @@ int security_kernel_module_request(char *kmod_name)
>   	ret = call_int_hook(kernel_module_request, 0, kmod_name);
>   	if (ret)
>   		return ret;
> -	return integrity_kernel_module_request(kmod_name);
> +	return ima_kernel_module_request(kmod_name);
>   }
>   
>   /**

Reviewed-by: Stefan Berger <stefanb at linux.ibm.com>



More information about the Linux-security-module-archive mailing list