Message ID | 20190306235913.6631-4-matthewgarrett@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [PULL,REQUEST] Kernel lockdown patches for 5.2 | expand |
On Wed, 6 Mar 2019, Matthew Garrett wrote: > From: David Howells <dhowells@redhat.com> > > If the kernel is locked down, require that all modules have valid > signatures that we can verify. Perhaps note that this won't cover the case where folk are using DM-Verity with a signed root hash for verifying kernel modules.
On Fri, Mar 8, 2019 at 3:00 PM James Morris <jmorris@namei.org> wrote: > > On Wed, 6 Mar 2019, Matthew Garrett wrote: > > > From: David Howells <dhowells@redhat.com> > > > > If the kernel is locked down, require that all modules have valid > > signatures that we can verify. > > Perhaps note that this won't cover the case where folk are using DM-Verity > with a signed root hash for verifying kernel modules. Mm. I can't see a terribly good way of doing this generically - loadpin gives no indication to the module loading code that it comes from a trusted source. Would making the lockdown/module signature enforcement a separate config option be reasonable?
On Fri, 8 Mar 2019, Matthew Garrett wrote: > On Fri, Mar 8, 2019 at 3:00 PM James Morris <jmorris@namei.org> wrote: > > > > On Wed, 6 Mar 2019, Matthew Garrett wrote: > > > > > From: David Howells <dhowells@redhat.com> > > > > > > If the kernel is locked down, require that all modules have valid > > > signatures that we can verify. > > > > Perhaps note that this won't cover the case where folk are using DM-Verity > > with a signed root hash for verifying kernel modules. > > Mm. I can't see a terribly good way of doing this generically - > loadpin gives no indication to the module loading code that it comes > from a trusted source. Would making the lockdown/module signature > enforcement a separate config option be reasonable? I was just suggest documenting this.
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)