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 132d671726SPaul Moore /* LSM enabled constants. */ 142d671726SPaul Moore static __initdata int lsm_enabled_true = 1; 152d671726SPaul Moore static __initdata int lsm_enabled_false = 0; 162d671726SPaul Moore 1767a4b6a8SPaul Moore /* Pointers to LSM sections defined in include/asm-generic/vmlinux.lds.h */ 1867a4b6a8SPaul Moore extern struct lsm_info __start_lsm_info[], __end_lsm_info[]; 1967a4b6a8SPaul Moore extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[]; 2067a4b6a8SPaul Moore 2145a41d13SPaul Moore /* Number of "early" LSMs */ 2245a41d13SPaul Moore static __initdata unsigned int lsm_count_early; 2345a41d13SPaul Moore 24592b104fSPaul Moore /* Build and boot-time LSM ordering. */ 25592b104fSPaul Moore static __initconst const char *const lsm_order_builtin = CONFIG_LSM; 26592b104fSPaul Moore static __initdata const char *lsm_order_cmdline; 27592b104fSPaul Moore static __initdata const char *lsm_order_legacy; 2867a4b6a8SPaul Moore 2967a4b6a8SPaul Moore /* Ordered list of LSMs to initialize. */ 30592b104fSPaul Moore static __initdata struct lsm_info *lsm_order[MAX_LSM_COUNT + 1]; 31592b104fSPaul Moore static __initdata struct lsm_info *lsm_exclusive; 3267a4b6a8SPaul Moore 3337f788f6SPaul Moore #define lsm_order_for_each(iter) \ 34592b104fSPaul Moore for ((iter) = lsm_order; *(iter); (iter)++) 3537f788f6SPaul Moore #define lsm_for_each_raw(iter) \ 3637f788f6SPaul Moore for ((iter) = __start_lsm_info; \ 3737f788f6SPaul Moore (iter) < __end_lsm_info; (iter)++) 3837f788f6SPaul Moore #define lsm_early_for_each_raw(iter) \ 3937f788f6SPaul Moore for ((iter) = __start_early_lsm_info; \ 4037f788f6SPaul Moore (iter) < __end_early_lsm_info; (iter)++) 4137f788f6SPaul Moore 42*cdc02881SPaul Moore #define lsm_initcall(level) \ 43*cdc02881SPaul Moore ({ \ 44*cdc02881SPaul Moore int _r, _rc = 0; \ 45*cdc02881SPaul Moore struct lsm_info **_lp, *_l; \ 46*cdc02881SPaul Moore lsm_order_for_each(_lp) { \ 47*cdc02881SPaul Moore _l = *_lp; \ 48*cdc02881SPaul Moore if (!_l->initcall_##level) \ 49*cdc02881SPaul Moore continue; \ 50*cdc02881SPaul Moore lsm_pr_dbg("running %s %s initcall", \ 51*cdc02881SPaul Moore _l->id->name, #level); \ 52*cdc02881SPaul Moore _r = _l->initcall_##level(); \ 53*cdc02881SPaul Moore if (_r) { \ 54*cdc02881SPaul Moore pr_warn("failed LSM %s %s initcall with errno %d\n", \ 55*cdc02881SPaul Moore _l->id->name, #level, _r); \ 56*cdc02881SPaul Moore if (!_rc) \ 57*cdc02881SPaul Moore _rc = _r; \ 58*cdc02881SPaul Moore } \ 59*cdc02881SPaul Moore } \ 60*cdc02881SPaul Moore _rc; \ 61*cdc02881SPaul Moore }) 62*cdc02881SPaul Moore 63592b104fSPaul Moore /** 64592b104fSPaul Moore * lsm_choose_security - Legacy "major" LSM selection 65592b104fSPaul Moore * @str: kernel command line parameter 66592b104fSPaul Moore */ 67592b104fSPaul Moore static int __init lsm_choose_security(char *str) 6867a4b6a8SPaul Moore { 69592b104fSPaul Moore lsm_order_legacy = str; 7067a4b6a8SPaul Moore return 1; 7167a4b6a8SPaul Moore } 72592b104fSPaul Moore __setup("security=", lsm_choose_security); 7367a4b6a8SPaul Moore 74592b104fSPaul Moore /** 75592b104fSPaul Moore * lsm_choose_lsm - Modern LSM selection 76592b104fSPaul Moore * @str: kernel command line parameter 77592b104fSPaul Moore */ 78592b104fSPaul Moore static int __init lsm_choose_lsm(char *str) 7967a4b6a8SPaul Moore { 80592b104fSPaul Moore lsm_order_cmdline = str; 8167a4b6a8SPaul Moore return 1; 8267a4b6a8SPaul Moore } 83592b104fSPaul Moore __setup("lsm=", lsm_choose_lsm); 8467a4b6a8SPaul Moore 85592b104fSPaul Moore /** 86592b104fSPaul Moore * lsm_debug_enable - Enable LSM framework debugging 87592b104fSPaul Moore * @str: kernel command line parameter 88592b104fSPaul Moore * 89592b104fSPaul Moore * Currently we only provide debug info during LSM initialization, but we may 90592b104fSPaul Moore * want to expand this in the future. 91592b104fSPaul Moore */ 92592b104fSPaul Moore static int __init lsm_debug_enable(char *str) 9367a4b6a8SPaul Moore { 945137e583SPaul Moore lsm_debug = true; 9567a4b6a8SPaul Moore return 1; 9667a4b6a8SPaul Moore } 97592b104fSPaul Moore __setup("lsm.debug", lsm_debug_enable); 9867a4b6a8SPaul Moore 992d671726SPaul Moore /** 1002d671726SPaul Moore * lsm_enabled_set - Mark a LSM as enabled 1012d671726SPaul Moore * @lsm: LSM definition 1022d671726SPaul Moore * @enabled: enabled flag 1032d671726SPaul Moore */ 1042d671726SPaul Moore static void __init lsm_enabled_set(struct lsm_info *lsm, bool enabled) 10567a4b6a8SPaul Moore { 10667a4b6a8SPaul Moore /* 10767a4b6a8SPaul Moore * When an LSM hasn't configured an enable variable, we can use 10867a4b6a8SPaul Moore * a hard-coded location for storing the default enabled state. 10967a4b6a8SPaul Moore */ 1102d671726SPaul Moore if (!lsm->enabled || 1112d671726SPaul Moore lsm->enabled == &lsm_enabled_true || 1122d671726SPaul Moore lsm->enabled == &lsm_enabled_false) { 1132d671726SPaul Moore lsm->enabled = enabled ? &lsm_enabled_true : &lsm_enabled_false; 11467a4b6a8SPaul Moore } else { 11567a4b6a8SPaul Moore *lsm->enabled = enabled; 11667a4b6a8SPaul Moore } 11767a4b6a8SPaul Moore } 11867a4b6a8SPaul Moore 1192d671726SPaul Moore /** 1202d671726SPaul Moore * lsm_is_enabled - Determine if a LSM is enabled 1212d671726SPaul Moore * @lsm: LSM definition 1222d671726SPaul Moore */ 1232d671726SPaul Moore static inline bool lsm_is_enabled(struct lsm_info *lsm) 12467a4b6a8SPaul Moore { 1252d671726SPaul Moore return (lsm->enabled ? *lsm->enabled : false); 12667a4b6a8SPaul Moore } 12767a4b6a8SPaul Moore 128a748372aSPaul Moore /** 129a748372aSPaul Moore * lsm_order_exists - Determine if a LSM exists in the ordered list 130a748372aSPaul Moore * @lsm: LSM definition 131a748372aSPaul Moore */ 132a748372aSPaul Moore static bool __init lsm_order_exists(struct lsm_info *lsm) 13367a4b6a8SPaul Moore { 13467a4b6a8SPaul Moore struct lsm_info **check; 13567a4b6a8SPaul Moore 13637f788f6SPaul Moore lsm_order_for_each(check) { 13767a4b6a8SPaul Moore if (*check == lsm) 13867a4b6a8SPaul Moore return true; 13937f788f6SPaul Moore } 14067a4b6a8SPaul Moore 14167a4b6a8SPaul Moore return false; 14267a4b6a8SPaul Moore } 14367a4b6a8SPaul Moore 14424a9c589SPaul Moore /** 14524a9c589SPaul Moore * lsm_order_append - Append a LSM to the ordered list 14624a9c589SPaul Moore * @lsm: LSM definition 14724a9c589SPaul Moore * @src: source of the addition 14824a9c589SPaul Moore * 14924a9c589SPaul Moore * Append @lsm to the enabled LSM array after ensuring that it hasn't been 15024a9c589SPaul Moore * explicitly disabled, is a duplicate entry, or would run afoul of the 15124a9c589SPaul Moore * LSM_FLAG_EXCLUSIVE logic. 15224a9c589SPaul Moore */ 15324a9c589SPaul Moore static void __init lsm_order_append(struct lsm_info *lsm, const char *src) 15467a4b6a8SPaul Moore { 15567a4b6a8SPaul Moore /* Ignore duplicate selections. */ 156a748372aSPaul Moore if (lsm_order_exists(lsm)) 15767a4b6a8SPaul Moore return; 15867a4b6a8SPaul Moore 15924a9c589SPaul Moore /* Skip explicitly disabled LSMs. */ 1605137e583SPaul Moore if (lsm->enabled && !lsm_is_enabled(lsm)) { 1615137e583SPaul Moore lsm_pr_dbg("skip previously disabled LSM %s:%s\n", 1625137e583SPaul Moore src, lsm->id->name); 1635137e583SPaul Moore return; 1645137e583SPaul Moore } 16567a4b6a8SPaul Moore 1665137e583SPaul Moore if (lsm_active_cnt == MAX_LSM_COUNT) { 1675137e583SPaul Moore pr_warn("exceeded maximum LSM count on %s:%s\n", 1685137e583SPaul Moore src, lsm->id->name); 16924a9c589SPaul Moore lsm_enabled_set(lsm, false); 1705137e583SPaul Moore return; 17124a9c589SPaul Moore } 17267a4b6a8SPaul Moore 17324a9c589SPaul Moore if (lsm->flags & LSM_FLAG_EXCLUSIVE) { 17424a9c589SPaul Moore if (lsm_exclusive) { 1755137e583SPaul Moore lsm_pr_dbg("skip exclusive LSM conflict %s:%s\n", 1765137e583SPaul Moore src, lsm->id->name); 17724a9c589SPaul Moore lsm_enabled_set(lsm, false); 1785137e583SPaul Moore return; 17924a9c589SPaul Moore } else { 1805137e583SPaul Moore lsm_pr_dbg("select exclusive LSM %s:%s\n", 1815137e583SPaul Moore src, lsm->id->name); 18224a9c589SPaul Moore lsm_exclusive = lsm; 18324a9c589SPaul Moore } 18424a9c589SPaul Moore } 18524a9c589SPaul Moore 18624a9c589SPaul Moore lsm_enabled_set(lsm, true); 18724a9c589SPaul Moore lsm_order[lsm_active_cnt] = lsm; 18824a9c589SPaul Moore lsm_idlist[lsm_active_cnt++] = lsm->id; 18924a9c589SPaul Moore 1905137e583SPaul Moore lsm_pr_dbg("enabling LSM %s:%s\n", src, lsm->id->name); 19167a4b6a8SPaul Moore } 19267a4b6a8SPaul Moore 193291271e6SPaul Moore /** 1943423c639SPaul Moore * lsm_order_parse - Parse the comma delimited LSM list 1953423c639SPaul Moore * @list: LSM list 1963423c639SPaul Moore * @src: source of the list 1973423c639SPaul Moore */ 1983423c639SPaul Moore static void __init lsm_order_parse(const char *list, const char *src) 1993423c639SPaul Moore { 2003423c639SPaul Moore struct lsm_info *lsm; 2013423c639SPaul Moore char *sep, *name, *next; 2023423c639SPaul Moore 2033423c639SPaul Moore /* Handle any Legacy LSM exclusions if one was specified. */ 2043423c639SPaul Moore if (lsm_order_legacy) { 2053423c639SPaul Moore /* 2063423c639SPaul Moore * To match the original "security=" behavior, this explicitly 2073423c639SPaul Moore * does NOT fallback to another Legacy Major if the selected 2083423c639SPaul Moore * one was separately disabled: disable all non-matching 2093423c639SPaul Moore * Legacy Major LSMs. 2103423c639SPaul Moore */ 2113423c639SPaul Moore lsm_for_each_raw(lsm) { 2123423c639SPaul Moore if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) && 2133423c639SPaul Moore strcmp(lsm->id->name, lsm_order_legacy)) { 2143423c639SPaul Moore lsm_enabled_set(lsm, false); 2153423c639SPaul Moore lsm_pr_dbg("skip legacy LSM conflict %s:%s\n", 2163423c639SPaul Moore src, lsm->id->name); 2173423c639SPaul Moore } 2183423c639SPaul Moore } 2193423c639SPaul Moore } 2203423c639SPaul Moore 2213423c639SPaul Moore /* LSM_ORDER_FIRST */ 2223423c639SPaul Moore lsm_for_each_raw(lsm) { 2233423c639SPaul Moore if (lsm->order == LSM_ORDER_FIRST) 2243423c639SPaul Moore lsm_order_append(lsm, "first"); 2253423c639SPaul Moore } 2263423c639SPaul Moore 2273423c639SPaul Moore /* Normal or "mutable" LSMs */ 2283423c639SPaul Moore sep = kstrdup(list, GFP_KERNEL); 2293423c639SPaul Moore next = sep; 2303423c639SPaul Moore /* Walk the list, looking for matching LSMs. */ 2313423c639SPaul Moore while ((name = strsep(&next, ",")) != NULL) { 2323423c639SPaul Moore lsm_for_each_raw(lsm) { 2333423c639SPaul Moore if (!strcmp(lsm->id->name, name) && 2343423c639SPaul Moore lsm->order == LSM_ORDER_MUTABLE) 2353423c639SPaul Moore lsm_order_append(lsm, src); 2363423c639SPaul Moore } 2373423c639SPaul Moore } 2383423c639SPaul Moore kfree(sep); 2393423c639SPaul Moore 2403423c639SPaul Moore /* Legacy LSM if specified. */ 2413423c639SPaul Moore if (lsm_order_legacy) { 2423423c639SPaul Moore lsm_for_each_raw(lsm) { 2433423c639SPaul Moore if (!strcmp(lsm->id->name, lsm_order_legacy)) 2443423c639SPaul Moore lsm_order_append(lsm, src); 2453423c639SPaul Moore } 2463423c639SPaul Moore } 2473423c639SPaul Moore 2483423c639SPaul Moore /* LSM_ORDER_LAST */ 2493423c639SPaul Moore lsm_for_each_raw(lsm) { 2503423c639SPaul Moore if (lsm->order == LSM_ORDER_LAST) 2513423c639SPaul Moore lsm_order_append(lsm, "last"); 2523423c639SPaul Moore } 2533423c639SPaul Moore 2543423c639SPaul Moore /* Disable all LSMs not previously enabled. */ 2553423c639SPaul Moore lsm_for_each_raw(lsm) { 2563423c639SPaul Moore if (lsm_order_exists(lsm)) 2573423c639SPaul Moore continue; 2583423c639SPaul Moore lsm_enabled_set(lsm, false); 2593423c639SPaul Moore lsm_pr_dbg("skip disabled LSM %s:%s\n", src, lsm->id->name); 2603423c639SPaul Moore } 2613423c639SPaul Moore } 2623423c639SPaul Moore 2633423c639SPaul Moore /** 264291271e6SPaul Moore * lsm_blob_size_update - Update the LSM blob size and offset information 265291271e6SPaul Moore * @sz_req: the requested additional blob size 266291271e6SPaul Moore * @sz_cur: the existing blob size 267291271e6SPaul Moore */ 268291271e6SPaul Moore static void __init lsm_blob_size_update(unsigned int *sz_req, 269291271e6SPaul Moore unsigned int *sz_cur) 27067a4b6a8SPaul Moore { 271291271e6SPaul Moore unsigned int offset; 27267a4b6a8SPaul Moore 273291271e6SPaul Moore if (*sz_req == 0) 27467a4b6a8SPaul Moore return; 27567a4b6a8SPaul Moore 276291271e6SPaul Moore offset = ALIGN(*sz_cur, sizeof(void *)); 277291271e6SPaul Moore *sz_cur = offset + *sz_req; 278291271e6SPaul Moore *sz_req = offset; 27967a4b6a8SPaul Moore } 28067a4b6a8SPaul Moore 281e0257856SPaul Moore /** 282e0257856SPaul Moore * lsm_prepare - Prepare the LSM framework for a new LSM 283e0257856SPaul Moore * @lsm: LSM definition 28467a4b6a8SPaul Moore */ 285e0257856SPaul Moore static void __init lsm_prepare(struct lsm_info *lsm) 28667a4b6a8SPaul Moore { 28724a9c589SPaul Moore struct lsm_blob_sizes *blobs = lsm->blobs; 28867a4b6a8SPaul Moore 28924a9c589SPaul Moore if (!blobs) 290e0257856SPaul Moore return; 29167a4b6a8SPaul Moore 292e0257856SPaul Moore /* Register the LSM blob sizes. */ 293291271e6SPaul Moore blobs = lsm->blobs; 294291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_cred, &blob_sizes.lbs_cred); 295291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_file, &blob_sizes.lbs_file); 296291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_ib, &blob_sizes.lbs_ib); 297e0257856SPaul Moore /* inode blob gets an rcu_head in addition to LSM blobs. */ 298e0257856SPaul Moore if (blobs->lbs_inode && blob_sizes.lbs_inode == 0) 299e0257856SPaul Moore blob_sizes.lbs_inode = sizeof(struct rcu_head); 300291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_inode, &blob_sizes.lbs_inode); 301291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_ipc, &blob_sizes.lbs_ipc); 302291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_key, &blob_sizes.lbs_key); 303291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_msg_msg, &blob_sizes.lbs_msg_msg); 304291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_perf_event, 305291271e6SPaul Moore &blob_sizes.lbs_perf_event); 306291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_sock, &blob_sizes.lbs_sock); 307291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_superblock, 308291271e6SPaul Moore &blob_sizes.lbs_superblock); 309291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_task, &blob_sizes.lbs_task); 310291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_tun_dev, &blob_sizes.lbs_tun_dev); 311291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_xattr_count, 312e0257856SPaul Moore &blob_sizes.lbs_xattr_count); 313291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_bdev, &blob_sizes.lbs_bdev); 314291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_bpf_map, &blob_sizes.lbs_bpf_map); 315291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_bpf_prog, &blob_sizes.lbs_bpf_prog); 316291271e6SPaul Moore lsm_blob_size_update(&blobs->lbs_bpf_token, &blob_sizes.lbs_bpf_token); 31767a4b6a8SPaul Moore } 31867a4b6a8SPaul Moore 31927be5600SPaul Moore /** 32027be5600SPaul Moore * lsm_init_single - Initialize a given LSM 32127be5600SPaul Moore * @lsm: LSM definition 32227be5600SPaul Moore */ 32327be5600SPaul Moore static void __init lsm_init_single(struct lsm_info *lsm) 32467a4b6a8SPaul Moore { 32567a4b6a8SPaul Moore int ret; 32667a4b6a8SPaul Moore 32727be5600SPaul Moore if (!lsm_is_enabled(lsm)) 32827be5600SPaul Moore return; 32927be5600SPaul Moore 3305137e583SPaul Moore lsm_pr_dbg("initializing %s\n", lsm->id->name); 33167a4b6a8SPaul Moore ret = lsm->init(); 3329f9dc69eSPaul Moore WARN(ret, "%s failed to initialize: %d\n", lsm->id->name, ret); 33367a4b6a8SPaul Moore } 33467a4b6a8SPaul Moore 335752db065SPaul Moore /** 33645070533SPaul Moore * lsm_static_call_init - Initialize a LSM's static calls 33745070533SPaul Moore * @hl: LSM hook list 33845070533SPaul Moore */ 3395137e583SPaul Moore static int __init lsm_static_call_init(struct security_hook_list *hl) 34067a4b6a8SPaul Moore { 34145a41d13SPaul Moore struct lsm_static_call *scall = hl->scalls; 34245a41d13SPaul Moore int i; 34345a41d13SPaul Moore 34445a41d13SPaul Moore for (i = 0; i < MAX_LSM_COUNT; i++) { 34545a41d13SPaul Moore /* Update the first static call that is not used yet */ 34645a41d13SPaul Moore if (!scall->hl) { 34745a41d13SPaul Moore __static_call_update(scall->key, scall->trampoline, 34845a41d13SPaul Moore hl->hook.lsm_func_addr); 34945a41d13SPaul Moore scall->hl = hl; 35045a41d13SPaul Moore static_branch_enable(scall->active); 3515137e583SPaul Moore return 0; 35245a41d13SPaul Moore } 35345a41d13SPaul Moore scall++; 35445a41d13SPaul Moore } 3555137e583SPaul Moore 3565137e583SPaul Moore return -ENOSPC; 35745a41d13SPaul Moore } 35845a41d13SPaul Moore 35945a41d13SPaul Moore /** 36045070533SPaul Moore * security_add_hooks - Add a LSM's hooks to the LSM framework's hook lists 36145070533SPaul Moore * @hooks: LSM hooks to add 36245070533SPaul Moore * @count: number of hooks to add 36345070533SPaul Moore * @lsmid: identification information for the LSM 36445a41d13SPaul Moore * 36545070533SPaul Moore * Each LSM has to register its hooks with the LSM framework. 36645a41d13SPaul Moore */ 36745a41d13SPaul Moore void __init security_add_hooks(struct security_hook_list *hooks, int count, 36845a41d13SPaul Moore const struct lsm_id *lsmid) 36945a41d13SPaul Moore { 37045a41d13SPaul Moore int i; 37145a41d13SPaul Moore 37245a41d13SPaul Moore for (i = 0; i < count; i++) { 37345a41d13SPaul Moore hooks[i].lsmid = lsmid; 3745137e583SPaul Moore if (lsm_static_call_init(&hooks[i])) 3755137e583SPaul Moore panic("exhausted LSM callback slots with LSM %s\n", 3765137e583SPaul Moore lsmid->name); 37745a41d13SPaul Moore } 37845a41d13SPaul Moore } 37945a41d13SPaul Moore 38045070533SPaul Moore /** 38145070533SPaul Moore * early_security_init - Initialize the early LSMs 38245070533SPaul Moore */ 38345a41d13SPaul Moore int __init early_security_init(void) 38445a41d13SPaul Moore { 38545a41d13SPaul Moore struct lsm_info *lsm; 38645a41d13SPaul Moore 387ac3c47ceSPaul Moore /* NOTE: lsm_pr_dbg() doesn't work here as lsm_debug is not yet set */ 388ac3c47ceSPaul Moore 38945a41d13SPaul Moore lsm_early_for_each_raw(lsm) { 39045a41d13SPaul Moore lsm_enabled_set(lsm, true); 39145a41d13SPaul Moore lsm_order_append(lsm, "early"); 39245a41d13SPaul Moore lsm_prepare(lsm); 39345a41d13SPaul Moore lsm_init_single(lsm); 39445a41d13SPaul Moore lsm_count_early++; 39545a41d13SPaul Moore } 39645a41d13SPaul Moore 39745a41d13SPaul Moore return 0; 39845a41d13SPaul Moore } 39945a41d13SPaul Moore 40045a41d13SPaul Moore /** 40145a41d13SPaul Moore * security_init - Initializes the LSM framework 40245a41d13SPaul Moore * 40345a41d13SPaul Moore * This should be called early in the kernel initialization sequence. 40445a41d13SPaul Moore */ 40545a41d13SPaul Moore int __init security_init(void) 40645a41d13SPaul Moore { 40745a41d13SPaul Moore unsigned int cnt; 40867a4b6a8SPaul Moore struct lsm_info **lsm; 40945a41d13SPaul Moore 4105137e583SPaul Moore if (lsm_debug) { 411ac3c47ceSPaul Moore struct lsm_info *i; 412ac3c47ceSPaul Moore 413ac3c47ceSPaul Moore cnt = 0; 414ac3c47ceSPaul Moore lsm_pr("available LSMs: "); 415ac3c47ceSPaul Moore lsm_early_for_each_raw(i) 416ac3c47ceSPaul Moore lsm_pr_cont("%s%s(E)", (cnt++ ? "," : ""), i->id->name); 417ac3c47ceSPaul Moore lsm_for_each_raw(i) 418ac3c47ceSPaul Moore lsm_pr_cont("%s%s", (cnt++ ? "," : ""), i->id->name); 419ac3c47ceSPaul Moore lsm_pr_cont("\n"); 420ac3c47ceSPaul Moore 421ac3c47ceSPaul Moore lsm_pr("built-in LSM config: %s\n", lsm_order_builtin); 422ac3c47ceSPaul Moore 4235137e583SPaul Moore lsm_pr("legacy LSM parameter: %s\n", lsm_order_legacy); 4245137e583SPaul Moore lsm_pr("boot LSM parameter: %s\n", lsm_order_cmdline); 425ac3c47ceSPaul Moore 426ac3c47ceSPaul Moore /* see the note about lsm_pr_dbg() in early_security_init() */ 427ac3c47ceSPaul Moore lsm_early_for_each_raw(i) 428ac3c47ceSPaul Moore lsm_pr("enabled LSM early:%s\n", i->id->name); 4295137e583SPaul Moore } 43067a4b6a8SPaul Moore 431592b104fSPaul Moore if (lsm_order_cmdline) { 4325137e583SPaul Moore if (lsm_order_legacy) 433592b104fSPaul Moore lsm_order_legacy = NULL; 434752db065SPaul Moore lsm_order_parse(lsm_order_cmdline, "cmdline"); 43567a4b6a8SPaul Moore } else 436752db065SPaul Moore lsm_order_parse(lsm_order_builtin, "builtin"); 43767a4b6a8SPaul Moore 43845a41d13SPaul Moore lsm_order_for_each(lsm) 439e0257856SPaul Moore lsm_prepare(*lsm); 44067a4b6a8SPaul Moore 4415137e583SPaul Moore if (lsm_debug) { 4425137e583SPaul Moore lsm_pr("blob(cred) size %d\n", blob_sizes.lbs_cred); 4435137e583SPaul Moore lsm_pr("blob(file) size %d\n", blob_sizes.lbs_file); 4445137e583SPaul Moore lsm_pr("blob(ib) size %d\n", blob_sizes.lbs_ib); 4455137e583SPaul Moore lsm_pr("blob(inode) size %d\n", blob_sizes.lbs_inode); 4465137e583SPaul Moore lsm_pr("blob(ipc) size %d\n", blob_sizes.lbs_ipc); 4475137e583SPaul Moore lsm_pr("blob(key) size %d\n", blob_sizes.lbs_key); 4485137e583SPaul Moore lsm_pr("blob(msg_msg)_size %d\n", blob_sizes.lbs_msg_msg); 4495137e583SPaul Moore lsm_pr("blob(sock) size %d\n", blob_sizes.lbs_sock); 4505137e583SPaul Moore lsm_pr("blob(superblock) size %d\n", blob_sizes.lbs_superblock); 4515137e583SPaul Moore lsm_pr("blob(perf_event) size %d\n", blob_sizes.lbs_perf_event); 4525137e583SPaul Moore lsm_pr("blob(task) size %d\n", blob_sizes.lbs_task); 4535137e583SPaul Moore lsm_pr("blob(tun_dev) size %d\n", blob_sizes.lbs_tun_dev); 4545137e583SPaul Moore lsm_pr("blob(xattr) count %d\n", blob_sizes.lbs_xattr_count); 4555137e583SPaul Moore lsm_pr("blob(bdev) size %d\n", blob_sizes.lbs_bdev); 4565137e583SPaul Moore lsm_pr("blob(bpf_map) size %d\n", blob_sizes.lbs_bpf_map); 4575137e583SPaul Moore lsm_pr("blob(bpf_prog) size %d\n", blob_sizes.lbs_bpf_prog); 4585137e583SPaul Moore lsm_pr("blob(bpf_token) size %d\n", blob_sizes.lbs_bpf_token); 459cb1513dbSPaul Moore } 46067a4b6a8SPaul Moore 46167a4b6a8SPaul Moore if (blob_sizes.lbs_file) 46267a4b6a8SPaul Moore lsm_file_cache = kmem_cache_create("lsm_file_cache", 46367a4b6a8SPaul Moore blob_sizes.lbs_file, 0, 46467a4b6a8SPaul Moore SLAB_PANIC, NULL); 46567a4b6a8SPaul Moore if (blob_sizes.lbs_inode) 46667a4b6a8SPaul Moore lsm_inode_cache = kmem_cache_create("lsm_inode_cache", 46767a4b6a8SPaul Moore blob_sizes.lbs_inode, 0, 46867a4b6a8SPaul Moore SLAB_PANIC, NULL); 46967a4b6a8SPaul Moore 47092ed3500SPaul Moore if (lsm_cred_alloc((struct cred __rcu *)current->cred, GFP_KERNEL)) 4715137e583SPaul Moore panic("early LSM cred alloc failed\n"); 47292ed3500SPaul Moore if (lsm_task_alloc(current)) 4735137e583SPaul Moore panic("early LSM task alloc failed\n"); 47492ed3500SPaul Moore 47545a41d13SPaul Moore cnt = 0; 47637f788f6SPaul Moore lsm_order_for_each(lsm) { 47745a41d13SPaul Moore /* skip the "early" LSMs as they have already been setup */ 47845a41d13SPaul Moore if (cnt++ < lsm_count_early) 47945a41d13SPaul Moore continue; 48027be5600SPaul Moore lsm_init_single(*lsm); 48167a4b6a8SPaul Moore } 48267a4b6a8SPaul Moore 48367a4b6a8SPaul Moore return 0; 48467a4b6a8SPaul Moore } 485*cdc02881SPaul Moore 486*cdc02881SPaul Moore /** 487*cdc02881SPaul Moore * security_initcall_pure - Run the LSM pure initcalls 488*cdc02881SPaul Moore */ 489*cdc02881SPaul Moore static int __init security_initcall_pure(void) 490*cdc02881SPaul Moore { 491*cdc02881SPaul Moore return lsm_initcall(pure); 492*cdc02881SPaul Moore } 493*cdc02881SPaul Moore pure_initcall(security_initcall_pure); 494*cdc02881SPaul Moore 495*cdc02881SPaul Moore /** 496*cdc02881SPaul Moore * security_initcall_early - Run the LSM early initcalls 497*cdc02881SPaul Moore */ 498*cdc02881SPaul Moore static int __init security_initcall_early(void) 499*cdc02881SPaul Moore { 500*cdc02881SPaul Moore return lsm_initcall(early); 501*cdc02881SPaul Moore } 502*cdc02881SPaul Moore early_initcall(security_initcall_early); 503*cdc02881SPaul Moore 504*cdc02881SPaul Moore /** 505*cdc02881SPaul Moore * security_initcall_core - Run the LSM core initcalls 506*cdc02881SPaul Moore */ 507*cdc02881SPaul Moore static int __init security_initcall_core(void) 508*cdc02881SPaul Moore { 509*cdc02881SPaul Moore return lsm_initcall(core); 510*cdc02881SPaul Moore } 511*cdc02881SPaul Moore core_initcall(security_initcall_core); 512*cdc02881SPaul Moore 513*cdc02881SPaul Moore /** 514*cdc02881SPaul Moore * security_initcall_subsys - Run the LSM subsys initcalls 515*cdc02881SPaul Moore */ 516*cdc02881SPaul Moore static int __init security_initcall_subsys(void) 517*cdc02881SPaul Moore { 518*cdc02881SPaul Moore return lsm_initcall(subsys); 519*cdc02881SPaul Moore } 520*cdc02881SPaul Moore subsys_initcall(security_initcall_subsys); 521*cdc02881SPaul Moore 522*cdc02881SPaul Moore /** 523*cdc02881SPaul Moore * security_initcall_fs - Run the LSM fs initcalls 524*cdc02881SPaul Moore */ 525*cdc02881SPaul Moore static int __init security_initcall_fs(void) 526*cdc02881SPaul Moore { 527*cdc02881SPaul Moore return lsm_initcall(fs); 528*cdc02881SPaul Moore } 529*cdc02881SPaul Moore fs_initcall(security_initcall_fs); 530*cdc02881SPaul Moore 531*cdc02881SPaul Moore /** 532*cdc02881SPaul Moore * security_initcall_device - Run the LSM device initcalls 533*cdc02881SPaul Moore */ 534*cdc02881SPaul Moore static int __init security_initcall_device(void) 535*cdc02881SPaul Moore { 536*cdc02881SPaul Moore return lsm_initcall(device); 537*cdc02881SPaul Moore } 538*cdc02881SPaul Moore device_initcall(security_initcall_device); 539*cdc02881SPaul Moore 540*cdc02881SPaul Moore /** 541*cdc02881SPaul Moore * security_initcall_late - Run the LSM late initcalls 542*cdc02881SPaul Moore */ 543*cdc02881SPaul Moore static int __init security_initcall_late(void) 544*cdc02881SPaul Moore { 545*cdc02881SPaul Moore int rc; 546*cdc02881SPaul Moore 547*cdc02881SPaul Moore rc = lsm_initcall(late); 548*cdc02881SPaul Moore lsm_pr_dbg("all enabled LSMs fully activated\n"); 549*cdc02881SPaul Moore 550*cdc02881SPaul Moore return rc; 551*cdc02881SPaul Moore } 552*cdc02881SPaul Moore late_initcall(security_initcall_late); 553