diff options
Diffstat (limited to 'security/security.c')
| -rw-r--r-- | security/security.c | 62 | 
1 files changed, 54 insertions, 8 deletions
diff --git a/security/security.c b/security/security.c index 250ee2d76406..1bc000f834e2 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 BLOCKING_NOTIFIER_HEAD(blocking_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_blocking_lsm_notifier(enum lsm_event event, void *data) @@ -870,6 +904,12 @@ int security_move_mount(const struct path *from_path, const struct path *to_path  	return call_int_hook(move_mount, 0, from_path, to_path);  } +int security_path_notify(const struct path *path, u64 mask, +				unsigned int obj_type) +{ +	return call_int_hook(path_notify, 0, path, mask, obj_type); +} +  int security_inode_alloc(struct inode *inode)  {  	int rc = lsm_inode_alloc(inode); @@ -2358,3 +2398,9 @@ void security_bpf_prog_free(struct bpf_prog_aux *aux)  	call_void_hook(bpf_prog_free_security, aux);  }  #endif /* CONFIG_BPF_SYSCALL */ + +int security_locked_down(enum lockdown_reason what) +{ +	return call_int_hook(locked_down, 0, what); +} +EXPORT_SYMBOL(security_locked_down);  |