aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2014-01-23 18:55:59 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-23 19:37:03 -0500
commit7984754b99b6c89054edc405e9d9d35810a91d36 (patch)
tree9828ff56e995007158fecee07666f6a5c08f403a /kernel
parent3b96d7db3b6dc99d207bca50037274d22e48dea5 (diff)
kexec: add sysctl to disable kexec_load
For general-purpose (i.e. distro) kernel builds it makes sense to build with CONFIG_KEXEC to allow end users to choose what kind of things they want to do with kexec. However, in the face of trying to lock down a system with such a kernel, there needs to be a way to disable kexec_load (much like module loading can be disabled). Without this, it is too easy for the root user to modify kernel memory even when CONFIG_STRICT_DEVMEM and modules_disabled are set. With this change, it is still possible to load an image for use later, then disable kexec_load so the image (or lack of image) can't be altered. The intention is for using this in environments where "perfect" enforcement is hard. Without a verified boot, along with verified modules, and along with verified kexec, this is trying to give a system a better chance to defend itself (or at least grow the window of discoverability) against attack in the face of a privilege escalation. In my mind, I consider several boot scenarios: 1) Verified boot of read-only verified root fs loading fd-based verification of kexec images. 2) Secure boot of writable root fs loading signed kexec images. 3) Regular boot loading kexec (e.g. kcrash) image early and locking it. 4) Regular boot with no control of kexec image at all. 1 and 2 don't exist yet, but will soon once the verified kexec series has landed. 4 is the state of things now. The gap between 2 and 4 is too large, so this change creates scenario 3, a middle-ground above 4 when 2 and 1 are not possible for a system. Signed-off-by: Kees Cook <keescook@chromium.org> Acked-by: Rik van Riel <riel@redhat.com> Cc: Vivek Goyal <vgoyal@redhat.com> Cc: Eric Biederman <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/kexec.c3
-rw-r--r--kernel/sysctl.c13
2 files changed, 15 insertions, 1 deletions
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 9c970167e402..ac738781d356 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -932,6 +932,7 @@ static int kimage_load_segment(struct kimage *image,
932 */ 932 */
933struct kimage *kexec_image; 933struct kimage *kexec_image;
934struct kimage *kexec_crash_image; 934struct kimage *kexec_crash_image;
935int kexec_load_disabled;
935 936
936static DEFINE_MUTEX(kexec_mutex); 937static DEFINE_MUTEX(kexec_mutex);
937 938
@@ -942,7 +943,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
942 int result; 943 int result;
943 944
944 /* We only trust the superuser with rebooting the system. */ 945 /* We only trust the superuser with rebooting the system. */
945 if (!capable(CAP_SYS_BOOT)) 946 if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
946 return -EPERM; 947 return -EPERM;
947 948
948 /* 949 /*
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 693eac39c202..096db7452cbd 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -62,6 +62,7 @@
62#include <linux/capability.h> 62#include <linux/capability.h>
63#include <linux/binfmts.h> 63#include <linux/binfmts.h>
64#include <linux/sched/sysctl.h> 64#include <linux/sched/sysctl.h>
65#include <linux/kexec.h>
65 66
66#include <asm/uaccess.h> 67#include <asm/uaccess.h>
67#include <asm/processor.h> 68#include <asm/processor.h>
@@ -614,6 +615,18 @@ static struct ctl_table kern_table[] = {
614 .proc_handler = proc_dointvec, 615 .proc_handler = proc_dointvec,
615 }, 616 },
616#endif 617#endif
618#ifdef CONFIG_KEXEC
619 {
620 .procname = "kexec_load_disabled",
621 .data = &kexec_load_disabled,
622 .maxlen = sizeof(int),
623 .mode = 0644,
624 /* only handle a transition from default "0" to "1" */
625 .proc_handler = proc_dointvec_minmax,
626 .extra1 = &one,
627 .extra2 = &one,
628 },
629#endif
617#ifdef CONFIG_MODULES 630#ifdef CONFIG_MODULES
618 { 631 {
619 .procname = "modprobe", 632 .procname = "modprobe",