summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/asm-generic/vmlinux.lds.h8
-rw-r--r--include/linux/lsm_hooks.h6
-rw-r--r--include/linux/security.h6
-rw-r--r--init/main.c1
-rw-r--r--security/security.c50
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 @@
208 __start_lsm_info = .; \ 208 __start_lsm_info = .; \
209 KEEP(*(.lsm_info.init)) \ 209 KEEP(*(.lsm_info.init)) \
210 __end_lsm_info = .; 210 __end_lsm_info = .;
211#define EARLY_LSM_TABLE() . = ALIGN(8); \
212 __start_early_lsm_info = .; \
213 KEEP(*(.early_lsm_info.init)) \
214 __end_early_lsm_info = .;
211#else 215#else
212#define LSM_TABLE() 216#define LSM_TABLE()
217#define EARLY_LSM_TABLE()
213#endif 218#endif
214 219
215#define ___OF_TABLE(cfg, name) _OF_TABLE_##cfg(name) 220#define ___OF_TABLE(cfg, name) _OF_TABLE_##cfg(name)
@@ -609,7 +614,8 @@
609 ACPI_PROBE_TABLE(irqchip) \ 614 ACPI_PROBE_TABLE(irqchip) \
610 ACPI_PROBE_TABLE(timer) \ 615 ACPI_PROBE_TABLE(timer) \
611 EARLYCON_TABLE() \ 616 EARLYCON_TABLE() \
612 LSM_TABLE() 617 LSM_TABLE() \
618 EARLY_LSM_TABLE()
613 619
614#define INIT_TEXT \ 620#define INIT_TEXT \
615 *(.init.text .init.text.*) \ 621 *(.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 {
2104}; 2104};
2105 2105
2106extern struct lsm_info __start_lsm_info[], __end_lsm_info[]; 2106extern struct lsm_info __start_lsm_info[], __end_lsm_info[];
2107extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[];
2107 2108
2108#define DEFINE_LSM(lsm) \ 2109#define DEFINE_LSM(lsm) \
2109 static struct lsm_info __lsm_##lsm \ 2110 static struct lsm_info __lsm_##lsm \
2110 __used __section(.lsm_info.init) \ 2111 __used __section(.lsm_info.init) \
2111 __aligned(sizeof(unsigned long)) 2112 __aligned(sizeof(unsigned long))
2112 2113
2114#define DEFINE_EARLY_LSM(lsm) \
2115 static struct lsm_info __early_lsm_##lsm \
2116 __used __section(.early_lsm_info.init) \
2117 __aligned(sizeof(unsigned long))
2118
2113#ifdef CONFIG_SECURITY_SELINUX_DISABLE 2119#ifdef CONFIG_SECURITY_SELINUX_DISABLE
2114/* 2120/*
2115 * Assuring the safety of deleting a security module is up to 2121 * 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);
195 195
196/* prototypes */ 196/* prototypes */
197extern int security_init(void); 197extern int security_init(void);
198extern int early_security_init(void);
198 199
199/* Security operations */ 200/* Security operations */
200int security_binder_set_context_mgr(struct task_struct *mgr); 201int security_binder_set_context_mgr(struct task_struct *mgr);
@@ -423,6 +424,11 @@ static inline int security_init(void)
423 return 0; 424 return 0;
424} 425}
425 426
427static inline int early_security_init(void)
428{
429 return 0;
430}
431
426static inline int security_binder_set_context_mgr(struct task_struct *mgr) 432static inline int security_binder_set_context_mgr(struct task_struct *mgr)
427{ 433{
428 return 0; 434 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)
569 boot_cpu_init(); 569 boot_cpu_init();
570 page_address_init(); 570 page_address_init();
571 pr_notice("%s", linux_banner); 571 pr_notice("%s", linux_banner);
572 early_security_init();
572 setup_arch(&command_line); 573 setup_arch(&command_line);
573 mm_init_cpumask(&init_mm); 574 mm_init_cpumask(&init_mm);
574 setup_command_line(command_line); 575 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 @@
33 33
34/* How many LSMs were built into the kernel? */ 34/* How many LSMs were built into the kernel? */
35#define LSM_COUNT (__end_lsm_info - __start_lsm_info) 35#define LSM_COUNT (__end_lsm_info - __start_lsm_info)
36#define EARLY_LSM_COUNT (__end_early_lsm_info - __start_early_lsm_info)
36 37
37struct security_hook_heads security_hook_heads __lsm_ro_after_init; 38struct security_hook_heads security_hook_heads __lsm_ro_after_init;
38static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain); 39static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
@@ -277,6 +278,8 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
277static void __init lsm_early_cred(struct cred *cred); 278static void __init lsm_early_cred(struct cred *cred);
278static void __init lsm_early_task(struct task_struct *task); 279static void __init lsm_early_task(struct task_struct *task);
279 280
281static int lsm_append(const char *new, char **result);
282
280static void __init ordered_lsm_init(void) 283static void __init ordered_lsm_init(void)
281{ 284{
282 struct lsm_info **lsm; 285 struct lsm_info **lsm;
@@ -323,6 +326,26 @@ static void __init ordered_lsm_init(void)
323 kfree(ordered_lsms); 326 kfree(ordered_lsms);
324} 327}
325 328
329int __init early_security_init(void)
330{
331 int i;
332 struct hlist_head *list = (struct hlist_head *) &security_hook_heads;
333 struct lsm_info *lsm;
334
335 for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct hlist_head);
336 i++)
337 INIT_HLIST_HEAD(&list[i]);
338
339 for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) {
340 if (!lsm->enabled)
341 lsm->enabled = &lsm_enabled_true;
342 prepare_lsm(lsm);
343 initialize_lsm(lsm);
344 }
345
346 return 0;
347}
348
326/** 349/**
327 * security_init - initializes the security framework 350 * security_init - initializes the security framework
328 * 351 *
@@ -330,14 +353,18 @@ static void __init ordered_lsm_init(void)
330 */ 353 */
331int __init security_init(void) 354int __init security_init(void)
332{ 355{
333 int i; 356 struct lsm_info *lsm;
334 struct hlist_head *list = (struct hlist_head *) &security_hook_heads;
335 357
336 pr_info("Security Framework initializing\n"); 358 pr_info("Security Framework initializing\n");
337 359
338 for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct hlist_head); 360 /*
339 i++) 361 * Append the names of the early LSM modules now that kmalloc() is
340 INIT_HLIST_HEAD(&list[i]); 362 * available
363 */
364 for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) {
365 if (lsm->enabled)
366 lsm_append(lsm->name, &lsm_names);
367 }
341 368
342 /* Load LSMs in specified order. */ 369 /* Load LSMs in specified order. */
343 ordered_lsm_init(); 370 ordered_lsm_init();
@@ -384,7 +411,7 @@ static bool match_last_lsm(const char *list, const char *lsm)
384 return !strcmp(last, lsm); 411 return !strcmp(last, lsm);
385} 412}
386 413
387static int lsm_append(char *new, char **result) 414static int lsm_append(const char *new, char **result)
388{ 415{
389 char *cp; 416 char *cp;
390 417
@@ -422,8 +449,15 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
422 hooks[i].lsm = lsm; 449 hooks[i].lsm = lsm;
423 hlist_add_tail_rcu(&hooks[i].list, hooks[i].head); 450 hlist_add_tail_rcu(&hooks[i].list, hooks[i].head);
424 } 451 }
425 if (lsm_append(lsm, &lsm_names) < 0) 452
426 panic("%s - Cannot get early memory.\n", __func__); 453 /*
454 * Don't try to append during early_security_init(), we'll come back
455 * and fix this up afterwards.
456 */
457 if (slab_is_available()) {
458 if (lsm_append(lsm, &lsm_names) < 0)
459 panic("%s - Cannot get early memory.\n", __func__);
460 }
427} 461}
428 462
429int call_lsm_notifier(enum lsm_event event, void *data) 463int call_lsm_notifier(enum lsm_event event, void *data)