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@xxxxxxxxxxxxx> --- 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; } -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