diff options
| -rw-r--r-- | include/asm-generic/vmlinux.lds.h | 8 | ||||
| -rw-r--r-- | include/linux/lsm_hooks.h | 6 | ||||
| -rw-r--r-- | include/linux/security.h | 6 | ||||
| -rw-r--r-- | init/main.c | 1 | ||||
| -rw-r--r-- | 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 @@ | |||
| 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 | ||
| 2106 | extern struct lsm_info __start_lsm_info[], __end_lsm_info[]; | 2106 | extern struct lsm_info __start_lsm_info[], __end_lsm_info[]; |
| 2107 | extern 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 */ |
| 197 | extern int security_init(void); | 197 | extern int security_init(void); |
| 198 | extern int early_security_init(void); | ||
| 198 | 199 | ||
| 199 | /* Security operations */ | 200 | /* Security operations */ |
| 200 | int security_binder_set_context_mgr(struct task_struct *mgr); | 201 | int 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 | ||
| 427 | static inline int early_security_init(void) | ||
| 428 | { | ||
| 429 | return 0; | ||
| 430 | } | ||
| 431 | |||
| 426 | static inline int security_binder_set_context_mgr(struct task_struct *mgr) | 432 | static 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 | ||
| 37 | struct security_hook_heads security_hook_heads __lsm_ro_after_init; | 38 | struct security_hook_heads security_hook_heads __lsm_ro_after_init; |
| 38 | static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain); | 39 | static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain); |
| @@ -277,6 +278,8 @@ static void __init ordered_lsm_parse(const char *order, const char *origin) | |||
| 277 | static void __init lsm_early_cred(struct cred *cred); | 278 | static void __init lsm_early_cred(struct cred *cred); |
| 278 | static void __init lsm_early_task(struct task_struct *task); | 279 | static void __init lsm_early_task(struct task_struct *task); |
| 279 | 280 | ||
| 281 | static int lsm_append(const char *new, char **result); | ||
| 282 | |||
| 280 | static void __init ordered_lsm_init(void) | 283 | static 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 | ||
| 329 | int __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 | */ |
| 331 | int __init security_init(void) | 354 | int __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 | ||
| 387 | static int lsm_append(char *new, char **result) | 414 | static 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 | ||
| 429 | int call_lsm_notifier(enum lsm_event event, void *data) | 463 | int call_lsm_notifier(enum lsm_event event, void *data) |
