Linux-Security-Module Archive on lore.kernel.org
 help / color / Atom feed
From: Matthew Garrett <matthewgarrett@google.com>
To: jmorris@namei.org
Cc: linux-security-module@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-api@vger.kernel.org,
	Matthew Garrett <matthewgarrett@google.com>,
	Matthew Garrett <mjg59@google.com>,
	Kees Cook <keescook@chromium.org>,
	Casey Schaufler <casey@schaufler-ca.com>,
	Stephen Rothwell <sfr@canb.auug.org.au>
Subject: [PATCH V40 01/29] security: Support early LSMs
Date: Mon, 19 Aug 2019 17:17:37 -0700
Message-ID: <20190820001805.241928-2-matthewgarrett@google.com> (raw)
In-Reply-To: <20190820001805.241928-1-matthewgarrett@google.com>

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).

(Fixed by Stephen Rothwell to include a stub to fix builds when
!CONFIG_SECURITY)

Signed-off-by: Matthew Garrett <mjg59@google.com>
Acked-by: Kees Cook <keescook@chromium.org>
Acked-by: Casey Schaufler <casey@schaufler-ca.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
---
 include/asm-generic/vmlinux.lds.h |  8 ++++-
 include/linux/lsm_hooks.h         |  6 ++++
 include/linux/security.h          |  6 ++++
 init/main.c                       |  1 +
 security/security.c               | 50 ++++++++++++++++++++++++++-----
 5 files changed, 62 insertions(+), 9 deletions(-)

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 088987e9a3ea..c1807d14daa3 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -208,8 +208,13 @@
 			__start_lsm_info = .;				\
 			KEEP(*(.lsm_info.init))				\
 			__end_lsm_info = .;
+#define EARLY_LSM_TABLE()	. = ALIGN(8);				\
+			__start_early_lsm_info = .;			\
+			KEEP(*(.early_lsm_info.init))			\
+			__end_early_lsm_info = .;
 #else
 #define LSM_TABLE()
+#define EARLY_LSM_TABLE()
 #endif
 
 #define ___OF_TABLE(cfg, name)	_OF_TABLE_##cfg(name)
@@ -609,7 +614,8 @@
 	ACPI_PROBE_TABLE(irqchip)					\
 	ACPI_PROBE_TABLE(timer)						\
 	EARLYCON_TABLE()						\
-	LSM_TABLE()
+	LSM_TABLE()							\
+	EARLY_LSM_TABLE()
 
 #define INIT_TEXT							\
 	*(.init.text .init.text.*)					\
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 47f58cfb6a19..b02e8bb6654d 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2104,12 +2104,18 @@ struct lsm_info {
 };
 
 extern struct lsm_info __start_lsm_info[], __end_lsm_info[];
+extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[];
 
 #define DEFINE_LSM(lsm)							\
 	static struct lsm_info __lsm_##lsm				\
 		__used __section(.lsm_info.init)			\
 		__aligned(sizeof(unsigned long))
 
+#define DEFINE_EARLY_LSM(lsm)						\
+	static struct lsm_info __early_lsm_##lsm			\
+		__used __section(.early_lsm_info.init)			\
+		__aligned(sizeof(unsigned long))
+
 #ifdef CONFIG_SECURITY_SELINUX_DISABLE
 /*
  * Assuring the safety of deleting a security module is up to
diff --git a/include/linux/security.h b/include/linux/security.h
index 659071c2e57c..c5dd90981c98 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -195,6 +195,7 @@ int unregister_lsm_notifier(struct notifier_block *nb);
 
 /* prototypes */
 extern int security_init(void);
+extern int early_security_init(void);
 
 /* Security operations */
 int security_binder_set_context_mgr(struct task_struct *mgr);
@@ -423,6 +424,11 @@ static inline int security_init(void)
 	return 0;
 }
 
+static inline int early_security_init(void)
+{
+	return 0;
+}
+
 static inline int security_binder_set_context_mgr(struct task_struct *mgr)
 {
 	return 0;
diff --git a/init/main.c b/init/main.c
index 66a196c5e4c3..598effd29a0a 100644
--- a/init/main.c
+++ b/init/main.c
@@ -569,6 +569,7 @@ asmlinkage __visible void __init start_kernel(void)
 	boot_cpu_init();
 	page_address_init();
 	pr_notice("%s", linux_banner);
+	early_security_init();
 	setup_arch(&command_line);
 	mm_init_cpumask(&init_mm);
 	setup_command_line(command_line);
diff --git a/security/security.c b/security/security.c
index f493db0bf62a..ef4a0111c8b4 100644
--- a/security/security.c
+++ b/security/security.c
@@ -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)
 
 struct security_hook_heads security_hook_heads __lsm_ro_after_init;
 static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
@@ -277,6 +278,8 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
 static void __init lsm_early_cred(struct cred *cred);
 static void __init lsm_early_task(struct task_struct *task);
 
+static int lsm_append(const char *new, char **result);
+
 static void __init ordered_lsm_init(void)
 {
 	struct lsm_info **lsm;
@@ -323,6 +326,26 @@ static void __init ordered_lsm_init(void)
 	kfree(ordered_lsms);
 }
 
+int __init early_security_init(void)
+{
+	int i;
+	struct hlist_head *list = (struct hlist_head *) &security_hook_heads;
+	struct lsm_info *lsm;
+
+	for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct hlist_head);
+	     i++)
+		INIT_HLIST_HEAD(&list[i]);
+
+	for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) {
+		if (!lsm->enabled)
+			lsm->enabled = &lsm_enabled_true;
+		prepare_lsm(lsm);
+		initialize_lsm(lsm);
+	}
+
+	return 0;
+}
+
 /**
  * security_init - initializes the security framework
  *
@@ -330,14 +353,18 @@ static void __init ordered_lsm_init(void)
  */
 int __init security_init(void)
 {
-	int i;
-	struct hlist_head *list = (struct hlist_head *) &security_hook_heads;
+	struct lsm_info *lsm;
 
 	pr_info("Security Framework initializing\n");
 
-	for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct hlist_head);
-	     i++)
-		INIT_HLIST_HEAD(&list[i]);
+	/*
+	 * Append the names of the early LSM modules now that kmalloc() is
+	 * available
+	 */
+	for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) {
+		if (lsm->enabled)
+			lsm_append(lsm->name, &lsm_names);
+	}
 
 	/* Load LSMs in specified order. */
 	ordered_lsm_init();
@@ -384,7 +411,7 @@ static bool match_last_lsm(const char *list, const char *lsm)
 	return !strcmp(last, lsm);
 }
 
-static int lsm_append(char *new, char **result)
+static int lsm_append(const char *new, char **result)
 {
 	char *cp;
 
@@ -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't try to append during early_security_init(), we'll come back
+	 * and fix this up afterwards.
+	 */
+	if (slab_is_available()) {
+		if (lsm_append(lsm, &lsm_names) < 0)
+			panic("%s - Cannot get early memory.\n", __func__);
+	}
 }
 
 int call_lsm_notifier(enum lsm_event event, void *data)
-- 
2.23.0.rc1.153.gdeed80330f-goog


  reply index

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-20  0:17 [PATCH V40 00/29] Add kernel lockdown functionality Matthew Garrett
2019-08-20  0:17 ` Matthew Garrett [this message]
2019-08-20  0:17 ` [PATCH V40 02/29] security: Add a "locked down" LSM hook Matthew Garrett
2019-08-20  0:17 ` [PATCH V40 03/29] security: Add a static lockdown policy LSM Matthew Garrett
2019-08-20  0:17 ` [PATCH V40 04/29] lockdown: Enforce module signatures if the kernel is locked down Matthew Garrett
2019-08-20  0:17 ` [PATCH V40 05/29] lockdown: Restrict /dev/{mem,kmem,port} when " Matthew Garrett
2019-08-20  0:17 ` [PATCH V40 06/29] kexec_load: Disable at runtime if " Matthew Garrett
2019-08-20  0:17 ` [PATCH V40 07/29] lockdown: Copy secure_boot flag in boot params across kexec reboot Matthew Garrett
2019-08-20  0:17 ` [PATCH V40 08/29] kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE Matthew Garrett
2019-08-30 14:26   ` Philipp Rudo
2019-08-20  0:17 ` [PATCH V40 09/29] kexec_file: Restrict at runtime if the kernel is locked down Matthew Garrett
2019-08-20  0:17 ` [PATCH V40 10/29] hibernate: Disable when " Matthew Garrett
2019-08-20 21:43   ` Rafael J. Wysocki
2019-08-25  9:51   ` Pavel Machek
2019-08-20  0:17 ` [PATCH V40 11/29] PCI: Lock down BAR access " Matthew Garrett
2019-08-20 19:45   ` Bjorn Helgaas
2019-08-20 21:04     ` Matthew Garrett
2019-08-20  0:17 ` [PATCH V40 12/29] x86: Lock down IO port " Matthew Garrett
2019-08-20  0:17 ` [PATCH V40 13/29] x86/msr: Restrict MSR " Matthew Garrett
2019-08-20  0:17 ` [PATCH V40 14/29] ACPI: Limit access to custom_method " Matthew Garrett
2019-08-20 22:07   ` Rafael J. Wysocki
2019-08-20  0:17 ` [PATCH V40 15/29] acpi: Ignore acpi_rsdp kernel param when the kernel has been " Matthew Garrett
2019-08-20 22:08   ` Rafael J. Wysocki
2019-08-20  0:17 ` [PATCH V40 16/29] acpi: Disable ACPI table override if the kernel is " Matthew Garrett
2019-08-20 22:08   ` Rafael J. Wysocki
2019-08-20  0:17 ` [PATCH V40 17/29] lockdown: Prohibit PCMCIA CIS storage when " Matthew Garrett
2019-08-20  0:17 ` [PATCH V40 18/29] lockdown: Lock down TIOCSSERIAL Matthew Garrett
2019-08-20  0:17 ` [PATCH V40 19/29] lockdown: Lock down module params that specify hardware parameters (eg. ioport) Matthew Garrett
2019-08-20 16:39   ` Jessica Yu
2019-08-20  0:17 ` [PATCH V40 20/29] x86/mmiotrace: Lock down the testmmiotrace module Matthew Garrett
2019-08-20  0:17 ` [PATCH V40 21/29] lockdown: Lock down /proc/kcore Matthew Garrett
2019-08-20  0:17 ` [PATCH V40 22/29] lockdown: Lock down tracing and perf kprobes when in confidentiality mode Matthew Garrett
2019-08-20  0:17 ` [PATCH V40 23/29] bpf: Restrict bpf when kernel lockdown is " Matthew Garrett
2019-08-20  0:18 ` [PATCH V40 24/29] lockdown: Lock down perf when " Matthew Garrett
2019-08-20  0:18 ` [PATCH V40 25/29] kexec: Allow kexec_file() with appropriate IMA policy when locked down Matthew Garrett
2019-08-20  0:18 ` [PATCH V40 26/29] debugfs: Restrict debugfs when the kernel is " Matthew Garrett
2019-08-20  0:18 ` [PATCH V40 27/29] tracefs: Restrict tracefs " Matthew Garrett
2019-08-20  0:18 ` [PATCH V40 28/29] efi: Restrict efivar_ssdt_load " Matthew Garrett
2019-08-20  0:18 ` [PATCH V40 29/29] lockdown: Print current->comm in restriction messages Matthew Garrett
2019-08-20  6:45 ` [PATCH V40 00/29] Add kernel lockdown functionality James Morris
2019-08-30 16:28 ` [PATCH V40 03/29] security: Add a static lockdown policy LSM David Howells
2019-09-04 16:51   ` Matthew Garrett
2019-09-10 10:06     ` Matthew Garrett
2019-08-30 16:31 ` [PATCH V40 04/29] lockdown: Enforce module signatures if the kernel is locked down David Howells
2019-09-04 16:57   ` Matthew Garrett
2019-08-30 16:32 ` [PATCH V40 23/29] bpf: Restrict bpf when kernel lockdown is in confidentiality mode David Howells

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190820001805.241928-2-matthewgarrett@google.com \
    --to=matthewgarrett@google.com \
    --cc=casey@schaufler-ca.com \
    --cc=jmorris@namei.org \
    --cc=keescook@chromium.org \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mjg59@google.com \
    --cc=sfr@canb.auug.org.au \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-Security-Module Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-security-module/0 linux-security-module/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-security-module linux-security-module/ https://lore.kernel.org/linux-security-module \
		linux-security-module@vger.kernel.org
	public-inbox-index linux-security-module

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-security-module


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git