@@ -18,6 +18,9 @@ int lsm_enabled_false = 0;
extern struct lsm_info __start_lsm_info[], __end_lsm_info[];
extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[];
+/* Number of "early" LSMs */
+static __initdata unsigned int lsm_count_early;
+
/* Build and boot-time LSM ordering. */
static __initconst const char *const lsm_order_builtin = CONFIG_LSM;
static __initdata const char *lsm_order_cmdline;
@@ -310,78 +313,6 @@ static void __init lsm_init_single(struct lsm_info *lsm)
WARN(ret, "%s failed to initialize: %d\n", lsm->id->name, ret);
}
-/**
- * lsm_init_ordered - Initialize the ordered LSMs
- */
-static void __init lsm_init_ordered(void)
-{
- struct lsm_info **lsm;
- struct lsm_info *early;
-
- if (lsm_order_cmdline) {
- if (lsm_order_legacy) {
- pr_warn("security=%s is ignored because it is superseded by lsm=%s\n",
- lsm_order_legacy, lsm_order_cmdline);
- lsm_order_legacy = NULL;
- }
- lsm_order_parse(lsm_order_cmdline, "cmdline");
- } else
- lsm_order_parse(lsm_order_builtin, "builtin");
-
- lsm_order_for_each(lsm) {
- lsm_prep_single(*lsm);
- }
-
- pr_info("initializing lsm=");
- lsm_early_for_each_raw(early) {
- if (lsm_is_enabled(early))
- pr_cont("%s%s",
- early == __start_early_lsm_info ? "" : ",",
- early->id->name);
- }
- lsm_order_for_each(lsm) {
- if (lsm_is_enabled(*lsm))
- pr_cont("%s%s",
- lsm == lsm_order ? "" : ",", (*lsm)->id->name);
- }
- pr_cont("\n");
-
- init_debug("cred blob size = %d\n", blob_sizes.lbs_cred);
- init_debug("file blob size = %d\n", blob_sizes.lbs_file);
- init_debug("ib blob size = %d\n", blob_sizes.lbs_ib);
- init_debug("inode blob size = %d\n", blob_sizes.lbs_inode);
- init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc);
-#ifdef CONFIG_KEYS
- init_debug("key blob size = %d\n", blob_sizes.lbs_key);
-#endif /* CONFIG_KEYS */
- init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg);
- init_debug("sock blob size = %d\n", blob_sizes.lbs_sock);
- init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
- init_debug("perf event blob size = %d\n", blob_sizes.lbs_perf_event);
- init_debug("task blob size = %d\n", blob_sizes.lbs_task);
- init_debug("tun device blob size = %d\n", blob_sizes.lbs_tun_dev);
- init_debug("xattr slots = %d\n", blob_sizes.lbs_xattr_count);
- init_debug("bdev blob size = %d\n", blob_sizes.lbs_bdev);
-
- if (blob_sizes.lbs_file)
- lsm_file_cache = kmem_cache_create("lsm_file_cache",
- blob_sizes.lbs_file, 0,
- SLAB_PANIC, NULL);
- if (blob_sizes.lbs_inode)
- lsm_inode_cache = kmem_cache_create("lsm_inode_cache",
- blob_sizes.lbs_inode, 0,
- SLAB_PANIC, NULL);
-
- if (lsm_cred_alloc((struct cred *)current->cred, GFP_KERNEL))
- panic("%s: early cred alloc failed.\n", __func__);
- if (lsm_task_alloc(current))
- panic("%s: early task alloc failed.\n", __func__);
-
- lsm_order_for_each(lsm) {
- lsm_init_single(*lsm);
- }
-}
-
static void __init lsm_static_call_init(struct security_hook_list *hl)
{
struct lsm_static_call *scall = hl->scalls;
@@ -429,35 +360,92 @@ int __init early_security_init(void)
lsm_order_append(lsm, "early");
lsm_prep_single(lsm);
lsm_init_single(lsm);
+ lsm_count_early++;
}
return 0;
}
/**
- * security_init - initializes the security framework
+ * security_init - Initializes the LSM framework
*
* This should be called early in the kernel initialization sequence.
*/
int __init security_init(void)
{
- struct lsm_info *lsm;
+ unsigned int cnt;
+ struct lsm_info **lsm;
+ struct lsm_info *early;
init_debug("legacy security=%s\n", lsm_order_legacy ? : " *unspecified*");
init_debug(" CONFIG_LSM=%s\n", lsm_order_builtin);
init_debug("boot arg lsm=%s\n", lsm_order_cmdline ? : " *unspecified*");
- /*
- * Append the names of the early LSM modules now that kmalloc() is
- * available
- */
- lsm_early_for_each_raw(lsm) {
- init_debug(" early started: %s (%s)\n", lsm->id->name,
- lsm_is_enabled(lsm) ? "enabled" : "disabled");
- }
+ if (lsm_order_cmdline) {
+ if (lsm_order_legacy) {
+ pr_warn("security=%s is ignored because it is superseded by lsm=%s\n",
+ lsm_order_legacy, lsm_order_cmdline);
+ lsm_order_legacy = NULL;
+ }
+ lsm_order_parse(lsm_order_cmdline, "cmdline");
+ } else
+ lsm_order_parse(lsm_order_builtin, "builtin");
- /* Load LSMs in specified order. */
- lsm_init_ordered();
+ lsm_order_for_each(lsm)
+ lsm_prep_single(*lsm);
+
+ pr_info("initializing lsm=");
+ lsm_early_for_each_raw(early) {
+ if (lsm_is_enabled(early))
+ pr_cont("%s%s",
+ early == __start_early_lsm_info ? "" : ",",
+ early->id->name);
+ }
+ lsm_order_for_each(lsm) {
+ if (lsm_is_enabled(*lsm))
+ pr_cont("%s%s",
+ lsm == lsm_order ? "" : ",", (*lsm)->id->name);
+ }
+ pr_cont("\n");
+
+ init_debug("cred blob size = %d\n", blob_sizes.lbs_cred);
+ init_debug("file blob size = %d\n", blob_sizes.lbs_file);
+ init_debug("ib blob size = %d\n", blob_sizes.lbs_ib);
+ init_debug("inode blob size = %d\n", blob_sizes.lbs_inode);
+ init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc);
+#ifdef CONFIG_KEYS
+ init_debug("key blob size = %d\n", blob_sizes.lbs_key);
+#endif /* CONFIG_KEYS */
+ init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg);
+ init_debug("sock blob size = %d\n", blob_sizes.lbs_sock);
+ init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
+ init_debug("perf event blob size = %d\n", blob_sizes.lbs_perf_event);
+ init_debug("task blob size = %d\n", blob_sizes.lbs_task);
+ init_debug("tun device blob size = %d\n", blob_sizes.lbs_tun_dev);
+ init_debug("xattr slots = %d\n", blob_sizes.lbs_xattr_count);
+ init_debug("bdev blob size = %d\n", blob_sizes.lbs_bdev);
+
+ if (blob_sizes.lbs_file)
+ lsm_file_cache = kmem_cache_create("lsm_file_cache",
+ blob_sizes.lbs_file, 0,
+ SLAB_PANIC, NULL);
+ if (blob_sizes.lbs_inode)
+ lsm_inode_cache = kmem_cache_create("lsm_inode_cache",
+ blob_sizes.lbs_inode, 0,
+ SLAB_PANIC, NULL);
+
+ if (lsm_cred_alloc((struct cred *)current->cred, GFP_KERNEL))
+ panic("%s: early cred alloc failed.\n", __func__);
+ if (lsm_task_alloc(current))
+ panic("%s: early task alloc failed.\n", __func__);
+
+ cnt = 0;
+ lsm_order_for_each(lsm) {
+ /* skip the "early" LSMs as they have already been setup */
+ if (cnt++ < lsm_count_early)
+ continue;
+ lsm_init_single(*lsm);
+ }
return 0;
}
One part of a larger effort to cleanup the LSM framework initialization code. Signed-off-by: Paul Moore <paul@paul-moore.com> --- security/lsm_init.c | 156 ++++++++++++++++++++------------------------ 1 file changed, 72 insertions(+), 84 deletions(-)