[PATCH] x86/ima: require signed kernel modules

Mimi Zohar zohar at linux.ibm.com
Mon Feb 11 16:19:04 UTC 2019


On Mon, 2019-02-11 at 16:56 +0100, Jessica Yu wrote:
> +++ Mimi Zohar [31/01/19 14:18 -0500]:
> >Require signed kernel modules on systems with secure boot mode enabled.
> >
> >To coordinate between appended kernel module signatures and IMA
> >signatures, only define an IMA MODULE_CHECK policy rule if
> >CONFIG_MODULE_SIG is not enabled.
> >
> >This patch defines a function named set_module_sig_required() and renames
> >is_module_sig_enforced() to is_module_sig_enforced_or_required().  The
> >call to set_module_sig_required() is dependent on CONFIG_IMA_ARCH_POLICY
> >being enabled.
> >
> >Signed-off-by: Mimi Zohar <zohar at linux.ibm.com>
> >---
> > arch/x86/kernel/ima_arch.c        |  9 ++++++++-
> > include/linux/module.h            |  7 ++++++-
> > kernel/module.c                   | 15 +++++++++++----
> > security/integrity/ima/ima_main.c |  2 +-
> > 4 files changed, 26 insertions(+), 7 deletions(-)
> >
> >diff --git a/arch/x86/kernel/ima_arch.c b/arch/x86/kernel/ima_arch.c
> >index e47cd9390ab4..96a023238a83 100644
> >--- a/arch/x86/kernel/ima_arch.c
> >+++ b/arch/x86/kernel/ima_arch.c
> >@@ -64,12 +64,19 @@ static const char * const sb_arch_rules[] = {
> > 	"appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig",
> > #endif /* CONFIG_KEXEC_VERIFY_SIG */
> > 	"measure func=KEXEC_KERNEL_CHECK",
> >+#if !IS_ENABLED(CONFIG_MODULE_SIG)
> >+	"appraise func=MODULE_CHECK appraise_type=imasig",
> >+#endif
> >+	"measure func=MODULE_CHECK",
> > 	NULL
> > };
> >
> > const char * const *arch_get_ima_policy(void)
> > {
> >-	if (IS_ENABLED(CONFIG_IMA_ARCH_POLICY) && arch_ima_get_secureboot())
> >+	if (IS_ENABLED(CONFIG_IMA_ARCH_POLICY) && arch_ima_get_secureboot()) {
> >+		if (IS_ENABLED(CONFIG_MODULE_SIG))
> >+			set_module_sig_required();
> > 		return sb_arch_rules;
> >+	}
> > 	return NULL;
> > }
> >diff --git a/include/linux/module.h b/include/linux/module.h
> >index 8fa38d3e7538..af51c8ec755f 100644
> >--- a/include/linux/module.h
> >+++ b/include/linux/module.h
> >@@ -659,7 +659,8 @@ static inline bool is_livepatch_module(struct module *mod)
> > }
> > #endif /* CONFIG_LIVEPATCH */
> >
> >-bool is_module_sig_enforced(void);
> >+bool is_module_sig_enforced_or_required(void);
> >+void set_module_sig_required(void);
> >
> > #else /* !CONFIG_MODULES... */
> >
> >@@ -780,6 +781,10 @@ static inline bool is_module_sig_enforced(void)
> > 	return false;
> > }
> >
> >+static inline void set_module_sig_required(void)
> >+{
> >+}
> >+
> > /* Dereference module function descriptor */
> > static inline
> > void *dereference_module_function_descriptor(struct module *mod, void *ptr)
> >diff --git a/kernel/module.c b/kernel/module.c
> >index 2ad1b5239910..70a9709d19eb 100644
> >--- a/kernel/module.c
> >+++ b/kernel/module.c
> >@@ -275,16 +275,23 @@ static void module_assert_mutex_or_preempt(void)
> >
> > static bool sig_enforce = IS_ENABLED(CONFIG_MODULE_SIG_FORCE);
> > module_param(sig_enforce, bool_enable_only, 0644);
> >+static bool sig_required;
> >
> > /*
> >  * Export sig_enforce kernel cmdline parameter to allow other subsystems rely
> >  * on that instead of directly to CONFIG_MODULE_SIG_FORCE config.
> >  */
> >-bool is_module_sig_enforced(void)
> >+bool is_module_sig_enforced_or_required(void)
> > {
> >-	return sig_enforce;
> >+	return sig_enforce || sig_required;
> > }
> 
> Hi Mimi,
> 
> Just wondering, is there any particular reason why a distinction is
> made between sig_enforce and sig_required? Doesn't sig_enforce imply
> that signed modules are required? In other words, why introduce
> another variable instead of just using sig_enforce? It may be
> confusing in the case of a user looking at /sys/module/module/parameters/sig_enforce
> and it having a value of 0 yet module signatures are being required by ima.

Hi Jessica,

It would definitely be a lot better not having to differentiate
between the builtin CONFIG/module parm enforced and runtime enforced.
 For some reason the "lockdown" patch doesn't directly modify
sig_enforce.

Mimi

> 
> >-EXPORT_SYMBOL(is_module_sig_enforced);
> >+EXPORT_SYMBOL(is_module_sig_enforced_or_required);
> >+
> >+void set_module_sig_required(void)
> >+{
> >+	sig_required = true;
> >+}
> >+EXPORT_SYMBOL(set_module_sig_required);
> >
> > /* Block module loading/unloading? */
> > int modules_disabled = 0;
> >@@ -2789,7 +2796,7 @@ static int module_sig_check(struct load_info *info, int flags)
> > 	}
> >
> > 	/* Not having a signature is only an error if we're strict. */
> >-	if (err == -ENOKEY && !is_module_sig_enforced())
> >+	if (err == -ENOKEY && !is_module_sig_enforced_or_required())
> > 		err = 0;
> >
> > 	return err;
> >diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> >index 357edd140c09..bbaf87f688be 100644
> >--- a/security/integrity/ima/ima_main.c
> >+++ b/security/integrity/ima/ima_main.c
> >@@ -563,7 +563,7 @@ int ima_load_data(enum kernel_load_data_id id)
> > 		}
> > 		break;
> > 	case LOADING_MODULE:
> >-		sig_enforce = is_module_sig_enforced();
> >+		sig_enforce = is_module_sig_enforced_or_required();
> >
> > 		if (ima_enforce && (!sig_enforce
> > 				    && (ima_appraise & IMA_APPRAISE_MODULES))) {
> >-- 
> >2.7.5
> >
> 



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