diff options
Diffstat (limited to 'security/security.c')
-rw-r--r-- | security/security.c | 56 |
1 files changed, 48 insertions, 8 deletions
diff --git a/security/security.c b/security/security.c index 25ee5c75551f..1bc000f834e2 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 BLOCKING_NOTIFIER_HEAD(blocking_lsm_notifier_chain); | 39 | static BLOCKING_NOTIFIER_HEAD(blocking_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_blocking_lsm_notifier(enum lsm_event event, void *data) | 463 | int call_blocking_lsm_notifier(enum lsm_event event, void *data) |
@@ -2364,3 +2398,9 @@ void security_bpf_prog_free(struct bpf_prog_aux *aux) | |||
2364 | call_void_hook(bpf_prog_free_security, aux); | 2398 | call_void_hook(bpf_prog_free_security, aux); |
2365 | } | 2399 | } |
2366 | #endif /* CONFIG_BPF_SYSCALL */ | 2400 | #endif /* CONFIG_BPF_SYSCALL */ |
2401 | |||
2402 | int security_locked_down(enum lockdown_reason what) | ||
2403 | { | ||
2404 | return call_int_hook(locked_down, 0, what); | ||
2405 | } | ||
2406 | EXPORT_SYMBOL(security_locked_down); | ||