From patchwork Fri Feb 7 16:29:23 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Whitcroft X-Patchwork-Id: 318104 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id D44572C00AF for ; Sat, 8 Feb 2014 03:29:38 +1100 (EST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1WBoJ4-0007EV-Ic; Fri, 07 Feb 2014 16:29:34 +0000 Received: from mail-wg0-f50.google.com ([74.125.82.50]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1WBoIx-0007E8-Ni for kernel-team@lists.ubuntu.com; Fri, 07 Feb 2014 16:29:27 +0000 Received: by mail-wg0-f50.google.com with SMTP id l18so2452486wgh.5 for ; Fri, 07 Feb 2014 08:29:27 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=fv14qll28XExsIOMDcO6DC0MxxWdjg9961q60rHyYps=; b=mX6LwYwu8cLRwtlkhor3a5JWG17miHXf3cPymDVpGIfaWDvF9ESSrhp7DPi8rI7IJI rq1qp93JD+nvhKN7nq+SPkPnUGGfIBoldMJEiqrkd0AU1c+3XEmvrJmj62piFLGxZqGG Og1kmIAXgBjj6kGP+AqZ438Z4yAjIDwaSg306PvVLMMVP3ujj7z/VLXoTfeMKC+v9SlJ VlJaEXs9nFCh1PUWLMHq1JvYUFaX2ff6mB2cyMNA2EohFMopIDsAfbTCZkLLenxOEhot 9tDO4f9qo+Dn9JH5xvEsONXk6K7I4fmhLpSzwz0d7yuD32OYKCFmkdnb7SR5Hq9Koj6W HXuQ== X-Gm-Message-State: ALoCoQmqUgINxb1Y93s+6nkIcdpOzcyDSKSuI8atWFsJyrEOXhkDWhOy6vDel7l+0ECncgeKp/+F X-Received: by 10.194.58.132 with SMTP id r4mr7182111wjq.45.1391790567583; Fri, 07 Feb 2014 08:29:27 -0800 (PST) Received: from localhost ([2001:470:6973:2:221:70ff:fe81:b177]) by mx.google.com with ESMTPSA id f7sm11892528wjb.7.2014.02.07.08.29.26 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 07 Feb 2014 08:29:26 -0800 (PST) From: Andy Whitcroft To: kernel-team@lists.ubuntu.com Subject: [saucy 1/1] kexec: add sysctl to disable kexec_load Date: Fri, 7 Feb 2014 16:29:23 +0000 Message-Id: <1391790563-11982-2-git-send-email-apw@canonical.com> X-Mailer: git-send-email 1.8.5.3 In-Reply-To: <1391790563-11982-1-git-send-email-apw@canonical.com> References: <1391790563-11982-1-git-send-email-apw@canonical.com> Cc: Andy Whitcroft X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com From: Kees Cook 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 Acked-by: Rik van Riel Cc: Vivek Goyal Cc: Eric Biederman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds (cherry picked from commit 7984754b99b6c89054edc405e9d9d35810a91d36) BugLink: http://bugs.launchpad.net/bugs/1259570 Signed-off-by: Andy Whitcroft --- Documentation/sysctl/kernel.txt | 15 ++++++++++++++- include/linux/kexec.h | 1 + kernel/kexec.c | 3 ++- kernel/sysctl.c | 13 +++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 7ea3a96..33b745f 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -33,6 +33,7 @@ show up in /proc/sys/kernel: - domainname - hostname - hotplug +- kexec_load_disabled - kptr_restrict - kstack_depth_to_print [ X86 only ] - l2cr [ PPC only ] @@ -286,6 +287,18 @@ Default value is "/sbin/hotplug". ============================================================== +kexec_load_disabled: + +A toggle indicating if the kexec_load syscall has been disabled. This +value defaults to 0 (false: kexec_load enabled), but can be set to 1 +(true: kexec_load disabled). Once true, kexec can no longer be used, and +the toggle cannot be set back to false. This allows a kexec image to be +loaded before disabling the syscall, allowing a system to set up (and +later use) an image without it being altered. Generally used together +with the "modules_disabled" sysctl. + +============================================================== + kptr_restrict: This toggle indicates whether restrictions are placed on @@ -330,7 +343,7 @@ A toggle value indicating if modules are allowed to be loaded in an otherwise modular kernel. This toggle defaults to off (0), but can be set true (1). Once true, modules can be neither loaded nor unloaded, and the toggle cannot be set back -to false. +to false. Generally used with the "kexec_load_disabled" toggle. ============================================================== diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 5fd33dc..6d4066c 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -170,6 +170,7 @@ unsigned long paddr_vmcoreinfo_note(void); extern struct kimage *kexec_image; extern struct kimage *kexec_crash_image; +extern int kexec_load_disabled; #ifndef kexec_flush_icache_page #define kexec_flush_icache_page(page) diff --git a/kernel/kexec.c b/kernel/kexec.c index 57cc094..d3a2301 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -932,6 +932,7 @@ static int kimage_load_segment(struct kimage *image, */ struct kimage *kexec_image; struct kimage *kexec_crash_image; +int kexec_load_disabled; static DEFINE_MUTEX(kexec_mutex); @@ -942,7 +943,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, int result; /* We only trust the superuser with rebooting the system. */ - if (!capable(CAP_SYS_BOOT)) + if (!capable(CAP_SYS_BOOT) || kexec_load_disabled) return -EPERM; /* diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 07f6fc4..9608937 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include @@ -607,6 +608,18 @@ static struct ctl_table kern_table[] = { .proc_handler = proc_dointvec, }, #endif +#ifdef CONFIG_KEXEC + { + .procname = "kexec_load_disabled", + .data = &kexec_load_disabled, + .maxlen = sizeof(int), + .mode = 0644, + /* only handle a transition from default "0" to "1" */ + .proc_handler = proc_dointvec_minmax, + .extra1 = &one, + .extra2 = &one, + }, +#endif #ifdef CONFIG_MODULES { .procname = "modprobe",