167a4b6a8SPaul Moore // SPDX-License-Identifier: GPL-2.0-or-later 267a4b6a8SPaul Moore /* 367a4b6a8SPaul Moore * LSM initialization functions 467a4b6a8SPaul Moore */ 567a4b6a8SPaul Moore 667a4b6a8SPaul Moore #define pr_fmt(fmt) "LSM: " fmt 767a4b6a8SPaul Moore 867a4b6a8SPaul Moore #include <linux/init.h> 967a4b6a8SPaul Moore #include <linux/lsm_hooks.h> 1067a4b6a8SPaul Moore 1167a4b6a8SPaul Moore #include "lsm.h" 1267a4b6a8SPaul Moore 1367a4b6a8SPaul Moore char *lsm_names; 1467a4b6a8SPaul Moore 1567a4b6a8SPaul Moore /* Pointers to LSM sections defined in include/asm-generic/vmlinux.lds.h */ 1667a4b6a8SPaul Moore extern struct lsm_info __start_lsm_info[], __end_lsm_info[]; 1767a4b6a8SPaul Moore extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[]; 1867a4b6a8SPaul Moore 1967a4b6a8SPaul Moore /* Boot-time LSM user choice */ 2067a4b6a8SPaul Moore static __initconst const char *const builtin_lsm_order = CONFIG_LSM; 2167a4b6a8SPaul Moore static __initdata const char *chosen_lsm_order; 2267a4b6a8SPaul Moore static __initdata const char *chosen_major_lsm; 2367a4b6a8SPaul Moore 2467a4b6a8SPaul Moore /* Ordered list of LSMs to initialize. */ 2567a4b6a8SPaul Moore static __initdata struct lsm_info *ordered_lsms[MAX_LSM_COUNT + 1]; 2667a4b6a8SPaul Moore static __initdata struct lsm_info *exclusive; 2767a4b6a8SPaul Moore 2867a4b6a8SPaul Moore static __initdata bool debug; 2967a4b6a8SPaul Moore #define init_debug(...) \ 3067a4b6a8SPaul Moore do { \ 3167a4b6a8SPaul Moore if (debug) \ 3267a4b6a8SPaul Moore pr_info(__VA_ARGS__); \ 3367a4b6a8SPaul Moore } while (0) 3467a4b6a8SPaul Moore 35*37f788f6SPaul Moore #define lsm_order_for_each(iter) \ 36*37f788f6SPaul Moore for ((iter) = ordered_lsms; *(iter); (iter)++) 37*37f788f6SPaul Moore #define lsm_for_each_raw(iter) \ 38*37f788f6SPaul Moore for ((iter) = __start_lsm_info; \ 39*37f788f6SPaul Moore (iter) < __end_lsm_info; (iter)++) 40*37f788f6SPaul Moore #define lsm_early_for_each_raw(iter) \ 41*37f788f6SPaul Moore for ((iter) = __start_early_lsm_info; \ 42*37f788f6SPaul Moore (iter) < __end_early_lsm_info; (iter)++) 43*37f788f6SPaul Moore 4467a4b6a8SPaul Moore static int lsm_append(const char *new, char **result); 4567a4b6a8SPaul Moore 4667a4b6a8SPaul Moore /* Save user chosen LSM */ 4767a4b6a8SPaul Moore static int __init choose_major_lsm(char *str) 4867a4b6a8SPaul Moore { 4967a4b6a8SPaul Moore chosen_major_lsm = str; 5067a4b6a8SPaul Moore return 1; 5167a4b6a8SPaul Moore } 5267a4b6a8SPaul Moore __setup("security=", choose_major_lsm); 5367a4b6a8SPaul Moore 5467a4b6a8SPaul Moore /* Explicitly choose LSM initialization order. */ 5567a4b6a8SPaul Moore static int __init choose_lsm_order(char *str) 5667a4b6a8SPaul Moore { 5767a4b6a8SPaul Moore chosen_lsm_order = str; 5867a4b6a8SPaul Moore return 1; 5967a4b6a8SPaul Moore } 6067a4b6a8SPaul Moore __setup("lsm=", choose_lsm_order); 6167a4b6a8SPaul Moore 6267a4b6a8SPaul Moore /* Enable LSM order debugging. */ 6367a4b6a8SPaul Moore static int __init enable_debug(char *str) 6467a4b6a8SPaul Moore { 6567a4b6a8SPaul Moore debug = true; 6667a4b6a8SPaul Moore return 1; 6767a4b6a8SPaul Moore } 6867a4b6a8SPaul Moore __setup("lsm.debug", enable_debug); 6967a4b6a8SPaul Moore 7067a4b6a8SPaul Moore /* Mark an LSM's enabled flag. */ 7167a4b6a8SPaul Moore static int lsm_enabled_true __initdata = 1; 7267a4b6a8SPaul Moore static int lsm_enabled_false __initdata = 0; 7367a4b6a8SPaul Moore static void __init set_enabled(struct lsm_info *lsm, bool enabled) 7467a4b6a8SPaul Moore { 7567a4b6a8SPaul Moore /* 7667a4b6a8SPaul Moore * When an LSM hasn't configured an enable variable, we can use 7767a4b6a8SPaul Moore * a hard-coded location for storing the default enabled state. 7867a4b6a8SPaul Moore */ 7967a4b6a8SPaul Moore if (!lsm->enabled) { 8067a4b6a8SPaul Moore if (enabled) 8167a4b6a8SPaul Moore lsm->enabled = &lsm_enabled_true; 8267a4b6a8SPaul Moore else 8367a4b6a8SPaul Moore lsm->enabled = &lsm_enabled_false; 8467a4b6a8SPaul Moore } else if (lsm->enabled == &lsm_enabled_true) { 8567a4b6a8SPaul Moore if (!enabled) 8667a4b6a8SPaul Moore lsm->enabled = &lsm_enabled_false; 8767a4b6a8SPaul Moore } else if (lsm->enabled == &lsm_enabled_false) { 8867a4b6a8SPaul Moore if (enabled) 8967a4b6a8SPaul Moore lsm->enabled = &lsm_enabled_true; 9067a4b6a8SPaul Moore } else { 9167a4b6a8SPaul Moore *lsm->enabled = enabled; 9267a4b6a8SPaul Moore } 9367a4b6a8SPaul Moore } 9467a4b6a8SPaul Moore 9567a4b6a8SPaul Moore static inline bool is_enabled(struct lsm_info *lsm) 9667a4b6a8SPaul Moore { 9767a4b6a8SPaul Moore if (!lsm->enabled) 9867a4b6a8SPaul Moore return false; 9967a4b6a8SPaul Moore 10067a4b6a8SPaul Moore return *lsm->enabled; 10167a4b6a8SPaul Moore } 10267a4b6a8SPaul Moore 10367a4b6a8SPaul Moore /* Is an LSM already listed in the ordered LSMs list? */ 10467a4b6a8SPaul Moore static bool __init exists_ordered_lsm(struct lsm_info *lsm) 10567a4b6a8SPaul Moore { 10667a4b6a8SPaul Moore struct lsm_info **check; 10767a4b6a8SPaul Moore 108*37f788f6SPaul Moore lsm_order_for_each(check) { 10967a4b6a8SPaul Moore if (*check == lsm) 11067a4b6a8SPaul Moore return true; 111*37f788f6SPaul Moore } 11267a4b6a8SPaul Moore 11367a4b6a8SPaul Moore return false; 11467a4b6a8SPaul Moore } 11567a4b6a8SPaul Moore 11667a4b6a8SPaul Moore /* Append an LSM to the list of ordered LSMs to initialize. */ 11767a4b6a8SPaul Moore static int last_lsm __initdata; 11867a4b6a8SPaul Moore static void __init append_ordered_lsm(struct lsm_info *lsm, const char *from) 11967a4b6a8SPaul Moore { 12067a4b6a8SPaul Moore /* Ignore duplicate selections. */ 12167a4b6a8SPaul Moore if (exists_ordered_lsm(lsm)) 12267a4b6a8SPaul Moore return; 12367a4b6a8SPaul Moore 12467a4b6a8SPaul Moore if (WARN(last_lsm == MAX_LSM_COUNT, "%s: out of LSM static calls!?\n", from)) 12567a4b6a8SPaul Moore return; 12667a4b6a8SPaul Moore 12767a4b6a8SPaul Moore /* Enable this LSM, if it is not already set. */ 12867a4b6a8SPaul Moore if (!lsm->enabled) 12967a4b6a8SPaul Moore lsm->enabled = &lsm_enabled_true; 13067a4b6a8SPaul Moore ordered_lsms[last_lsm++] = lsm; 13167a4b6a8SPaul Moore 13267a4b6a8SPaul Moore init_debug("%s ordered: %s (%s)\n", from, lsm->name, 13367a4b6a8SPaul Moore is_enabled(lsm) ? "enabled" : "disabled"); 13467a4b6a8SPaul Moore } 13567a4b6a8SPaul Moore 13667a4b6a8SPaul Moore static void __init lsm_set_blob_size(int *need, int *lbs) 13767a4b6a8SPaul Moore { 13867a4b6a8SPaul Moore int offset; 13967a4b6a8SPaul Moore 14067a4b6a8SPaul Moore if (*need <= 0) 14167a4b6a8SPaul Moore return; 14267a4b6a8SPaul Moore 14367a4b6a8SPaul Moore offset = ALIGN(*lbs, sizeof(void *)); 14467a4b6a8SPaul Moore *lbs = offset + *need; 14567a4b6a8SPaul Moore *need = offset; 14667a4b6a8SPaul Moore } 14767a4b6a8SPaul Moore 148e0257856SPaul Moore /** 149e0257856SPaul Moore * lsm_prepare - Prepare the LSM framework for a new LSM 150e0257856SPaul Moore * @lsm: LSM definition 15167a4b6a8SPaul Moore */ 152e0257856SPaul Moore static void __init lsm_prepare(struct lsm_info *lsm) 15367a4b6a8SPaul Moore { 154e0257856SPaul Moore struct lsm_blob_sizes *blobs; 15567a4b6a8SPaul Moore 156e0257856SPaul Moore if (!is_enabled(lsm)) { 157e0257856SPaul Moore set_enabled(lsm, false); 158e0257856SPaul Moore return; 159e0257856SPaul Moore } else if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && exclusive) { 160e0257856SPaul Moore init_debug("exclusive disabled: %s\n", lsm->name); 161e0257856SPaul Moore set_enabled(lsm, false); 162e0257856SPaul Moore return; 163e0257856SPaul Moore } 16467a4b6a8SPaul Moore 165e0257856SPaul Moore /* Mark the LSM as enabled. */ 166e0257856SPaul Moore set_enabled(lsm, true); 16767a4b6a8SPaul Moore if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !exclusive) { 16867a4b6a8SPaul Moore init_debug("exclusive chosen: %s\n", lsm->name); 169e0257856SPaul Moore exclusive = lsm; 17067a4b6a8SPaul Moore } 17167a4b6a8SPaul Moore 172e0257856SPaul Moore /* Register the LSM blob sizes. */ 173e0257856SPaul Moore blobs = lsm->blobs; 174e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_cred, &blob_sizes.lbs_cred); 175e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_file, &blob_sizes.lbs_file); 176e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_ib, &blob_sizes.lbs_ib); 177e0257856SPaul Moore /* inode blob gets an rcu_head in addition to LSM blobs. */ 178e0257856SPaul Moore if (blobs->lbs_inode && blob_sizes.lbs_inode == 0) 179e0257856SPaul Moore blob_sizes.lbs_inode = sizeof(struct rcu_head); 180e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_inode, &blob_sizes.lbs_inode); 181e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_ipc, &blob_sizes.lbs_ipc); 182e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_key, &blob_sizes.lbs_key); 183e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_msg_msg, &blob_sizes.lbs_msg_msg); 184e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_perf_event, &blob_sizes.lbs_perf_event); 185e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_sock, &blob_sizes.lbs_sock); 186e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_superblock, &blob_sizes.lbs_superblock); 187e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_task, &blob_sizes.lbs_task); 188e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_tun_dev, &blob_sizes.lbs_tun_dev); 189e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_xattr_count, 190e0257856SPaul Moore &blob_sizes.lbs_xattr_count); 191e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_bdev, &blob_sizes.lbs_bdev); 192e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_bpf_map, &blob_sizes.lbs_bpf_map); 193e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_bpf_prog, &blob_sizes.lbs_bpf_prog); 194e0257856SPaul Moore lsm_set_blob_size(&blobs->lbs_bpf_token, &blob_sizes.lbs_bpf_token); 19567a4b6a8SPaul Moore } 19667a4b6a8SPaul Moore 19767a4b6a8SPaul Moore /* Initialize a given LSM, if it is enabled. */ 19867a4b6a8SPaul Moore static void __init initialize_lsm(struct lsm_info *lsm) 19967a4b6a8SPaul Moore { 20067a4b6a8SPaul Moore if (is_enabled(lsm)) { 20167a4b6a8SPaul Moore int ret; 20267a4b6a8SPaul Moore 20367a4b6a8SPaul Moore init_debug("initializing %s\n", lsm->name); 20467a4b6a8SPaul Moore ret = lsm->init(); 20567a4b6a8SPaul Moore WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret); 20667a4b6a8SPaul Moore } 20767a4b6a8SPaul Moore } 20867a4b6a8SPaul Moore 20967a4b6a8SPaul Moore /* 21067a4b6a8SPaul Moore * Current index to use while initializing the lsm id list. 21167a4b6a8SPaul Moore */ 21267a4b6a8SPaul Moore u32 lsm_active_cnt __ro_after_init; 21367a4b6a8SPaul Moore const struct lsm_id *lsm_idlist[MAX_LSM_COUNT]; 21467a4b6a8SPaul Moore 21567a4b6a8SPaul Moore /* Populate ordered LSMs list from comma-separated LSM name list. */ 21667a4b6a8SPaul Moore static void __init ordered_lsm_parse(const char *order, const char *origin) 21767a4b6a8SPaul Moore { 21867a4b6a8SPaul Moore struct lsm_info *lsm; 21967a4b6a8SPaul Moore char *sep, *name, *next; 22067a4b6a8SPaul Moore 22167a4b6a8SPaul Moore /* LSM_ORDER_FIRST is always first. */ 222*37f788f6SPaul Moore lsm_for_each_raw(lsm) { 22367a4b6a8SPaul Moore if (lsm->order == LSM_ORDER_FIRST) 22467a4b6a8SPaul Moore append_ordered_lsm(lsm, " first"); 22567a4b6a8SPaul Moore } 22667a4b6a8SPaul Moore 22767a4b6a8SPaul Moore /* Process "security=", if given. */ 22867a4b6a8SPaul Moore if (chosen_major_lsm) { 22967a4b6a8SPaul Moore struct lsm_info *major; 23067a4b6a8SPaul Moore 23167a4b6a8SPaul Moore /* 23267a4b6a8SPaul Moore * To match the original "security=" behavior, this 23367a4b6a8SPaul Moore * explicitly does NOT fallback to another Legacy Major 23467a4b6a8SPaul Moore * if the selected one was separately disabled: disable 23567a4b6a8SPaul Moore * all non-matching Legacy Major LSMs. 23667a4b6a8SPaul Moore */ 237*37f788f6SPaul Moore lsm_for_each_raw(major) { 23867a4b6a8SPaul Moore if ((major->flags & LSM_FLAG_LEGACY_MAJOR) && 23967a4b6a8SPaul Moore strcmp(major->name, chosen_major_lsm) != 0) { 24067a4b6a8SPaul Moore set_enabled(major, false); 24167a4b6a8SPaul Moore init_debug("security=%s disabled: %s (only one legacy major LSM)\n", 24267a4b6a8SPaul Moore chosen_major_lsm, major->name); 24367a4b6a8SPaul Moore } 24467a4b6a8SPaul Moore } 24567a4b6a8SPaul Moore } 24667a4b6a8SPaul Moore 24767a4b6a8SPaul Moore sep = kstrdup(order, GFP_KERNEL); 24867a4b6a8SPaul Moore next = sep; 24967a4b6a8SPaul Moore /* Walk the list, looking for matching LSMs. */ 25067a4b6a8SPaul Moore while ((name = strsep(&next, ",")) != NULL) { 25167a4b6a8SPaul Moore bool found = false; 25267a4b6a8SPaul Moore 253*37f788f6SPaul Moore lsm_for_each_raw(lsm) { 25467a4b6a8SPaul Moore if (strcmp(lsm->name, name) == 0) { 25567a4b6a8SPaul Moore if (lsm->order == LSM_ORDER_MUTABLE) 25667a4b6a8SPaul Moore append_ordered_lsm(lsm, origin); 25767a4b6a8SPaul Moore found = true; 25867a4b6a8SPaul Moore } 25967a4b6a8SPaul Moore } 26067a4b6a8SPaul Moore 26167a4b6a8SPaul Moore if (!found) 26267a4b6a8SPaul Moore init_debug("%s ignored: %s (not built into kernel)\n", 26367a4b6a8SPaul Moore origin, name); 26467a4b6a8SPaul Moore } 26567a4b6a8SPaul Moore 26667a4b6a8SPaul Moore /* Process "security=", if given. */ 26767a4b6a8SPaul Moore if (chosen_major_lsm) { 268*37f788f6SPaul Moore lsm_for_each_raw(lsm) { 26967a4b6a8SPaul Moore if (exists_ordered_lsm(lsm)) 27067a4b6a8SPaul Moore continue; 27167a4b6a8SPaul Moore if (strcmp(lsm->name, chosen_major_lsm) == 0) 27267a4b6a8SPaul Moore append_ordered_lsm(lsm, "security="); 27367a4b6a8SPaul Moore } 27467a4b6a8SPaul Moore } 27567a4b6a8SPaul Moore 27667a4b6a8SPaul Moore /* LSM_ORDER_LAST is always last. */ 277*37f788f6SPaul Moore lsm_for_each_raw(lsm) { 27867a4b6a8SPaul Moore if (lsm->order == LSM_ORDER_LAST) 27967a4b6a8SPaul Moore append_ordered_lsm(lsm, " last"); 28067a4b6a8SPaul Moore } 28167a4b6a8SPaul Moore 28267a4b6a8SPaul Moore /* Disable all LSMs not in the ordered list. */ 283*37f788f6SPaul Moore lsm_for_each_raw(lsm) { 28467a4b6a8SPaul Moore if (exists_ordered_lsm(lsm)) 28567a4b6a8SPaul Moore continue; 28667a4b6a8SPaul Moore set_enabled(lsm, false); 28767a4b6a8SPaul Moore init_debug("%s skipped: %s (not in requested order)\n", 28867a4b6a8SPaul Moore origin, lsm->name); 28967a4b6a8SPaul Moore } 29067a4b6a8SPaul Moore 29167a4b6a8SPaul Moore kfree(sep); 29267a4b6a8SPaul Moore } 29367a4b6a8SPaul Moore 29467a4b6a8SPaul Moore static void __init report_lsm_order(void) 29567a4b6a8SPaul Moore { 29667a4b6a8SPaul Moore struct lsm_info **lsm, *early; 29767a4b6a8SPaul Moore int first = 0; 29867a4b6a8SPaul Moore 29967a4b6a8SPaul Moore pr_info("initializing lsm="); 30067a4b6a8SPaul Moore 30167a4b6a8SPaul Moore /* Report each enabled LSM name, comma separated. */ 302*37f788f6SPaul Moore lsm_early_for_each_raw(early) { 30367a4b6a8SPaul Moore if (is_enabled(early)) 30467a4b6a8SPaul Moore pr_cont("%s%s", first++ == 0 ? "" : ",", early->name); 305*37f788f6SPaul Moore } 306*37f788f6SPaul Moore lsm_order_for_each(lsm) { 30767a4b6a8SPaul Moore if (is_enabled(*lsm)) 30867a4b6a8SPaul Moore pr_cont("%s%s", first++ == 0 ? "" : ",", (*lsm)->name); 309*37f788f6SPaul Moore } 31067a4b6a8SPaul Moore 31167a4b6a8SPaul Moore pr_cont("\n"); 31267a4b6a8SPaul Moore } 31367a4b6a8SPaul Moore 31467a4b6a8SPaul Moore /** 31567a4b6a8SPaul Moore * lsm_early_cred - during initialization allocate a composite cred blob 31667a4b6a8SPaul Moore * @cred: the cred that needs a blob 31767a4b6a8SPaul Moore * 31867a4b6a8SPaul Moore * Allocate the cred blob for all the modules 31967a4b6a8SPaul Moore */ 32067a4b6a8SPaul Moore static void __init lsm_early_cred(struct cred *cred) 32167a4b6a8SPaul Moore { 32267a4b6a8SPaul Moore int rc = lsm_cred_alloc(cred, GFP_KERNEL); 32367a4b6a8SPaul Moore 32467a4b6a8SPaul Moore if (rc) 32567a4b6a8SPaul Moore panic("%s: Early cred alloc failed.\n", __func__); 32667a4b6a8SPaul Moore } 32767a4b6a8SPaul Moore 32867a4b6a8SPaul Moore /** 32967a4b6a8SPaul Moore * lsm_early_task - during initialization allocate a composite task blob 33067a4b6a8SPaul Moore * @task: the task that needs a blob 33167a4b6a8SPaul Moore * 33267a4b6a8SPaul Moore * Allocate the task blob for all the modules 33367a4b6a8SPaul Moore */ 33467a4b6a8SPaul Moore static void __init lsm_early_task(struct task_struct *task) 33567a4b6a8SPaul Moore { 33667a4b6a8SPaul Moore int rc = lsm_task_alloc(task); 33767a4b6a8SPaul Moore 33867a4b6a8SPaul Moore if (rc) 33967a4b6a8SPaul Moore panic("%s: Early task alloc failed.\n", __func__); 34067a4b6a8SPaul Moore } 34167a4b6a8SPaul Moore 34267a4b6a8SPaul Moore static void __init ordered_lsm_init(void) 34367a4b6a8SPaul Moore { 34467a4b6a8SPaul Moore struct lsm_info **lsm; 34567a4b6a8SPaul Moore 34667a4b6a8SPaul Moore if (chosen_lsm_order) { 34767a4b6a8SPaul Moore if (chosen_major_lsm) { 34867a4b6a8SPaul Moore pr_warn("security=%s is ignored because it is superseded by lsm=%s\n", 34967a4b6a8SPaul Moore chosen_major_lsm, chosen_lsm_order); 35067a4b6a8SPaul Moore chosen_major_lsm = NULL; 35167a4b6a8SPaul Moore } 35267a4b6a8SPaul Moore ordered_lsm_parse(chosen_lsm_order, "cmdline"); 35367a4b6a8SPaul Moore } else 35467a4b6a8SPaul Moore ordered_lsm_parse(builtin_lsm_order, "builtin"); 35567a4b6a8SPaul Moore 356*37f788f6SPaul Moore lsm_order_for_each(lsm) { 357e0257856SPaul Moore lsm_prepare(*lsm); 358*37f788f6SPaul Moore } 35967a4b6a8SPaul Moore 36067a4b6a8SPaul Moore report_lsm_order(); 36167a4b6a8SPaul Moore 36267a4b6a8SPaul Moore init_debug("cred blob size = %d\n", blob_sizes.lbs_cred); 36367a4b6a8SPaul Moore init_debug("file blob size = %d\n", blob_sizes.lbs_file); 36467a4b6a8SPaul Moore init_debug("ib blob size = %d\n", blob_sizes.lbs_ib); 36567a4b6a8SPaul Moore init_debug("inode blob size = %d\n", blob_sizes.lbs_inode); 36667a4b6a8SPaul Moore init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc); 36767a4b6a8SPaul Moore #ifdef CONFIG_KEYS 36867a4b6a8SPaul Moore init_debug("key blob size = %d\n", blob_sizes.lbs_key); 36967a4b6a8SPaul Moore #endif /* CONFIG_KEYS */ 37067a4b6a8SPaul Moore init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg); 37167a4b6a8SPaul Moore init_debug("sock blob size = %d\n", blob_sizes.lbs_sock); 37267a4b6a8SPaul Moore init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock); 37367a4b6a8SPaul Moore init_debug("perf event blob size = %d\n", blob_sizes.lbs_perf_event); 37467a4b6a8SPaul Moore init_debug("task blob size = %d\n", blob_sizes.lbs_task); 37567a4b6a8SPaul Moore init_debug("tun device blob size = %d\n", blob_sizes.lbs_tun_dev); 37667a4b6a8SPaul Moore init_debug("xattr slots = %d\n", blob_sizes.lbs_xattr_count); 37767a4b6a8SPaul Moore init_debug("bdev blob size = %d\n", blob_sizes.lbs_bdev); 37867a4b6a8SPaul Moore init_debug("bpf map blob size = %d\n", blob_sizes.lbs_bpf_map); 37967a4b6a8SPaul Moore init_debug("bpf prog blob size = %d\n", blob_sizes.lbs_bpf_prog); 38067a4b6a8SPaul Moore init_debug("bpf token blob size = %d\n", blob_sizes.lbs_bpf_token); 38167a4b6a8SPaul Moore 38267a4b6a8SPaul Moore /* 38367a4b6a8SPaul Moore * Create any kmem_caches needed for blobs 38467a4b6a8SPaul Moore */ 38567a4b6a8SPaul Moore if (blob_sizes.lbs_file) 38667a4b6a8SPaul Moore lsm_file_cache = kmem_cache_create("lsm_file_cache", 38767a4b6a8SPaul Moore blob_sizes.lbs_file, 0, 38867a4b6a8SPaul Moore SLAB_PANIC, NULL); 38967a4b6a8SPaul Moore if (blob_sizes.lbs_inode) 39067a4b6a8SPaul Moore lsm_inode_cache = kmem_cache_create("lsm_inode_cache", 39167a4b6a8SPaul Moore blob_sizes.lbs_inode, 0, 39267a4b6a8SPaul Moore SLAB_PANIC, NULL); 39367a4b6a8SPaul Moore 39467a4b6a8SPaul Moore lsm_early_cred((struct cred *) current->cred); 39567a4b6a8SPaul Moore lsm_early_task(current); 396*37f788f6SPaul Moore lsm_order_for_each(lsm) { 39767a4b6a8SPaul Moore initialize_lsm(*lsm); 39867a4b6a8SPaul Moore } 399*37f788f6SPaul Moore } 40067a4b6a8SPaul Moore 40167a4b6a8SPaul Moore static bool match_last_lsm(const char *list, const char *lsm) 40267a4b6a8SPaul Moore { 40367a4b6a8SPaul Moore const char *last; 40467a4b6a8SPaul Moore 40567a4b6a8SPaul Moore if (WARN_ON(!list || !lsm)) 40667a4b6a8SPaul Moore return false; 40767a4b6a8SPaul Moore last = strrchr(list, ','); 40867a4b6a8SPaul Moore if (last) 40967a4b6a8SPaul Moore /* Pass the comma, strcmp() will check for '\0' */ 41067a4b6a8SPaul Moore last++; 41167a4b6a8SPaul Moore else 41267a4b6a8SPaul Moore last = list; 41367a4b6a8SPaul Moore return !strcmp(last, lsm); 41467a4b6a8SPaul Moore } 41567a4b6a8SPaul Moore 41667a4b6a8SPaul Moore static int lsm_append(const char *new, char **result) 41767a4b6a8SPaul Moore { 41867a4b6a8SPaul Moore char *cp; 41967a4b6a8SPaul Moore 42067a4b6a8SPaul Moore if (*result == NULL) { 42167a4b6a8SPaul Moore *result = kstrdup(new, GFP_KERNEL); 42267a4b6a8SPaul Moore if (*result == NULL) 42367a4b6a8SPaul Moore return -ENOMEM; 42467a4b6a8SPaul Moore } else { 42567a4b6a8SPaul Moore /* Check if it is the last registered name */ 42667a4b6a8SPaul Moore if (match_last_lsm(*result, new)) 42767a4b6a8SPaul Moore return 0; 42867a4b6a8SPaul Moore cp = kasprintf(GFP_KERNEL, "%s,%s", *result, new); 42967a4b6a8SPaul Moore if (cp == NULL) 43067a4b6a8SPaul Moore return -ENOMEM; 43167a4b6a8SPaul Moore kfree(*result); 43267a4b6a8SPaul Moore *result = cp; 43367a4b6a8SPaul Moore } 43467a4b6a8SPaul Moore return 0; 43567a4b6a8SPaul Moore } 43667a4b6a8SPaul Moore 43767a4b6a8SPaul Moore static void __init lsm_static_call_init(struct security_hook_list *hl) 43867a4b6a8SPaul Moore { 43967a4b6a8SPaul Moore struct lsm_static_call *scall = hl->scalls; 44067a4b6a8SPaul Moore int i; 44167a4b6a8SPaul Moore 44267a4b6a8SPaul Moore for (i = 0; i < MAX_LSM_COUNT; i++) { 44367a4b6a8SPaul Moore /* Update the first static call that is not used yet */ 44467a4b6a8SPaul Moore if (!scall->hl) { 44567a4b6a8SPaul Moore __static_call_update(scall->key, scall->trampoline, 44667a4b6a8SPaul Moore hl->hook.lsm_func_addr); 44767a4b6a8SPaul Moore scall->hl = hl; 44867a4b6a8SPaul Moore static_branch_enable(scall->active); 44967a4b6a8SPaul Moore return; 45067a4b6a8SPaul Moore } 45167a4b6a8SPaul Moore scall++; 45267a4b6a8SPaul Moore } 45367a4b6a8SPaul Moore panic("%s - Ran out of static slots.\n", __func__); 45467a4b6a8SPaul Moore } 45567a4b6a8SPaul Moore 45667a4b6a8SPaul Moore /** 45767a4b6a8SPaul Moore * security_add_hooks - Add a modules hooks to the hook lists. 45867a4b6a8SPaul Moore * @hooks: the hooks to add 45967a4b6a8SPaul Moore * @count: the number of hooks to add 46067a4b6a8SPaul Moore * @lsmid: the identification information for the security module 46167a4b6a8SPaul Moore * 46267a4b6a8SPaul Moore * Each LSM has to register its hooks with the infrastructure. 46367a4b6a8SPaul Moore */ 46467a4b6a8SPaul Moore void __init security_add_hooks(struct security_hook_list *hooks, int count, 46567a4b6a8SPaul Moore const struct lsm_id *lsmid) 46667a4b6a8SPaul Moore { 46767a4b6a8SPaul Moore int i; 46867a4b6a8SPaul Moore 46967a4b6a8SPaul Moore /* 47067a4b6a8SPaul Moore * A security module may call security_add_hooks() more 47167a4b6a8SPaul Moore * than once during initialization, and LSM initialization 47267a4b6a8SPaul Moore * is serialized. Landlock is one such case. 47367a4b6a8SPaul Moore * Look at the previous entry, if there is one, for duplication. 47467a4b6a8SPaul Moore */ 47567a4b6a8SPaul Moore if (lsm_active_cnt == 0 || lsm_idlist[lsm_active_cnt - 1] != lsmid) { 47667a4b6a8SPaul Moore if (lsm_active_cnt >= MAX_LSM_COUNT) 47767a4b6a8SPaul Moore panic("%s Too many LSMs registered.\n", __func__); 47867a4b6a8SPaul Moore lsm_idlist[lsm_active_cnt++] = lsmid; 47967a4b6a8SPaul Moore } 48067a4b6a8SPaul Moore 48167a4b6a8SPaul Moore for (i = 0; i < count; i++) { 48267a4b6a8SPaul Moore hooks[i].lsmid = lsmid; 48367a4b6a8SPaul Moore lsm_static_call_init(&hooks[i]); 48467a4b6a8SPaul Moore } 48567a4b6a8SPaul Moore 48667a4b6a8SPaul Moore /* 48767a4b6a8SPaul Moore * Don't try to append during early_security_init(), we'll come back 48867a4b6a8SPaul Moore * and fix this up afterwards. 48967a4b6a8SPaul Moore */ 49067a4b6a8SPaul Moore if (slab_is_available()) { 49167a4b6a8SPaul Moore if (lsm_append(lsmid->name, &lsm_names) < 0) 49267a4b6a8SPaul Moore panic("%s - Cannot get early memory.\n", __func__); 49367a4b6a8SPaul Moore } 49467a4b6a8SPaul Moore } 49567a4b6a8SPaul Moore 49667a4b6a8SPaul Moore int __init early_security_init(void) 49767a4b6a8SPaul Moore { 49867a4b6a8SPaul Moore struct lsm_info *lsm; 49967a4b6a8SPaul Moore 500*37f788f6SPaul Moore lsm_early_for_each_raw(lsm) { 50167a4b6a8SPaul Moore if (!lsm->enabled) 50267a4b6a8SPaul Moore lsm->enabled = &lsm_enabled_true; 503e0257856SPaul Moore lsm_prepare(lsm); 50467a4b6a8SPaul Moore initialize_lsm(lsm); 50567a4b6a8SPaul Moore } 50667a4b6a8SPaul Moore 50767a4b6a8SPaul Moore return 0; 50867a4b6a8SPaul Moore } 50967a4b6a8SPaul Moore 51067a4b6a8SPaul Moore /** 51167a4b6a8SPaul Moore * security_init - initializes the security framework 51267a4b6a8SPaul Moore * 51367a4b6a8SPaul Moore * This should be called early in the kernel initialization sequence. 51467a4b6a8SPaul Moore */ 51567a4b6a8SPaul Moore int __init security_init(void) 51667a4b6a8SPaul Moore { 51767a4b6a8SPaul Moore struct lsm_info *lsm; 51867a4b6a8SPaul Moore 51967a4b6a8SPaul Moore init_debug("legacy security=%s\n", chosen_major_lsm ? : " *unspecified*"); 52067a4b6a8SPaul Moore init_debug(" CONFIG_LSM=%s\n", builtin_lsm_order); 52167a4b6a8SPaul Moore init_debug("boot arg lsm=%s\n", chosen_lsm_order ? : " *unspecified*"); 52267a4b6a8SPaul Moore 52367a4b6a8SPaul Moore /* 52467a4b6a8SPaul Moore * Append the names of the early LSM modules now that kmalloc() is 52567a4b6a8SPaul Moore * available 52667a4b6a8SPaul Moore */ 527*37f788f6SPaul Moore lsm_early_for_each_raw(lsm) { 52867a4b6a8SPaul Moore init_debug(" early started: %s (%s)\n", lsm->name, 52967a4b6a8SPaul Moore is_enabled(lsm) ? "enabled" : "disabled"); 53067a4b6a8SPaul Moore if (lsm->enabled) 53167a4b6a8SPaul Moore lsm_append(lsm->name, &lsm_names); 53267a4b6a8SPaul Moore } 53367a4b6a8SPaul Moore 53467a4b6a8SPaul Moore /* Load LSMs in specified order. */ 53567a4b6a8SPaul Moore ordered_lsm_init(); 53667a4b6a8SPaul Moore 53767a4b6a8SPaul Moore return 0; 53867a4b6a8SPaul Moore } 539