From 31d47588cdee9850a11347b8b5dfdcfeaad0124a Mon Sep 17 00:00:00 2001 From: Jeremy Cline Date: Apr 12 2019 19:56:50 +0000 Subject: Enforce module signatures in lockdown (rhbz #1696671) --- diff --git a/efi-lockdown.patch b/efi-lockdown.patch index a4b602b..775a64d 100644 --- a/efi-lockdown.patch +++ b/efi-lockdown.patch @@ -518,6 +518,109 @@ index f35ffdd096ad..2615669dbf03 100644 -- 2.14.3 +From e5709852ca1e9ed443d9abebcb35cbc2f0d9d987 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Mon, 18 Feb 2019 12:44:58 +0000 +Subject: [PATCH 02/27] Enforce module signatures if the kernel is locked down + +If the kernel is locked down, require that all modules have valid +signatures that we can verify. + +I have adjusted the errors generated: + + (1) If there's no signature (ENODATA) or we can't check it (ENOPKG, + ENOKEY), then: + + (a) If signatures are enforced then EKEYREJECTED is returned. + + (b) If there's no signature or we can't check it, but the kernel is + locked down then EPERM is returned (this is then consistent with + other lockdown cases). + + (2) If the signature is unparseable (EBADMSG, EINVAL), the signature fails + the check (EKEYREJECTED) or a system error occurs (eg. ENOMEM), we + return the error we got. + +Note that the X.509 code doesn't check for key expiry as the RTC might not +be valid or might not have been transferred to the kernel's clock yet. + + [Modified by Matthew Garrett to remove the IMA integration. This will + be replaced with integration with the IMA architecture policy + patchset.] + +Signed-off-by: David Howells +Reviewed-by: Jiri Bohac +Signed-off-by: Matthew Garrett +Cc: Jessica Yu +--- + kernel/module.c | 39 ++++++++++++++++++++++++++++++++------- + 1 file changed, 32 insertions(+), 7 deletions(-) + +diff --git a/kernel/module.c b/kernel/module.c +index 2ad1b5239910..9a377c6ea200 100644 +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -2767,8 +2767,9 @@ static inline void kmemleak_load_module(const struct module *mod, + #ifdef CONFIG_MODULE_SIG + static int module_sig_check(struct load_info *info, int flags) + { +- int err = -ENOKEY; ++ int err = -ENODATA; + const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; ++ const char *reason; + const void *mod = info->hdr; + + /* +@@ -2783,16 +2784,40 @@ static int module_sig_check(struct load_info *info, int flags) + err = mod_verify_sig(mod, info); + } + +- if (!err) { ++ switch (err) { ++ case 0: + info->sig_ok = true; + return 0; +- } + +- /* Not having a signature is only an error if we're strict. */ +- if (err == -ENOKEY && !is_module_sig_enforced()) +- err = 0; ++ /* We don't permit modules to be loaded into trusted kernels ++ * without a valid signature on them, but if we're not ++ * enforcing, certain errors are non-fatal. ++ */ ++ case -ENODATA: ++ reason = "Loading of unsigned module"; ++ goto decide; ++ case -ENOPKG: ++ reason = "Loading of module with unsupported crypto"; ++ goto decide; ++ case -ENOKEY: ++ reason = "Loading of module with unavailable key"; ++ decide: ++ if (is_module_sig_enforced()) { ++ pr_notice("%s is rejected\n", reason); ++ return -EKEYREJECTED; ++ } + +- return err; ++ if (kernel_is_locked_down(reason)) ++ return -EPERM; ++ return 0; ++ ++ /* All other errors are fatal, including nomem, unparseable ++ * signatures and signature check failures - even if signatures ++ * aren't required. ++ */ ++ default: ++ return err; ++ } + } + #else /* !CONFIG_MODULE_SIG */ + static int module_sig_check(struct load_info *info, int flags) +-- +2.21.0 + From 7948946e19294e7560c81b177b2788d21ed79f59 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Mon, 9 Apr 2018 09:52:46 +0100