From: Matthew Garrett <hidden> Date: 2019-07-18 19:44:21
Minor changes to the previous set, other than a significant rework of
the "Ignore acpi_rsdp kernel param" patch to deal with the early parsing
of that parameter under certain circumstances.
From: Matthew Garrett <hidden> Date: 2019-07-18 19:44:25
The lockdown module is intended to allow for kernels to be locked down
early in boot - sufficiently early that we don't have the ability to
kmalloc() yet. Add support for early initialisation of some LSMs, and
then add them to the list of names when we do full initialisation later.
Early LSMs are initialised in link order and cannot be overridden via
boot parameters, and cannot make use of kmalloc() (since the allocator
isn't initialised yet).
Signed-off-by: Matthew Garrett <redacted>
Acked-by: Kees Cook <redacted>
---
include/asm-generic/vmlinux.lds.h | 8 ++++-
include/linux/lsm_hooks.h | 6 ++++
include/linux/security.h | 1 +
init/main.c | 1 +
security/security.c | 50 ++++++++++++++++++++++++++-----
5 files changed, 57 insertions(+), 9 deletions(-)
@@ -33,6 +33,7 @@/* How many LSMs were built into the kernel? */#define LSM_COUNT (__end_lsm_info - __start_lsm_info)+#define EARLY_LSM_COUNT (__end_early_lsm_info - __start_early_lsm_info)structsecurity_hook_headssecurity_hook_heads__lsm_ro_after_init;staticBLOCKING_NOTIFIER_HEAD(blocking_lsm_notifier_chain);
@@ -422,8 +449,15 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,hooks[i].lsm=lsm;hlist_add_tail_rcu(&hooks[i].list,hooks[i].head);}-if(lsm_append(lsm,&lsm_names)<0)-panic("%s - Cannot get early memory.\n",__func__);++/*+*Don'ttrytoappendduringearly_security_init(),we'llcomeback+*andfixthisupafterwards.+*/+if(slab_is_available()){+if(lsm_append(lsm,&lsm_names)<0)+panic("%s - Cannot get early memory.\n",__func__);+}}intcall_blocking_lsm_notifier(enumlsm_eventevent,void*data)
The lockdown module is intended to allow for kernels to be locked down
early in boot - sufficiently early that we don't have the ability to
kmalloc() yet. Add support for early initialisation of some LSMs, and
then add them to the list of names when we do full initialisation later.
Early LSMs are initialised in link order and cannot be overridden via
boot parameters, and cannot make use of kmalloc() (since the allocator
isn't initialised yet).
Signed-off-by: Matthew Garrett <redacted>
Acked-by: Kees Cook <redacted>
@@ -33,6 +33,7 @@/* How many LSMs were built into the kernel? */#define LSM_COUNT (__end_lsm_info - __start_lsm_info)+#define EARLY_LSM_COUNT (__end_early_lsm_info - __start_early_lsm_info)structsecurity_hook_headssecurity_hook_heads__lsm_ro_after_init;staticBLOCKING_NOTIFIER_HEAD(blocking_lsm_notifier_chain);
@@ -422,8 +449,15 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,hooks[i].lsm=lsm;hlist_add_tail_rcu(&hooks[i].list,hooks[i].head);}-if(lsm_append(lsm,&lsm_names)<0)-panic("%s - Cannot get early memory.\n",__func__);++/*+*Don'ttrytoappendduringearly_security_init(),we'llcomeback+*andfixthisupafterwards.+*/+if(slab_is_available()){+if(lsm_append(lsm,&lsm_names)<0)+panic("%s - Cannot get early memory.\n",__func__);+}}intcall_blocking_lsm_notifier(enumlsm_eventevent,void*data)
From: Matthew Garrett <hidden> Date: 2019-07-18 19:44:28
Add a mechanism to allow LSMs to make a policy decision around whether
kernel functionality that would allow tampering with or examining the
runtime state of the kernel should be permitted.
Signed-off-by: Matthew Garrett <redacted>
Acked-by: Kees Cook <redacted>
---
include/linux/lsm_hooks.h | 2 ++
include/linux/security.h | 32 ++++++++++++++++++++++++++++++++
security/security.c | 6 ++++++
3 files changed, 40 insertions(+)
@@ -77,6 +77,33 @@ enum lsm_event {LSM_POLICY_CHANGE,};+/*+*Thesearereasonsthatcanbepassedtothesecurity_locked_down()+*LSMhook.Lockdownreasonsthatprotectkernelintegrity(ie,the+*abilityforuserlandtomodifykernelcode)areplacedbefore+*LOCKDOWN_INTEGRITY_MAX.Lockdownreasonsthatprotectkernel+*confidentiality(ie,theabilityforuserlandtoextract+*informationfromtherunningkernelthatwouldotherwisebe+*restricted)areplacedbeforeLOCKDOWN_CONFIDENTIALITY_MAX.+*+*LSMauthorsshouldnotethatthesemanticsofanygivenlockdown+*reasonarenotguaranteedtobestable-thesamereasonmayblock+*onesetoffeaturesinonekernelrelease,andaslightlydifferent+*setoffeaturesinalaterkernelrelease.LSMsthatseektoexpose+*lockdownpolicyatanylevelofgranularityotherthan"none",+*"integrity"or"confidentiality"areresponsibleforeither+*ensuringthattheyexposeaconsistentleveloffunctionalityto+*userland,orensuringthatuserlandisawarethatthisis+*potentiallyamovingtarget.Itiseasytomisusethisinformation+*inawaythatcouldbreakuserspace.Pleasebecarefulnottodo+*so.+*/+enumlockdown_reason{+LOCKDOWN_NONE,+LOCKDOWN_INTEGRITY_MAX,+LOCKDOWN_CONFIDENTIALITY_MAX,+};+/* These functions are in security/commoncap.c */externintcap_capable(conststructcred*cred,structuser_namespace*ns,intcap,unsignedintopts);
Add a mechanism to allow LSMs to make a policy decision around whether
kernel functionality that would allow tampering with or examining the
runtime state of the kernel should be permitted.
Signed-off-by: Matthew Garrett <redacted>
Acked-by: Kees Cook <redacted>
@@ -77,6 +77,33 @@ enum lsm_event {LSM_POLICY_CHANGE,};+/*+*Thesearereasonsthatcanbepassedtothesecurity_locked_down()+*LSMhook.Lockdownreasonsthatprotectkernelintegrity(ie,the+*abilityforuserlandtomodifykernelcode)areplacedbefore+*LOCKDOWN_INTEGRITY_MAX.Lockdownreasonsthatprotectkernel+*confidentiality(ie,theabilityforuserlandtoextract+*informationfromtherunningkernelthatwouldotherwisebe+*restricted)areplacedbeforeLOCKDOWN_CONFIDENTIALITY_MAX.+*+*LSMauthorsshouldnotethatthesemanticsofanygivenlockdown+*reasonarenotguaranteedtobestable-thesamereasonmayblock+*onesetoffeaturesinonekernelrelease,andaslightlydifferent+*setoffeaturesinalaterkernelrelease.LSMsthatseektoexpose+*lockdownpolicyatanylevelofgranularityotherthan"none",+*"integrity"or"confidentiality"areresponsibleforeither+*ensuringthattheyexposeaconsistentleveloffunctionalityto+*userland,orensuringthatuserlandisawarethatthisis+*potentiallyamovingtarget.Itiseasytomisusethisinformation+*inawaythatcouldbreakuserspace.Pleasebecarefulnottodo+*so.+*/+enumlockdown_reason{+LOCKDOWN_NONE,+LOCKDOWN_INTEGRITY_MAX,+LOCKDOWN_CONFIDENTIALITY_MAX,+};+/* These functions are in security/commoncap.c */externintcap_capable(conststructcred*cred,structuser_namespace*ns,intcap,unsignedintopts);
From: Matthew Garrett <hidden> Date: 2019-07-18 19:44:31
While existing LSMs can be extended to handle lockdown policy,
distributions generally want to be able to apply a straightforward
static policy. This patch adds a simple LSM that can be configured to
reject either integrity or all lockdown queries, and can be configured
at runtime (through securityfs), boot time (via a kernel parameter) or
build time (via a kconfig option). Based on initial code by David
Howells.
Signed-off-by: Matthew Garrett <redacted>
Reviewed-by: Kees Cook <redacted>
Cc: David Howells <dhowells@redhat.com>
---
.../admin-guide/kernel-parameters.txt | 9 +
include/linux/security.h | 3 +
security/Kconfig | 11 +-
security/Makefile | 2 +
security/lockdown/Kconfig | 47 +++++
security/lockdown/Makefile | 1 +
security/lockdown/lockdown.c | 172 ++++++++++++++++++
7 files changed, 240 insertions(+), 5 deletions(-)
create mode 100644 security/lockdown/Kconfig
create mode 100644 security/lockdown/Makefile
create mode 100644 security/lockdown/lockdown.c
@@ -2248,6 +2248,15 @@ lockd.nlm_udpport=M [NFS] Assign UDP port. Format: <integer>+ lockdown= [SECURITY]+ { integrity | confidentiality }+ Enable the kernel lockdown feature. If set to+ integrity, kernel features that allow userland to+ modify the running kernel are disabled. If set to+ confidentiality, kernel features that allow userland+ to extract confidential information from the kernel+ are also disabled.+ locktorture.nreaders_stress= [KNL] Set the number of locking read-acquisition kthreads. Defaults to being automatically set based on the
@@ -276,11 +277,11 @@ endchoiceconfigLSMstring"Ordered list of enabled LSMs"-default"yama,loadpin,safesetid,integrity,smack,selinux,tomoyo,apparmor"ifDEFAULT_SECURITY_SMACK-default"yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo"ifDEFAULT_SECURITY_APPARMOR-default"yama,loadpin,safesetid,integrity,tomoyo"ifDEFAULT_SECURITY_TOMOYO-default"yama,loadpin,safesetid,integrity"ifDEFAULT_SECURITY_DAC-default"yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor"+default"lockdown,yama,loadpin,safesetid,integrity,smack,selinux,tomoyo,apparmor"ifDEFAULT_SECURITY_SMACK+default"lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo"ifDEFAULT_SECURITY_APPARMOR+default"lockdown,yama,loadpin,safesetid,integrity,tomoyo"ifDEFAULT_SECURITY_TOMOYO+default"lockdown,yama,loadpin,safesetid,integrity"ifDEFAULT_SECURITY_DAC+default"lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor"helpAcomma-separatedlistofLSMs,ininitializationorder.AnyLSMsleftoffthislistwillbeignored.Thiscanbe
@@ -0,0 +1,172 @@+// SPDX-License-Identifier: GPL-2.0+/* Lock down the kernel+*+*Copyright(C)2016RedHat,Inc.AllRightsReserved.+*WrittenbyDavidHowells(dhowells@redhat.com)+*+*Thisprogramisfreesoftware;youcanredistributeitand/or+*modifyitunderthetermsoftheGNUGeneralPublicLicence+*aspublishedbytheFreeSoftwareFoundation;eitherversion+*2oftheLicence,or(atyouroption)anylaterversion.+*/++#include<linux/security.h>+#include<linux/export.h>+#include<linux/lsm_hooks.h>++staticenumlockdown_reasonkernel_locked_down;++staticchar*lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1]={+[LOCKDOWN_NONE]="none",+[LOCKDOWN_INTEGRITY_MAX]="integrity",+[LOCKDOWN_CONFIDENTIALITY_MAX]="confidentiality",+};++staticenumlockdown_reasonlockdown_levels[]={LOCKDOWN_NONE,+LOCKDOWN_INTEGRITY_MAX,+LOCKDOWN_CONFIDENTIALITY_MAX};++/*+*Putthekernelintolock-downmode.+*/+staticintlock_kernel_down(constchar*where,enumlockdown_reasonlevel)+{+if(kernel_locked_down>=level)+return-EPERM;++kernel_locked_down=level;+pr_notice("Kernel is locked down from %s; see man kernel_lockdown.7\n",+where);+return0;+}++staticint__initlockdown_param(char*level)+{+if(!level)+return-EINVAL;++if(strcmp(level,"integrity")==0)+lock_kernel_down("command line",LOCKDOWN_INTEGRITY_MAX);+elseif(strcmp(level,"confidentiality")==0)+lock_kernel_down("command line",LOCKDOWN_CONFIDENTIALITY_MAX);+else+return-EINVAL;++return0;+}++early_param("lockdown",lockdown_param);++/**+*lockdown_is_locked_down-Findoutifthekernelislockeddown+*@what:Tagtouseinnoticegeneratediflockdownisineffect+*/+staticintlockdown_is_locked_down(enumlockdown_reasonwhat)+{+if(kernel_locked_down>=what){+if(lockdown_reasons[what])+pr_notice("Lockdown: %s is restricted; see man kernel_lockdown.7\n",+lockdown_reasons[what]);+return-EPERM;+}++return0;+}++staticstructsecurity_hook_listlockdown_hooks[]__lsm_ro_after_init={+LSM_HOOK_INIT(locked_down,lockdown_is_locked_down),+};++staticint__initlockdown_lsm_init(void)+{+#if defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY)+lock_kernel_down("Kernel configuration",LOCKDOWN_INTEGRITY_MAX);+#elif defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY)+lock_kernel_down("Kernel configuration",LOCKDOWN_CONFIDENTIALITY_MAX);+#endif+security_add_hooks(lockdown_hooks,ARRAY_SIZE(lockdown_hooks),+"lockdown");+return0;+}++staticssize_tlockdown_read(structfile*filp,char__user*buf,size_tcount,+loff_t*ppos)+{+chartemp[80];+inti,offset=0;++for(i=0;i<ARRAY_SIZE(lockdown_levels);i++){+enumlockdown_reasonlevel=lockdown_levels[i];++if(lockdown_reasons[level]){+constchar*label=lockdown_reasons[level];++if(kernel_locked_down==level)+offset+=sprintf(temp+offset,"[%s] ",label);+else+offset+=sprintf(temp+offset,"%s ",label);+}+}++/* Convert the last space to a newline if needed. */+if(offset>0)+temp[offset-1]='\n';++returnsimple_read_from_buffer(buf,count,ppos,temp,strlen(temp));+}++staticssize_tlockdown_write(structfile*file,constchar__user*buf,+size_tn,loff_t*ppos)+{+char*state;+inti,len,err=-EINVAL;++state=memdup_user_nul(buf,n);+if(IS_ERR(state))+returnPTR_ERR(state);++len=strlen(state);+if(len&&state[len-1]=='\n'){+state[len-1]='\0';+len--;+}++for(i=0;i<ARRAY_SIZE(lockdown_levels);i++){+enumlockdown_reasonlevel=lockdown_levels[i];+constchar*label=lockdown_reasons[level];++if(label&&!strcmp(state,label))+err=lock_kernel_down("securityfs",level);+}++kfree(state);+returnerr?err:n;+}++staticconststructfile_operationslockdown_ops={+.read=lockdown_read,+.write=lockdown_write,+};++staticint__initlockdown_secfs_init(void)+{+structdentry*dentry;++dentry=securityfs_create_file("lockdown",0600,NULL,NULL,+&lockdown_ops);+if(IS_ERR(dentry))+returnPTR_ERR(dentry);++return0;+}++core_initcall(lockdown_secfs_init);++#ifdef CONFIG_SECURITY_LOCKDOWN_LSM_EARLY+DEFINE_EARLY_LSM(lockdown)={+#else+DEFINE_LSM(lockdown)={+#endif+.name="lockdown",+.init=lockdown_lsm_init,+};
From: Matthew Garrett <hidden> Date: 2019-07-18 19:44:35
From: Matthew Garrett <mjg59@srcf.ucam.org>
Allowing users to read and write to core kernel memory makes it possible
for the kernel to be subverted, avoiding module loading restrictions, and
also to steal cryptographic information.
Disallow /dev/mem and /dev/kmem from being opened this when the kernel has
been locked down to prevent this.
Also disallow /dev/port from being opened to prevent raw ioport access and
thus DMA from being used to accomplish the same thing.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Matthew Garrett <redacted>
Reviewed-by: Kees Cook <redacted>
Cc: x86@kernel.org
---
drivers/char/mem.c | 7 +++++--
include/linux/security.h | 1 +
security/lockdown/lockdown.c | 1 +
3 files changed, 7 insertions(+), 2 deletions(-)
From: Matthew Garrett <hidden> Date: 2019-07-18 19:44:40
From: Matthew Garrett <mjg59@srcf.ucam.org>
The kexec_load() syscall permits the loading and execution of arbitrary
code in ring 0, which is something that lock-down is meant to prevent. It
makes sense to disable kexec_load() in this situation.
This does not affect kexec_file_load() syscall which can check for a
signature on the image to be booted.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Matthew Garrett <redacted>
Acked-by: Dave Young <redacted>
Reviewed-by: Kees Cook <redacted>
cc: kexec@lists.infradead.org
---
include/linux/security.h | 1 +
kernel/kexec.c | 8 ++++++++
security/lockdown/lockdown.c | 1 +
3 files changed, 10 insertions(+)
@@ -205,6 +205,14 @@ static inline int kexec_load_check(unsigned long nr_segments,if(result<0)returnresult;+/*+*kexeccanbeusedtocircumventmoduleloadingrestrictions,so+*preventloadinginthatcase+*/+result=security_locked_down(LOCKDOWN_KEXEC);+if(result)+returnresult;+/**Verifywehavealegalsetofflags*Thisleavesusroomforfutureextensions.
From: Matthew Garrett <hidden> Date: 2019-07-18 19:44:43
From: Dave Young <redacted>
Kexec reboot in case secure boot being enabled does not keep the secure
boot mode in new kernel, so later one can load unsigned kernel via legacy
kexec_load. In this state, the system is missing the protections provided
by secure boot.
Adding a patch to fix this by retain the secure_boot flag in original
kernel.
secure_boot flag in boot_params is set in EFI stub, but kexec bypasses the
stub. Fixing this issue by copying secure_boot flag across kexec reboot.
Signed-off-by: Dave Young <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Matthew Garrett <redacted>
Reviewed-by: Kees Cook <redacted>
cc: kexec@lists.infradead.org
---
arch/x86/kernel/kexec-bzimage64.c | 1 +
1 file changed, 1 insertion(+)
From: Matthew Garrett <hidden> Date: 2019-07-18 19:44:47
From: Jiri Bohac <redacted>
When KEXEC_SIG is not enabled, kernel should not load images through
kexec_file systemcall if the kernel is locked down.
[Modified by David Howells to fit with modifications to the previous patch
and to return -EPERM if the kernel is locked down for consistency with
other lockdowns. Modified by Matthew Garrett to remove the IMA
integration, which will be replaced by integrating with the IMA
architecture policy patches.]
Signed-off-by: Jiri Bohac <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Matthew Garrett <redacted>
Reviewed-by: Jiri Bohac <redacted>
Reviewed-by: Kees Cook <redacted>
cc: kexec@lists.infradead.org
---
kernel/kexec_file.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
@@ -228,7 +228,10 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,gotoout;}-ret=0;+ret=security_locked_down(LOCKDOWN_KEXEC);+if(ret)+gotoout;+break;/* All other errors are fatal, including nomem, unparseable
From: Matthew Garrett <hidden> Date: 2019-07-18 19:44:50
From: Matthew Garrett <mjg59@srcf.ucam.org>
Any hardware that can potentially generate DMA has to be locked down in
order to avoid it being possible for an attacker to modify kernel code,
allowing them to circumvent disabled module loading or module signing.
Default to paranoid - in future we can potentially relax this for
sufficiently IOMMU-isolated devices.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Matthew Garrett <redacted>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Kees Cook <redacted>
cc: linux-pci@vger.kernel.org
---
drivers/pci/pci-sysfs.c | 16 ++++++++++++++++
drivers/pci/proc.c | 14 ++++++++++++--
drivers/pci/syscall.c | 4 +++-
include/linux/security.h | 1 +
security/lockdown/lockdown.c | 1 +
5 files changed, 33 insertions(+), 3 deletions(-)
From: Matthew Garrett <hidden> Date: 2019-07-18 19:44:58
From: Matthew Garrett <mjg59@srcf.ucam.org>
custom_method effectively allows arbitrary access to system memory, making
it possible for an attacker to circumvent restrictions on module loading.
Disable it if the kernel is locked down.
Signed-off-by: Matthew Garrett <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Kees Cook <redacted>
cc: linux-acpi@vger.kernel.org
---
drivers/acpi/custom_method.c | 6 ++++++
include/linux/security.h | 1 +
security/lockdown/lockdown.c | 1 +
3 files changed, 8 insertions(+)
From: Matthew Garrett <hidden> Date: 2019-07-18 19:45:01
From: Matthew Garrett <mjg59@srcf.ucam.org>
Writing to MSRs should not be allowed if the kernel is locked down, since
it could lead to execution of arbitrary code in kernel mode. Based on a
patch by Kees Cook.
Signed-off-by: Matthew Garrett <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Kees Cook <redacted>
Reviewed-by: Thomas Gleixner <redacted>
cc: x86@kernel.org
---
arch/x86/kernel/msr.c | 8 ++++++++
include/linux/security.h | 1 +
security/lockdown/lockdown.c | 1 +
3 files changed, 10 insertions(+)
@@ -130,6 +135,9 @@ static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)err=-EFAULT;break;}+err=security_locked_down(LOCKDOWN_MSR);+if(err)+break;err=wrmsr_safe_regs_on_cpu(cpu,regs);if(err)break;
From: Matthew Garrett <hidden> Date: 2019-07-18 19:45:10
From: David Howells <dhowells@redhat.com>
Lock down TIOCSSERIAL as that can be used to change the ioport and irq
settings on a serial port. This only appears to be an issue for the serial
drivers that use the core serial code. All other drivers seem to either
ignore attempts to change port/irq or give an error.
Reported-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Matthew Garrett <redacted>
Reviewed-by: Kees Cook <redacted>
cc: Jiri Slaby <redacted>
Cc: linux-serial@vger.kernel.org
---
drivers/tty/serial/serial_core.c | 5 +++++
include/linux/security.h | 1 +
security/lockdown/lockdown.c | 1 +
3 files changed, 7 insertions(+)
From: Matthew Garrett <hidden> Date: 2019-07-18 19:45:14
From: David Howells <dhowells@redhat.com>
The testmmiotrace module shouldn't be permitted when the kernel is locked
down as it can be used to arbitrarily read and write MMIO space. This is
a runtime check rather than buildtime in order to allow configurations
where the same kernel may be run in both locked down or permissive modes
depending on local policy.
Suggested-by: Thomas Gleixner <redacted>
Signed-off-by: David Howells <dhowells@redhat.com
Signed-off-by: Matthew Garrett <redacted>
Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
cc: Thomas Gleixner <redacted>
cc: Steven Rostedt <rostedt@goodmis.org>
cc: Ingo Molnar <mingo@kernel.org>
cc: "H. Peter Anvin" <hpa@zytor.com>
cc: x86@kernel.org
---
arch/x86/mm/testmmiotrace.c | 5 +++++
include/linux/security.h | 1 +
security/lockdown/lockdown.c | 1 +
3 files changed, 7 insertions(+)
@@ -115,6 +116,10 @@ static void do_test_bulk_ioremapping(void)staticint__initinit(void){unsignedlongsize=(read_far)?(8<<20):(16<<10);+intret=security_locked_down(LOCKDOWN_MMIOTRACE);++if(ret)+returnret;if(mmio_address==0){pr_err("you have to use the module argument mmio_address.\n");
On Thu, Jul 18, 2019 at 12:44:06PM -0700, Matthew Garrett wrote:
From: David Howells <dhowells@redhat.com>
The testmmiotrace module shouldn't be permitted when the kernel is locked
down as it can be used to arbitrarily read and write MMIO space. This is
a runtime check rather than buildtime in order to allow configurations
where the same kernel may be run in both locked down or permissive modes
depending on local policy.
Suggested-by: Thomas Gleixner <redacted>
Signed-off-by: David Howells <dhowells@redhat.com
Reviewed-by: Kees Cook <redacted>
-Kees
quoted hunk
Signed-off-by: Matthew Garrett <redacted>
Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
cc: Thomas Gleixner <redacted>
cc: Steven Rostedt <rostedt@goodmis.org>
cc: Ingo Molnar <mingo@kernel.org>
cc: "H. Peter Anvin" <hpa@zytor.com>
cc: x86@kernel.org
---
arch/x86/mm/testmmiotrace.c | 5 +++++
include/linux/security.h | 1 +
security/lockdown/lockdown.c | 1 +
3 files changed, 7 insertions(+)
@@ -115,6 +116,10 @@ static void do_test_bulk_ioremapping(void)staticint__initinit(void){unsignedlongsize=(read_far)?(8<<20):(16<<10);+intret=security_locked_down(LOCKDOWN_MMIOTRACE);++if(ret)+returnret;if(mmio_address==0){pr_err("you have to use the module argument mmio_address.\n");
From: Matthew Garrett <hidden> Date: 2019-07-18 19:45:17
From: David Howells <dhowells@redhat.com>
Disallow access to /proc/kcore when the kernel is locked down to prevent
access to cryptographic data. This is limited to lockdown
confidentiality mode and is still permitted in integrity mode.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Matthew Garrett <redacted>
Reviewed-by: Kees Cook <redacted>
---
fs/proc/kcore.c | 5 +++++
include/linux/security.h | 1 +
security/lockdown/lockdown.c | 1 +
3 files changed, 7 insertions(+)
From: Matthew Garrett <hidden> Date: 2019-07-18 19:45:20
From: David Howells <dhowells@redhat.com>
Disallow the creation of perf and ftrace kprobes when the kernel is
locked down in confidentiality mode by preventing their registration.
This prevents kprobes from being used to access kernel memory to steal
crypto data, but continues to allow the use of kprobes from signed
modules.
Reported-by: Alexei Starovoitov <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Matthew Garrett <redacted>
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
Reviewed-by: Kees Cook <redacted>
Cc: Naveen N. Rao <redacted>
Cc: Anil S Keshavamurthy <redacted>
Cc: davem@davemloft.net
Cc: Masami Hiramatsu <mhiramat@kernel.org>
---
include/linux/security.h | 1 +
kernel/trace/trace_kprobe.c | 5 +++++
security/lockdown/lockdown.c | 1 +
3 files changed, 7 insertions(+)
From: Matthew Garrett <hidden> Date: 2019-07-18 19:45:24
From: David Howells <dhowells@redhat.com>
bpf_read() and bpf_read_str() could potentially be abused to (eg) allow
private keys in kernel memory to be leaked. Disable them if the kernel
has been locked down in confidentiality mode.
Suggested-by: Alexei Starovoitov <redacted>
Signed-off-by: Matthew Garrett <redacted>
cc: netdev@vger.kernel.org
cc: Chun-Yi Lee <jlee@suse.com>
cc: Alexei Starovoitov <redacted>
Cc: Daniel Borkmann <daniel@iogearbox.net>
---
include/linux/security.h | 1 +
kernel/trace/bpf_trace.c | 10 ++++++++++
security/lockdown/lockdown.c | 1 +
3 files changed, 12 insertions(+)
On Thu, Jul 18, 2019 at 12:44:09PM -0700, Matthew Garrett wrote:
From: David Howells <dhowells@redhat.com>
bpf_read() and bpf_read_str() could potentially be abused to (eg) allow
private keys in kernel memory to be leaked. Disable them if the kernel
has been locked down in confidentiality mode.
Suggested-by: Alexei Starovoitov <redacted>
Signed-off-by: Matthew Garrett <redacted>
From: Matthew Garrett <hidden> Date: 2019-07-29 21:47:18
On Thu, Jul 18, 2019 at 12:45 PM Matthew Garrett
[off-list ref] wrote:
bpf_read() and bpf_read_str() could potentially be abused to (eg) allow
private keys in kernel memory to be leaked. Disable them if the kernel
has been locked down in confidentiality mode.
Suggested-by: Alexei Starovoitov <redacted>
Signed-off-by: Matthew Garrett <redacted>
cc: netdev@vger.kernel.org
cc: Chun-Yi Lee <jlee@suse.com>
cc: Alexei Starovoitov <redacted>
Cc: Daniel Borkmann <daniel@iogearbox.net>
@@ -10806,6 +10806,13 @@ SYSCALL_DEFINE5(perf_event_open,perf_paranoid_kernel()&&!capable(CAP_SYS_ADMIN))return-EACCES;+err=security_locked_down(LOCKDOWN_PERF);+if(err&&(attr.sample_type&PERF_SAMPLE_REGS_INTR))+/* REGS_INTR can leak data, lockdown must prevent this */+returnerr;++err=0;+/**Incgroupmode,thepidargumentisusedtopassthefd*openedtothecgroupdirectoryincgroupfs.Thecpuargument
@@ -34,6 +34,7 @@ static char *lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {[LOCKDOWN_KCORE]="/proc/kcore access",[LOCKDOWN_KPROBES]="use of kprobes",[LOCKDOWN_BPF_READ]="use of bpf to read kernel RAM",+[LOCKDOWN_PERF]="unsafe use of perf",[LOCKDOWN_CONFIDENTIALITY_MAX]="confidentiality",};
From: Matthew Garrett <hidden> Date: 2019-07-18 19:45:33
Tracefs may release more information about the kernel than desirable, so
restrict it when the kernel is locked down in confidentiality mode by
preventing open().
Signed-off-by: Matthew Garrett <redacted>
Cc: Steven Rostedt <rostedt@goodmis.org>
---
fs/tracefs/inode.c | 38 +++++++++++++++++++++++++++++++++++-
include/linux/security.h | 1 +
security/lockdown/lockdown.c | 1 +
3 files changed, 39 insertions(+), 1 deletion(-)
@@ -36,6 +36,7 @@ static char *lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {[LOCKDOWN_KPROBES]="use of kprobes",[LOCKDOWN_BPF_READ]="use of bpf to read kernel RAM",[LOCKDOWN_PERF]="unsafe use of perf",+[LOCKDOWN_TRACEFS]="use of tracefs",[LOCKDOWN_CONFIDENTIALITY_MAX]="confidentiality",};
From: Matthew Garrett <hidden> Date: 2019-07-30 18:47:42
Tracefs may release more information about the kernel than desirable, so
restrict it when the kernel is locked down in confidentiality mode by
preventing open().
Signed-off-by: Matthew Garrett <redacted>
Cc: Steven Rostedt <rostedt@goodmis.org>
---
Added the iput()
fs/tracefs/inode.c | 40 +++++++++++++++++++++++++++++++++++-
include/linux/security.h | 1 +
security/lockdown/lockdown.c | 1 +
3 files changed, 41 insertions(+), 1 deletion(-)
@@ -36,6 +36,7 @@ static char *lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {[LOCKDOWN_KPROBES]="use of kprobes",[LOCKDOWN_BPF_READ]="use of bpf to read kernel RAM",[LOCKDOWN_PERF]="unsafe use of perf",+[LOCKDOWN_TRACEFS]="use of tracefs",[LOCKDOWN_CONFIDENTIALITY_MAX]="confidentiality",};
From: Steven Rostedt <rostedt@goodmis.org> Date: 2019-07-31 01:48:11
On Tue, 30 Jul 2019 11:47:34 -0700
Matthew Garrett [off-list ref] wrote:
Tracefs may release more information about the kernel than desirable, so
restrict it when the kernel is locked down in confidentiality mode by
preventing open().
Signed-off-by: Matthew Garrett <redacted>
Cc: Steven Rostedt <rostedt@goodmis.org>
Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
-- Steve
From: Matthew Garrett <hidden> Date: 2019-07-18 19:45:36
Print the content of current->comm in messages generated by lockdown to
indicate a restriction that was hit. This makes it a bit easier to find
out what caused the message.
The message now patterned something like:
Lockdown: <comm>: <what> is restricted; see man kernel_lockdown.7
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Matthew Garrett <redacted>
Reviewed-by: Kees Cook <redacted>
---
fs/proc/kcore.c | 5 +++--
security/lockdown/lockdown.c | 8 ++++++--
2 files changed, 9 insertions(+), 4 deletions(-)
@@ -81,10 +81,14 @@ early_param("lockdown", lockdown_param);*/staticintlockdown_is_locked_down(enumlockdown_reasonwhat){+if(WARN(what>=LOCKDOWN_CONFIDENTIALITY_MAX,+"Invalid lockdown reason"))+return-EPERM;+if(kernel_locked_down>=what){if(lockdown_reasons[what])-pr_notice("Lockdown: %s is restricted; see man kernel_lockdown.7\n",-lockdown_reasons[what]);+pr_notice("Lockdown: %s: %s is restricted; see man kernel_lockdown.7\n",+current->comm,lockdown_reasons[what]);return-EPERM;}
From: Matthew Garrett <hidden> Date: 2019-07-18 19:45:44
efivar_ssdt_load allows the kernel to import arbitrary ACPI code from an
EFI variable, which gives arbitrary code execution in ring 0. Prevent
that when the kernel is locked down.
Signed-off-by: Matthew Garrett <redacted>
Acked-by: Ard Biesheuvel <redacted>
Reviewed-by: Kees Cook <redacted>
Cc: Ard Biesheuvel <redacted>
Cc: linux-efi@vger.kernel.org
---
drivers/firmware/efi/efi.c | 6 ++++++
1 file changed, 6 insertions(+)
From: Matthew Garrett <hidden> Date: 2019-07-18 19:45:53
From: David Howells <dhowells@redhat.com>
Disallow opening of debugfs files that might be used to muck around when
the kernel is locked down as various drivers give raw access to hardware
through debugfs. Given the effort of auditing all 2000 or so files and
manually fixing each one as necessary, I've chosen to apply a heuristic
instead. The following changes are made:
(1) chmod and chown are disallowed on debugfs objects (though the root dir
can be modified by mount and remount, but I'm not worried about that).
(2) When the kernel is locked down, only files with the following criteria
are permitted to be opened:
- The file must have mode 00444
- The file must not have ioctl methods
- The file must not have mmap
(3) When the kernel is locked down, files may only be opened for reading.
Normal device interaction should be done through configfs, sysfs or a
miscdev, not debugfs.
Note that this makes it unnecessary to specifically lock down show_dsts(),
show_devs() and show_call() in the asus-wmi driver.
I would actually prefer to lock down all files by default and have the
the files unlocked by the creator. This is tricky to manage correctly,
though, as there are 19 creation functions and ~1600 call sites (some of
them in loops scanning tables).
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Andy Shevchenko <redacted>
cc: acpi4asus-user@lists.sourceforge.net
cc: platform-driver-x86@vger.kernel.org
cc: Matthew Garrett <mjg59@srcf.ucam.org>
cc: Thomas Gleixner <redacted>
Cc: Greg KH <redacted>
Cc: Rafael J. Wysocki <rafael@kernel.org>
Signed-off-by: Matthew Garrett <redacted>
---
fs/debugfs/file.c | 30 ++++++++++++++++++++++++++++++
fs/debugfs/inode.c | 32 ++++++++++++++++++++++++++++++--
include/linux/security.h | 1 +
security/lockdown/lockdown.c | 1 +
4 files changed, 62 insertions(+), 2 deletions(-)
@@ -147,6 +167,11 @@ static int open_proxy_open(struct inode *inode, struct file *filp)returnr==-EIO?-ENOENT:r;real_fops=debugfs_real_fops(filp);++r=debugfs_is_locked_down(inode,filp,real_fops);+if(r)+gotoout;+real_fops=fops_get(real_fops);if(!real_fops){/* Huh? Module did not clean up after itself at exit? */
@@ -272,6 +297,11 @@ static int full_proxy_open(struct inode *inode, struct file *filp)returnr==-EIO?-ENOENT:r;real_fops=debugfs_real_fops(filp);++r=debugfs_is_locked_down(inode,filp,real_fops);+if(r)+gotoout;+real_fops=fops_get(real_fops);if(!real_fops){/* Huh? Module did not cleanup after itself at exit? */
@@ -30,6 +30,7 @@ static char *lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {[LOCKDOWN_TIOCSSERIAL]="reconfiguration of serial port IO",[LOCKDOWN_MODULE_PARAMETERS]="unsafe module parameters",[LOCKDOWN_MMIOTRACE]="unsafe mmio",+[LOCKDOWN_DEBUGFS]="debugfs access",[LOCKDOWN_INTEGRITY_MAX]="integrity",[LOCKDOWN_KCORE]="/proc/kcore access",[LOCKDOWN_KPROBES]="use of kprobes",
From: Matthew Garrett <hidden> Date: 2019-07-18 19:45:58
Systems in lockdown mode should block the kexec of untrusted kernels.
For x86 and ARM we can ensure that a kernel is trustworthy by validating
a PE signature, but this isn't possible on other architectures. On those
platforms we can use IMA digital signatures instead. Add a function to
determine whether IMA has or will verify signatures for a given event type,
and if so permit kexec_file() even if the kernel is otherwise locked down.
This is restricted to cases where CONFIG_INTEGRITY_TRUSTED_KEYRING is set
in order to prevent an attacker from loading additional keys at runtime.
Signed-off-by: Matthew Garrett <redacted>
Acked-by: Mimi Zohar <zohar@linux.ibm.com>
Cc: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
Cc: linux-integrity@vger.kernel.org
---
include/linux/ima.h | 9 ++++++
kernel/kexec_file.c | 12 +++++--
security/integrity/ima/ima.h | 2 ++
security/integrity/ima/ima_main.c | 2 +-
security/integrity/ima/ima_policy.c | 50 +++++++++++++++++++++++++++++
5 files changed, 72 insertions(+), 3 deletions(-)
@@ -228,9 +228,17 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,gotoout;}-ret=security_locked_down(LOCKDOWN_KEXEC);-if(ret)+ret=0;++/* If IMA is guaranteed to appraise a signature on the kexec+*image,permititevenifthekernelisotherwiselocked+*down.+*/+if(!ima_appraise_signature(READING_KEXEC_IMAGE)&&+security_locked_down(LOCKDOWN_KEXEC)){+ret=-EPERM;gotoout;+}break;
@@ -12,6 +12,7 @@#include<linux/err.h>#include<linux/slab.h>#include<linux/ctype.h>+#include<linux/security.h>#ifdef CONFIG_SYSFS/* Protects all built-in parameters, modules use their own param_lock */
From: Matthew Garrett <hidden> Date: 2019-07-29 21:48:10
On Thu, Jul 18, 2019 at 12:45 PM Matthew Garrett
[off-list ref] wrote:
From: David Howells <dhowells@redhat.com>
Provided an annotation for module parameters that specify hardware
parameters (such as io ports, iomem addresses, irqs, dma channels, fixed
dma buffers and other types).
Suggested-by: Alan Cox <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Matthew Garrett <redacted>
Reviewed-by: Kees Cook <redacted>
Cc: Jessica Yu <jeyu@kernel.org>
From: Matthew Garrett <hidden> Date: 2019-07-18 19:46:12
From: Josh Boyer <redacted>
This option allows userspace to pass the RSDP address to the kernel, which
makes it possible for a user to modify the workings of hardware. Reject
the option when the kernel is locked down. This requires some reworking
of the existing RSDP command line logic, since the early boot code also
makes use of a command-line passed RSDP when locating the SRAT table
before the lockdown code has been initialised. This is achieved by
separating the command line RSDP path in the early boot code from the
generic RSDP path, and then copying the command line RSDP into boot
params in the kernel proper if lockdown is not enabled. If lockdown is
enabled and an RSDP is provided on the command line, this will only be
used when parsing SRAT (which shouldn't permit kernel code execution)
and will be ignored in the rest of the kernel.
(Modified by Matthew Garrett in order to handle the early boot RSDP
environment)
Signed-off-by: Josh Boyer <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Matthew Garrett <redacted>
Reviewed-by: Kees Cook <redacted>
cc: Dave Young <redacted>
cc: linux-acpi@vger.kernel.org
---
arch/x86/boot/compressed/acpi.c | 19 +++++++++++++------
arch/x86/include/asm/acpi.h | 9 +++++++++
arch/x86/include/asm/x86_init.h | 2 ++
arch/x86/kernel/acpi/boot.c | 5 +++++
arch/x86/kernel/x86_init.c | 1 +
drivers/acpi/osl.c | 14 +++++++++++++-
include/linux/acpi.h | 6 ++++++
7 files changed, 49 insertions(+), 7 deletions(-)
From: Matthew Garrett <hidden> Date: 2019-07-18 19:46:16
From: Linn Crosetto <redacted>
From the kernel documentation (initrd_table_override.txt):
If the ACPI_INITRD_TABLE_OVERRIDE compile option is true, it is possible
to override nearly any ACPI table provided by the BIOS with an
instrumented, modified one.
When lockdown is enabled, the kernel should disallow any unauthenticated
changes to kernel space. ACPI tables contain code invoked by the kernel,
so do not allow ACPI tables to be overridden if the kernel is locked down.
Signed-off-by: Linn Crosetto <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Matthew Garrett <redacted>
Reviewed-by: Kees Cook <redacted>
cc: linux-acpi@vger.kernel.org
---
drivers/acpi/tables.c | 6 ++++++
1 file changed, 6 insertions(+)
From: Matthew Garrett <hidden> Date: 2019-07-18 19:46:21
From: Matthew Garrett <mjg59@srcf.ucam.org>
IO port access would permit users to gain access to PCI configuration
registers, which in turn (on a lot of hardware) give access to MMIO
register space. This would potentially permit root to trigger arbitrary
DMA, so lock it down by default.
This also implicitly locks down the KDADDIO, KDDELIO, KDENABIO and
KDDISABIO console ioctls.
Signed-off-by: Matthew Garrett <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Kees Cook <redacted>
cc: x86@kernel.org
---
arch/x86/kernel/ioport.c | 7 +++++--
include/linux/security.h | 1 +
security/lockdown/lockdown.c | 1 +
3 files changed, 7 insertions(+), 2 deletions(-)
@@ -31,7 +32,8 @@ long ksys_ioperm(unsigned long from, unsigned long num, int turn_on)if((from+num<=from)||(from+num>IO_BITMAP_BITS))return-EINVAL;-if(turn_on&&!capable(CAP_SYS_RAWIO))+if(turn_on&&(!capable(CAP_SYS_RAWIO)||+security_locked_down(LOCKDOWN_IOPORT)))return-EPERM;/*
@@ -126,7 +128,8 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)return-EINVAL;/* Trying to gain more privileges? */if(level>old){-if(!capable(CAP_SYS_RAWIO))+if(!capable(CAP_SYS_RAWIO)||+security_locked_down(LOCKDOWN_IOPORT))return-EPERM;}regs->flags=(regs->flags&~X86_EFLAGS_IOPL)|
From: Matthew Garrett <hidden> Date: 2019-07-18 19:46:29
From: Josh Boyer <redacted>
There is currently no way to verify the resume image when returning
from hibernate. This might compromise the signed modules trust model,
so until we can work with signed hibernate images we disable it when the
kernel is locked down.
Signed-off-by: Josh Boyer <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Matthew Garrett <redacted>
Reviewed-by: Kees Cook <redacted>
Cc: rjw@rjwysocki.net
Cc: pavel@ucw.cz
cc: linux-pm@vger.kernel.org
---
include/linux/security.h | 1 +
kernel/power/hibernate.c | 3 ++-
security/lockdown/lockdown.c | 1 +
3 files changed, 4 insertions(+), 1 deletion(-)
From: Matthew Garrett <hidden> Date: 2019-07-18 19:46:39
From: David Howells <dhowells@redhat.com>
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 <dhowells@redhat.com>
Signed-off-by: Matthew Garrett <redacted>
Reviewed-by: Kees Cook <redacted>
Cc: Jessica Yu <jeyu@kernel.org>
---
include/linux/security.h | 1 +
kernel/module.c | 37 +++++++++++++++++++++++++++++-------
security/lockdown/lockdown.c | 1 +
3 files changed, 32 insertions(+), 7 deletions(-)
@@ -2769,16 +2770,38 @@ static int module_sig_check(struct load_info *info, int flags)err=mod_verify_sig(mod,info);}-if(!err){+switch(err){+case0:info->sig_ok=true;return0;-}-/* 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+*withoutavalidsignatureonthem,butifwe'renot+*enforcing,certainerrorsarenon-fatal.+*/+case-ENODATA:+reason="Loading of unsigned module";+gotodecide;+case-ENOPKG:+reason="Loading of module with unsupported crypto";+gotodecide;+case-ENOKEY:+reason="Loading of module with unavailable key";+decide:+if(is_module_sig_enforced()){+pr_notice("%s is rejected\n",reason);+return-EKEYREJECTED;+}-returnerr;+returnsecurity_locked_down(LOCKDOWN_MODULE_SIGNATURE);++/* All other errors are fatal, including nomem, unparseable+*signaturesandsignaturecheckfailures-evenifsignatures+*aren'trequired.+*/+default:+returnerr;+}}#else /* !CONFIG_MODULE_SIG */staticintmodule_sig_check(structload_info*info,intflags)
From: Matthew Garrett <hidden> Date: 2019-07-18 19:46:40
From: Jiri Bohac <redacted>
This is a preparatory patch for kexec_file_load() lockdown. A locked down
kernel needs to prevent unsigned kernel images from being loaded with
kexec_file_load(). Currently, the only way to force the signature
verification is compiling with KEXEC_VERIFY_SIG. This prevents loading
usigned images even when the kernel is not locked down at runtime.
This patch splits KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE.
Analogous to the MODULE_SIG and MODULE_SIG_FORCE for modules, KEXEC_SIG
turns on the signature verification but allows unsigned images to be
loaded. KEXEC_SIG_FORCE disallows images without a valid signature.
Signed-off-by: Jiri Bohac <redacted>
Signed-off-by: David Howells <redacted>
Signed-off-by: Matthew Garrett <redacted>
Reviewed-by: Jiri Bohac <redacted>
Reviewed-by: Dave Young <redacted>
cc: kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
---
arch/x86/Kconfig | 20 +++++++++----
crypto/asymmetric_keys/verify_pefile.c | 4 ++-
include/linux/kexec.h | 4 +--
kernel/kexec_file.c | 41 ++++++++++++++++++++++----
4 files changed, 55 insertions(+), 14 deletions(-)
@@ -96,7 +96,7 @@ static int pefile_parse_binary(const void *pebuf, unsigned int pelen,if(!ddir->certs.virtual_address||!ddir->certs.size){pr_debug("Unsigned PE binary\n");-return-EKEYREJECTED;+return-ENODATA;}chkaddr(ctx->header_size,ddir->certs.virtual_address,
@@ -403,6 +403,8 @@ static int pefile_digest_pe(const void *pebuf, unsigned int pelen,*(*)0ifatleastonesignaturechainintersectswiththekeysinthetrust*keyring,or:*+*(*)-ENODATAifthereisnosignaturepresent.+**(*)-ENOPKGifasuitablecryptomodulecouldn'tbefoundforacheckona*chain.*
@@ -186,7 +186,8 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,constchar__user*cmdline_ptr,unsignedlongcmdline_len,unsignedflags){-intret=0;+constchar*reason;+intret;void*ldata;loff_tsize;
@@ -202,14 +203,42 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,if(ret)gotoout;-#ifdef CONFIG_KEXEC_VERIFY_SIG+#ifdef CONFIG_KEXEC_SIGret=arch_kexec_kernel_verify_sig(image,image->kernel_buf,image->kernel_buf_len);-if(ret){-pr_debug("kernel signature verification failed.\n");+switch(ret){+case0:+break;++/* Certain verification errors are non-fatal if we're not+*checkingerrors,providedwearen'tmandatingthatthere+*mustbeavalidsignature.+*/+case-ENODATA:+reason="kexec of unsigned image";+gotodecide;+case-ENOPKG:+reason="kexec of image with unsupported crypto";+gotodecide;+case-ENOKEY:+reason="kexec of image with unavailable key";+decide:+if(IS_ENABLED(CONFIG_KEXEC_SIG_FORCE)){+pr_notice("%s rejected\n",reason);+gotoout;+}++ret=0;+break;++/* All other errors are fatal, including nomem, unparseable+*signaturesandsignaturecheckfailures-evenifsignatures+*aren'trequired.+*/+default:+pr_notice("kernel signature verification failed (%d).\n",ret);gotoout;}-pr_debug("kernel signature verification successful.\n");#endif/* It is possible that there no initramfs is being loaded */if(!(flags&KEXEC_FILE_NO_INITRAMFS)){