1*67a4b6a8SPaul Moore // SPDX-License-Identifier: GPL-2.0-or-later 2*67a4b6a8SPaul Moore /* 3*67a4b6a8SPaul Moore * LSM initialization functions 4*67a4b6a8SPaul Moore */ 5*67a4b6a8SPaul Moore 6*67a4b6a8SPaul Moore #define pr_fmt(fmt) "LSM: " fmt 7*67a4b6a8SPaul Moore 8*67a4b6a8SPaul Moore #include <linux/init.h> 9*67a4b6a8SPaul Moore #include <linux/lsm_hooks.h> 10*67a4b6a8SPaul Moore 11*67a4b6a8SPaul Moore #include "lsm.h" 12*67a4b6a8SPaul Moore 13*67a4b6a8SPaul Moore char *lsm_names; 14*67a4b6a8SPaul Moore 15*67a4b6a8SPaul Moore /* Pointers to LSM sections defined in include/asm-generic/vmlinux.lds.h */ 16*67a4b6a8SPaul Moore extern struct lsm_info __start_lsm_info[], __end_lsm_info[]; 17*67a4b6a8SPaul Moore extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[]; 18*67a4b6a8SPaul Moore 19*67a4b6a8SPaul Moore /* Boot-time LSM user choice */ 20*67a4b6a8SPaul Moore static __initconst const char *const builtin_lsm_order = CONFIG_LSM; 21*67a4b6a8SPaul Moore static __initdata const char *chosen_lsm_order; 22*67a4b6a8SPaul Moore static __initdata const char *chosen_major_lsm; 23*67a4b6a8SPaul Moore 24*67a4b6a8SPaul Moore /* Ordered list of LSMs to initialize. */ 25*67a4b6a8SPaul Moore static __initdata struct lsm_info *ordered_lsms[MAX_LSM_COUNT + 1]; 26*67a4b6a8SPaul Moore static __initdata struct lsm_info *exclusive; 27*67a4b6a8SPaul Moore 28*67a4b6a8SPaul Moore static __initdata bool debug; 29*67a4b6a8SPaul Moore #define init_debug(...) \ 30*67a4b6a8SPaul Moore do { \ 31*67a4b6a8SPaul Moore if (debug) \ 32*67a4b6a8SPaul Moore pr_info(__VA_ARGS__); \ 33*67a4b6a8SPaul Moore } while (0) 34*67a4b6a8SPaul Moore 35*67a4b6a8SPaul Moore static int lsm_append(const char *new, char **result); 36*67a4b6a8SPaul Moore 37*67a4b6a8SPaul Moore /* Save user chosen LSM */ 38*67a4b6a8SPaul Moore static int __init choose_major_lsm(char *str) 39*67a4b6a8SPaul Moore { 40*67a4b6a8SPaul Moore chosen_major_lsm = str; 41*67a4b6a8SPaul Moore return 1; 42*67a4b6a8SPaul Moore } 43*67a4b6a8SPaul Moore __setup("security=", choose_major_lsm); 44*67a4b6a8SPaul Moore 45*67a4b6a8SPaul Moore /* Explicitly choose LSM initialization order. */ 46*67a4b6a8SPaul Moore static int __init choose_lsm_order(char *str) 47*67a4b6a8SPaul Moore { 48*67a4b6a8SPaul Moore chosen_lsm_order = str; 49*67a4b6a8SPaul Moore return 1; 50*67a4b6a8SPaul Moore } 51*67a4b6a8SPaul Moore __setup("lsm=", choose_lsm_order); 52*67a4b6a8SPaul Moore 53*67a4b6a8SPaul Moore /* Enable LSM order debugging. */ 54*67a4b6a8SPaul Moore static int __init enable_debug(char *str) 55*67a4b6a8SPaul Moore { 56*67a4b6a8SPaul Moore debug = true; 57*67a4b6a8SPaul Moore return 1; 58*67a4b6a8SPaul Moore } 59*67a4b6a8SPaul Moore __setup("lsm.debug", enable_debug); 60*67a4b6a8SPaul Moore 61*67a4b6a8SPaul Moore /* Mark an LSM's enabled flag. */ 62*67a4b6a8SPaul Moore static int lsm_enabled_true __initdata = 1; 63*67a4b6a8SPaul Moore static int lsm_enabled_false __initdata = 0; 64*67a4b6a8SPaul Moore static void __init set_enabled(struct lsm_info *lsm, bool enabled) 65*67a4b6a8SPaul Moore { 66*67a4b6a8SPaul Moore /* 67*67a4b6a8SPaul Moore * When an LSM hasn't configured an enable variable, we can use 68*67a4b6a8SPaul Moore * a hard-coded location for storing the default enabled state. 69*67a4b6a8SPaul Moore */ 70*67a4b6a8SPaul Moore if (!lsm->enabled) { 71*67a4b6a8SPaul Moore if (enabled) 72*67a4b6a8SPaul Moore lsm->enabled = &lsm_enabled_true; 73*67a4b6a8SPaul Moore else 74*67a4b6a8SPaul Moore lsm->enabled = &lsm_enabled_false; 75*67a4b6a8SPaul Moore } else if (lsm->enabled == &lsm_enabled_true) { 76*67a4b6a8SPaul Moore if (!enabled) 77*67a4b6a8SPaul Moore lsm->enabled = &lsm_enabled_false; 78*67a4b6a8SPaul Moore } else if (lsm->enabled == &lsm_enabled_false) { 79*67a4b6a8SPaul Moore if (enabled) 80*67a4b6a8SPaul Moore lsm->enabled = &lsm_enabled_true; 81*67a4b6a8SPaul Moore } else { 82*67a4b6a8SPaul Moore *lsm->enabled = enabled; 83*67a4b6a8SPaul Moore } 84*67a4b6a8SPaul Moore } 85*67a4b6a8SPaul Moore 86*67a4b6a8SPaul Moore static inline bool is_enabled(struct lsm_info *lsm) 87*67a4b6a8SPaul Moore { 88*67a4b6a8SPaul Moore if (!lsm->enabled) 89*67a4b6a8SPaul Moore return false; 90*67a4b6a8SPaul Moore 91*67a4b6a8SPaul Moore return *lsm->enabled; 92*67a4b6a8SPaul Moore } 93*67a4b6a8SPaul Moore 94*67a4b6a8SPaul Moore /* Is an LSM already listed in the ordered LSMs list? */ 95*67a4b6a8SPaul Moore static bool __init exists_ordered_lsm(struct lsm_info *lsm) 96*67a4b6a8SPaul Moore { 97*67a4b6a8SPaul Moore struct lsm_info **check; 98*67a4b6a8SPaul Moore 99*67a4b6a8SPaul Moore for (check = ordered_lsms; *check; check++) 100*67a4b6a8SPaul Moore if (*check == lsm) 101*67a4b6a8SPaul Moore return true; 102*67a4b6a8SPaul Moore 103*67a4b6a8SPaul Moore return false; 104*67a4b6a8SPaul Moore } 105*67a4b6a8SPaul Moore 106*67a4b6a8SPaul Moore /* Append an LSM to the list of ordered LSMs to initialize. */ 107*67a4b6a8SPaul Moore static int last_lsm __initdata; 108*67a4b6a8SPaul Moore static void __init append_ordered_lsm(struct lsm_info *lsm, const char *from) 109*67a4b6a8SPaul Moore { 110*67a4b6a8SPaul Moore /* Ignore duplicate selections. */ 111*67a4b6a8SPaul Moore if (exists_ordered_lsm(lsm)) 112*67a4b6a8SPaul Moore return; 113*67a4b6a8SPaul Moore 114*67a4b6a8SPaul Moore if (WARN(last_lsm == MAX_LSM_COUNT, "%s: out of LSM static calls!?\n", from)) 115*67a4b6a8SPaul Moore return; 116*67a4b6a8SPaul Moore 117*67a4b6a8SPaul Moore /* Enable this LSM, if it is not already set. */ 118*67a4b6a8SPaul Moore if (!lsm->enabled) 119*67a4b6a8SPaul Moore lsm->enabled = &lsm_enabled_true; 120*67a4b6a8SPaul Moore ordered_lsms[last_lsm++] = lsm; 121*67a4b6a8SPaul Moore 122*67a4b6a8SPaul Moore init_debug("%s ordered: %s (%s)\n", from, lsm->name, 123*67a4b6a8SPaul Moore is_enabled(lsm) ? "enabled" : "disabled"); 124*67a4b6a8SPaul Moore } 125*67a4b6a8SPaul Moore 126*67a4b6a8SPaul Moore /* Is an LSM allowed to be initialized? */ 127*67a4b6a8SPaul Moore static bool __init lsm_allowed(struct lsm_info *lsm) 128*67a4b6a8SPaul Moore { 129*67a4b6a8SPaul Moore /* Skip if the LSM is disabled. */ 130*67a4b6a8SPaul Moore if (!is_enabled(lsm)) 131*67a4b6a8SPaul Moore return false; 132*67a4b6a8SPaul Moore 133*67a4b6a8SPaul Moore /* Not allowed if another exclusive LSM already initialized. */ 134*67a4b6a8SPaul Moore if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && exclusive) { 135*67a4b6a8SPaul Moore init_debug("exclusive disabled: %s\n", lsm->name); 136*67a4b6a8SPaul Moore return false; 137*67a4b6a8SPaul Moore } 138*67a4b6a8SPaul Moore 139*67a4b6a8SPaul Moore return true; 140*67a4b6a8SPaul Moore } 141*67a4b6a8SPaul Moore 142*67a4b6a8SPaul Moore static void __init lsm_set_blob_size(int *need, int *lbs) 143*67a4b6a8SPaul Moore { 144*67a4b6a8SPaul Moore int offset; 145*67a4b6a8SPaul Moore 146*67a4b6a8SPaul Moore if (*need <= 0) 147*67a4b6a8SPaul Moore return; 148*67a4b6a8SPaul Moore 149*67a4b6a8SPaul Moore offset = ALIGN(*lbs, sizeof(void *)); 150*67a4b6a8SPaul Moore *lbs = offset + *need; 151*67a4b6a8SPaul Moore *need = offset; 152*67a4b6a8SPaul Moore } 153*67a4b6a8SPaul Moore 154*67a4b6a8SPaul Moore static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed) 155*67a4b6a8SPaul Moore { 156*67a4b6a8SPaul Moore if (!needed) 157*67a4b6a8SPaul Moore return; 158*67a4b6a8SPaul Moore 159*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_cred, &blob_sizes.lbs_cred); 160*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_file, &blob_sizes.lbs_file); 161*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_ib, &blob_sizes.lbs_ib); 162*67a4b6a8SPaul Moore /* 163*67a4b6a8SPaul Moore * The inode blob gets an rcu_head in addition to 164*67a4b6a8SPaul Moore * what the modules might need. 165*67a4b6a8SPaul Moore */ 166*67a4b6a8SPaul Moore if (needed->lbs_inode && blob_sizes.lbs_inode == 0) 167*67a4b6a8SPaul Moore blob_sizes.lbs_inode = sizeof(struct rcu_head); 168*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_inode, &blob_sizes.lbs_inode); 169*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc); 170*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_key, &blob_sizes.lbs_key); 171*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg); 172*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_perf_event, &blob_sizes.lbs_perf_event); 173*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_sock, &blob_sizes.lbs_sock); 174*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock); 175*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task); 176*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_tun_dev, &blob_sizes.lbs_tun_dev); 177*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_xattr_count, 178*67a4b6a8SPaul Moore &blob_sizes.lbs_xattr_count); 179*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_bdev, &blob_sizes.lbs_bdev); 180*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_bpf_map, &blob_sizes.lbs_bpf_map); 181*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_bpf_prog, &blob_sizes.lbs_bpf_prog); 182*67a4b6a8SPaul Moore lsm_set_blob_size(&needed->lbs_bpf_token, &blob_sizes.lbs_bpf_token); 183*67a4b6a8SPaul Moore } 184*67a4b6a8SPaul Moore 185*67a4b6a8SPaul Moore /* Prepare LSM for initialization. */ 186*67a4b6a8SPaul Moore static void __init prepare_lsm(struct lsm_info *lsm) 187*67a4b6a8SPaul Moore { 188*67a4b6a8SPaul Moore int enabled = lsm_allowed(lsm); 189*67a4b6a8SPaul Moore 190*67a4b6a8SPaul Moore /* Record enablement (to handle any following exclusive LSMs). */ 191*67a4b6a8SPaul Moore set_enabled(lsm, enabled); 192*67a4b6a8SPaul Moore 193*67a4b6a8SPaul Moore /* If enabled, do pre-initialization work. */ 194*67a4b6a8SPaul Moore if (enabled) { 195*67a4b6a8SPaul Moore if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !exclusive) { 196*67a4b6a8SPaul Moore exclusive = lsm; 197*67a4b6a8SPaul Moore init_debug("exclusive chosen: %s\n", lsm->name); 198*67a4b6a8SPaul Moore } 199*67a4b6a8SPaul Moore 200*67a4b6a8SPaul Moore lsm_set_blob_sizes(lsm->blobs); 201*67a4b6a8SPaul Moore } 202*67a4b6a8SPaul Moore } 203*67a4b6a8SPaul Moore 204*67a4b6a8SPaul Moore /* Initialize a given LSM, if it is enabled. */ 205*67a4b6a8SPaul Moore static void __init initialize_lsm(struct lsm_info *lsm) 206*67a4b6a8SPaul Moore { 207*67a4b6a8SPaul Moore if (is_enabled(lsm)) { 208*67a4b6a8SPaul Moore int ret; 209*67a4b6a8SPaul Moore 210*67a4b6a8SPaul Moore init_debug("initializing %s\n", lsm->name); 211*67a4b6a8SPaul Moore ret = lsm->init(); 212*67a4b6a8SPaul Moore WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret); 213*67a4b6a8SPaul Moore } 214*67a4b6a8SPaul Moore } 215*67a4b6a8SPaul Moore 216*67a4b6a8SPaul Moore /* 217*67a4b6a8SPaul Moore * Current index to use while initializing the lsm id list. 218*67a4b6a8SPaul Moore */ 219*67a4b6a8SPaul Moore u32 lsm_active_cnt __ro_after_init; 220*67a4b6a8SPaul Moore const struct lsm_id *lsm_idlist[MAX_LSM_COUNT]; 221*67a4b6a8SPaul Moore 222*67a4b6a8SPaul Moore /* Populate ordered LSMs list from comma-separated LSM name list. */ 223*67a4b6a8SPaul Moore static void __init ordered_lsm_parse(const char *order, const char *origin) 224*67a4b6a8SPaul Moore { 225*67a4b6a8SPaul Moore struct lsm_info *lsm; 226*67a4b6a8SPaul Moore char *sep, *name, *next; 227*67a4b6a8SPaul Moore 228*67a4b6a8SPaul Moore /* LSM_ORDER_FIRST is always first. */ 229*67a4b6a8SPaul Moore for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { 230*67a4b6a8SPaul Moore if (lsm->order == LSM_ORDER_FIRST) 231*67a4b6a8SPaul Moore append_ordered_lsm(lsm, " first"); 232*67a4b6a8SPaul Moore } 233*67a4b6a8SPaul Moore 234*67a4b6a8SPaul Moore /* Process "security=", if given. */ 235*67a4b6a8SPaul Moore if (chosen_major_lsm) { 236*67a4b6a8SPaul Moore struct lsm_info *major; 237*67a4b6a8SPaul Moore 238*67a4b6a8SPaul Moore /* 239*67a4b6a8SPaul Moore * To match the original "security=" behavior, this 240*67a4b6a8SPaul Moore * explicitly does NOT fallback to another Legacy Major 241*67a4b6a8SPaul Moore * if the selected one was separately disabled: disable 242*67a4b6a8SPaul Moore * all non-matching Legacy Major LSMs. 243*67a4b6a8SPaul Moore */ 244*67a4b6a8SPaul Moore for (major = __start_lsm_info; major < __end_lsm_info; 245*67a4b6a8SPaul Moore major++) { 246*67a4b6a8SPaul Moore if ((major->flags & LSM_FLAG_LEGACY_MAJOR) && 247*67a4b6a8SPaul Moore strcmp(major->name, chosen_major_lsm) != 0) { 248*67a4b6a8SPaul Moore set_enabled(major, false); 249*67a4b6a8SPaul Moore init_debug("security=%s disabled: %s (only one legacy major LSM)\n", 250*67a4b6a8SPaul Moore chosen_major_lsm, major->name); 251*67a4b6a8SPaul Moore } 252*67a4b6a8SPaul Moore } 253*67a4b6a8SPaul Moore } 254*67a4b6a8SPaul Moore 255*67a4b6a8SPaul Moore sep = kstrdup(order, GFP_KERNEL); 256*67a4b6a8SPaul Moore next = sep; 257*67a4b6a8SPaul Moore /* Walk the list, looking for matching LSMs. */ 258*67a4b6a8SPaul Moore while ((name = strsep(&next, ",")) != NULL) { 259*67a4b6a8SPaul Moore bool found = false; 260*67a4b6a8SPaul Moore 261*67a4b6a8SPaul Moore for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { 262*67a4b6a8SPaul Moore if (strcmp(lsm->name, name) == 0) { 263*67a4b6a8SPaul Moore if (lsm->order == LSM_ORDER_MUTABLE) 264*67a4b6a8SPaul Moore append_ordered_lsm(lsm, origin); 265*67a4b6a8SPaul Moore found = true; 266*67a4b6a8SPaul Moore } 267*67a4b6a8SPaul Moore } 268*67a4b6a8SPaul Moore 269*67a4b6a8SPaul Moore if (!found) 270*67a4b6a8SPaul Moore init_debug("%s ignored: %s (not built into kernel)\n", 271*67a4b6a8SPaul Moore origin, name); 272*67a4b6a8SPaul Moore } 273*67a4b6a8SPaul Moore 274*67a4b6a8SPaul Moore /* Process "security=", if given. */ 275*67a4b6a8SPaul Moore if (chosen_major_lsm) { 276*67a4b6a8SPaul Moore for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { 277*67a4b6a8SPaul Moore if (exists_ordered_lsm(lsm)) 278*67a4b6a8SPaul Moore continue; 279*67a4b6a8SPaul Moore if (strcmp(lsm->name, chosen_major_lsm) == 0) 280*67a4b6a8SPaul Moore append_ordered_lsm(lsm, "security="); 281*67a4b6a8SPaul Moore } 282*67a4b6a8SPaul Moore } 283*67a4b6a8SPaul Moore 284*67a4b6a8SPaul Moore /* LSM_ORDER_LAST is always last. */ 285*67a4b6a8SPaul Moore for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { 286*67a4b6a8SPaul Moore if (lsm->order == LSM_ORDER_LAST) 287*67a4b6a8SPaul Moore append_ordered_lsm(lsm, " last"); 288*67a4b6a8SPaul Moore } 289*67a4b6a8SPaul Moore 290*67a4b6a8SPaul Moore /* Disable all LSMs not in the ordered list. */ 291*67a4b6a8SPaul Moore for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { 292*67a4b6a8SPaul Moore if (exists_ordered_lsm(lsm)) 293*67a4b6a8SPaul Moore continue; 294*67a4b6a8SPaul Moore set_enabled(lsm, false); 295*67a4b6a8SPaul Moore init_debug("%s skipped: %s (not in requested order)\n", 296*67a4b6a8SPaul Moore origin, lsm->name); 297*67a4b6a8SPaul Moore } 298*67a4b6a8SPaul Moore 299*67a4b6a8SPaul Moore kfree(sep); 300*67a4b6a8SPaul Moore } 301*67a4b6a8SPaul Moore 302*67a4b6a8SPaul Moore static void __init report_lsm_order(void) 303*67a4b6a8SPaul Moore { 304*67a4b6a8SPaul Moore struct lsm_info **lsm, *early; 305*67a4b6a8SPaul Moore int first = 0; 306*67a4b6a8SPaul Moore 307*67a4b6a8SPaul Moore pr_info("initializing lsm="); 308*67a4b6a8SPaul Moore 309*67a4b6a8SPaul Moore /* Report each enabled LSM name, comma separated. */ 310*67a4b6a8SPaul Moore for (early = __start_early_lsm_info; 311*67a4b6a8SPaul Moore early < __end_early_lsm_info; early++) 312*67a4b6a8SPaul Moore if (is_enabled(early)) 313*67a4b6a8SPaul Moore pr_cont("%s%s", first++ == 0 ? "" : ",", early->name); 314*67a4b6a8SPaul Moore for (lsm = ordered_lsms; *lsm; lsm++) 315*67a4b6a8SPaul Moore if (is_enabled(*lsm)) 316*67a4b6a8SPaul Moore pr_cont("%s%s", first++ == 0 ? "" : ",", (*lsm)->name); 317*67a4b6a8SPaul Moore 318*67a4b6a8SPaul Moore pr_cont("\n"); 319*67a4b6a8SPaul Moore } 320*67a4b6a8SPaul Moore 321*67a4b6a8SPaul Moore /** 322*67a4b6a8SPaul Moore * lsm_early_cred - during initialization allocate a composite cred blob 323*67a4b6a8SPaul Moore * @cred: the cred that needs a blob 324*67a4b6a8SPaul Moore * 325*67a4b6a8SPaul Moore * Allocate the cred blob for all the modules 326*67a4b6a8SPaul Moore */ 327*67a4b6a8SPaul Moore static void __init lsm_early_cred(struct cred *cred) 328*67a4b6a8SPaul Moore { 329*67a4b6a8SPaul Moore int rc = lsm_cred_alloc(cred, GFP_KERNEL); 330*67a4b6a8SPaul Moore 331*67a4b6a8SPaul Moore if (rc) 332*67a4b6a8SPaul Moore panic("%s: Early cred alloc failed.\n", __func__); 333*67a4b6a8SPaul Moore } 334*67a4b6a8SPaul Moore 335*67a4b6a8SPaul Moore /** 336*67a4b6a8SPaul Moore * lsm_early_task - during initialization allocate a composite task blob 337*67a4b6a8SPaul Moore * @task: the task that needs a blob 338*67a4b6a8SPaul Moore * 339*67a4b6a8SPaul Moore * Allocate the task blob for all the modules 340*67a4b6a8SPaul Moore */ 341*67a4b6a8SPaul Moore static void __init lsm_early_task(struct task_struct *task) 342*67a4b6a8SPaul Moore { 343*67a4b6a8SPaul Moore int rc = lsm_task_alloc(task); 344*67a4b6a8SPaul Moore 345*67a4b6a8SPaul Moore if (rc) 346*67a4b6a8SPaul Moore panic("%s: Early task alloc failed.\n", __func__); 347*67a4b6a8SPaul Moore } 348*67a4b6a8SPaul Moore 349*67a4b6a8SPaul Moore static void __init ordered_lsm_init(void) 350*67a4b6a8SPaul Moore { 351*67a4b6a8SPaul Moore struct lsm_info **lsm; 352*67a4b6a8SPaul Moore 353*67a4b6a8SPaul Moore if (chosen_lsm_order) { 354*67a4b6a8SPaul Moore if (chosen_major_lsm) { 355*67a4b6a8SPaul Moore pr_warn("security=%s is ignored because it is superseded by lsm=%s\n", 356*67a4b6a8SPaul Moore chosen_major_lsm, chosen_lsm_order); 357*67a4b6a8SPaul Moore chosen_major_lsm = NULL; 358*67a4b6a8SPaul Moore } 359*67a4b6a8SPaul Moore ordered_lsm_parse(chosen_lsm_order, "cmdline"); 360*67a4b6a8SPaul Moore } else 361*67a4b6a8SPaul Moore ordered_lsm_parse(builtin_lsm_order, "builtin"); 362*67a4b6a8SPaul Moore 363*67a4b6a8SPaul Moore for (lsm = ordered_lsms; *lsm; lsm++) 364*67a4b6a8SPaul Moore prepare_lsm(*lsm); 365*67a4b6a8SPaul Moore 366*67a4b6a8SPaul Moore report_lsm_order(); 367*67a4b6a8SPaul Moore 368*67a4b6a8SPaul Moore init_debug("cred blob size = %d\n", blob_sizes.lbs_cred); 369*67a4b6a8SPaul Moore init_debug("file blob size = %d\n", blob_sizes.lbs_file); 370*67a4b6a8SPaul Moore init_debug("ib blob size = %d\n", blob_sizes.lbs_ib); 371*67a4b6a8SPaul Moore init_debug("inode blob size = %d\n", blob_sizes.lbs_inode); 372*67a4b6a8SPaul Moore init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc); 373*67a4b6a8SPaul Moore #ifdef CONFIG_KEYS 374*67a4b6a8SPaul Moore init_debug("key blob size = %d\n", blob_sizes.lbs_key); 375*67a4b6a8SPaul Moore #endif /* CONFIG_KEYS */ 376*67a4b6a8SPaul Moore init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg); 377*67a4b6a8SPaul Moore init_debug("sock blob size = %d\n", blob_sizes.lbs_sock); 378*67a4b6a8SPaul Moore init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock); 379*67a4b6a8SPaul Moore init_debug("perf event blob size = %d\n", blob_sizes.lbs_perf_event); 380*67a4b6a8SPaul Moore init_debug("task blob size = %d\n", blob_sizes.lbs_task); 381*67a4b6a8SPaul Moore init_debug("tun device blob size = %d\n", blob_sizes.lbs_tun_dev); 382*67a4b6a8SPaul Moore init_debug("xattr slots = %d\n", blob_sizes.lbs_xattr_count); 383*67a4b6a8SPaul Moore init_debug("bdev blob size = %d\n", blob_sizes.lbs_bdev); 384*67a4b6a8SPaul Moore init_debug("bpf map blob size = %d\n", blob_sizes.lbs_bpf_map); 385*67a4b6a8SPaul Moore init_debug("bpf prog blob size = %d\n", blob_sizes.lbs_bpf_prog); 386*67a4b6a8SPaul Moore init_debug("bpf token blob size = %d\n", blob_sizes.lbs_bpf_token); 387*67a4b6a8SPaul Moore 388*67a4b6a8SPaul Moore /* 389*67a4b6a8SPaul Moore * Create any kmem_caches needed for blobs 390*67a4b6a8SPaul Moore */ 391*67a4b6a8SPaul Moore if (blob_sizes.lbs_file) 392*67a4b6a8SPaul Moore lsm_file_cache = kmem_cache_create("lsm_file_cache", 393*67a4b6a8SPaul Moore blob_sizes.lbs_file, 0, 394*67a4b6a8SPaul Moore SLAB_PANIC, NULL); 395*67a4b6a8SPaul Moore if (blob_sizes.lbs_inode) 396*67a4b6a8SPaul Moore lsm_inode_cache = kmem_cache_create("lsm_inode_cache", 397*67a4b6a8SPaul Moore blob_sizes.lbs_inode, 0, 398*67a4b6a8SPaul Moore SLAB_PANIC, NULL); 399*67a4b6a8SPaul Moore 400*67a4b6a8SPaul Moore lsm_early_cred((struct cred *) current->cred); 401*67a4b6a8SPaul Moore lsm_early_task(current); 402*67a4b6a8SPaul Moore for (lsm = ordered_lsms; *lsm; lsm++) 403*67a4b6a8SPaul Moore initialize_lsm(*lsm); 404*67a4b6a8SPaul Moore } 405*67a4b6a8SPaul Moore 406*67a4b6a8SPaul Moore static bool match_last_lsm(const char *list, const char *lsm) 407*67a4b6a8SPaul Moore { 408*67a4b6a8SPaul Moore const char *last; 409*67a4b6a8SPaul Moore 410*67a4b6a8SPaul Moore if (WARN_ON(!list || !lsm)) 411*67a4b6a8SPaul Moore return false; 412*67a4b6a8SPaul Moore last = strrchr(list, ','); 413*67a4b6a8SPaul Moore if (last) 414*67a4b6a8SPaul Moore /* Pass the comma, strcmp() will check for '\0' */ 415*67a4b6a8SPaul Moore last++; 416*67a4b6a8SPaul Moore else 417*67a4b6a8SPaul Moore last = list; 418*67a4b6a8SPaul Moore return !strcmp(last, lsm); 419*67a4b6a8SPaul Moore } 420*67a4b6a8SPaul Moore 421*67a4b6a8SPaul Moore static int lsm_append(const char *new, char **result) 422*67a4b6a8SPaul Moore { 423*67a4b6a8SPaul Moore char *cp; 424*67a4b6a8SPaul Moore 425*67a4b6a8SPaul Moore if (*result == NULL) { 426*67a4b6a8SPaul Moore *result = kstrdup(new, GFP_KERNEL); 427*67a4b6a8SPaul Moore if (*result == NULL) 428*67a4b6a8SPaul Moore return -ENOMEM; 429*67a4b6a8SPaul Moore } else { 430*67a4b6a8SPaul Moore /* Check if it is the last registered name */ 431*67a4b6a8SPaul Moore if (match_last_lsm(*result, new)) 432*67a4b6a8SPaul Moore return 0; 433*67a4b6a8SPaul Moore cp = kasprintf(GFP_KERNEL, "%s,%s", *result, new); 434*67a4b6a8SPaul Moore if (cp == NULL) 435*67a4b6a8SPaul Moore return -ENOMEM; 436*67a4b6a8SPaul Moore kfree(*result); 437*67a4b6a8SPaul Moore *result = cp; 438*67a4b6a8SPaul Moore } 439*67a4b6a8SPaul Moore return 0; 440*67a4b6a8SPaul Moore } 441*67a4b6a8SPaul Moore 442*67a4b6a8SPaul Moore static void __init lsm_static_call_init(struct security_hook_list *hl) 443*67a4b6a8SPaul Moore { 444*67a4b6a8SPaul Moore struct lsm_static_call *scall = hl->scalls; 445*67a4b6a8SPaul Moore int i; 446*67a4b6a8SPaul Moore 447*67a4b6a8SPaul Moore for (i = 0; i < MAX_LSM_COUNT; i++) { 448*67a4b6a8SPaul Moore /* Update the first static call that is not used yet */ 449*67a4b6a8SPaul Moore if (!scall->hl) { 450*67a4b6a8SPaul Moore __static_call_update(scall->key, scall->trampoline, 451*67a4b6a8SPaul Moore hl->hook.lsm_func_addr); 452*67a4b6a8SPaul Moore scall->hl = hl; 453*67a4b6a8SPaul Moore static_branch_enable(scall->active); 454*67a4b6a8SPaul Moore return; 455*67a4b6a8SPaul Moore } 456*67a4b6a8SPaul Moore scall++; 457*67a4b6a8SPaul Moore } 458*67a4b6a8SPaul Moore panic("%s - Ran out of static slots.\n", __func__); 459*67a4b6a8SPaul Moore } 460*67a4b6a8SPaul Moore 461*67a4b6a8SPaul Moore /** 462*67a4b6a8SPaul Moore * security_add_hooks - Add a modules hooks to the hook lists. 463*67a4b6a8SPaul Moore * @hooks: the hooks to add 464*67a4b6a8SPaul Moore * @count: the number of hooks to add 465*67a4b6a8SPaul Moore * @lsmid: the identification information for the security module 466*67a4b6a8SPaul Moore * 467*67a4b6a8SPaul Moore * Each LSM has to register its hooks with the infrastructure. 468*67a4b6a8SPaul Moore */ 469*67a4b6a8SPaul Moore void __init security_add_hooks(struct security_hook_list *hooks, int count, 470*67a4b6a8SPaul Moore const struct lsm_id *lsmid) 471*67a4b6a8SPaul Moore { 472*67a4b6a8SPaul Moore int i; 473*67a4b6a8SPaul Moore 474*67a4b6a8SPaul Moore /* 475*67a4b6a8SPaul Moore * A security module may call security_add_hooks() more 476*67a4b6a8SPaul Moore * than once during initialization, and LSM initialization 477*67a4b6a8SPaul Moore * is serialized. Landlock is one such case. 478*67a4b6a8SPaul Moore * Look at the previous entry, if there is one, for duplication. 479*67a4b6a8SPaul Moore */ 480*67a4b6a8SPaul Moore if (lsm_active_cnt == 0 || lsm_idlist[lsm_active_cnt - 1] != lsmid) { 481*67a4b6a8SPaul Moore if (lsm_active_cnt >= MAX_LSM_COUNT) 482*67a4b6a8SPaul Moore panic("%s Too many LSMs registered.\n", __func__); 483*67a4b6a8SPaul Moore lsm_idlist[lsm_active_cnt++] = lsmid; 484*67a4b6a8SPaul Moore } 485*67a4b6a8SPaul Moore 486*67a4b6a8SPaul Moore for (i = 0; i < count; i++) { 487*67a4b6a8SPaul Moore hooks[i].lsmid = lsmid; 488*67a4b6a8SPaul Moore lsm_static_call_init(&hooks[i]); 489*67a4b6a8SPaul Moore } 490*67a4b6a8SPaul Moore 491*67a4b6a8SPaul Moore /* 492*67a4b6a8SPaul Moore * Don't try to append during early_security_init(), we'll come back 493*67a4b6a8SPaul Moore * and fix this up afterwards. 494*67a4b6a8SPaul Moore */ 495*67a4b6a8SPaul Moore if (slab_is_available()) { 496*67a4b6a8SPaul Moore if (lsm_append(lsmid->name, &lsm_names) < 0) 497*67a4b6a8SPaul Moore panic("%s - Cannot get early memory.\n", __func__); 498*67a4b6a8SPaul Moore } 499*67a4b6a8SPaul Moore } 500*67a4b6a8SPaul Moore 501*67a4b6a8SPaul Moore int __init early_security_init(void) 502*67a4b6a8SPaul Moore { 503*67a4b6a8SPaul Moore struct lsm_info *lsm; 504*67a4b6a8SPaul Moore 505*67a4b6a8SPaul Moore for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) { 506*67a4b6a8SPaul Moore if (!lsm->enabled) 507*67a4b6a8SPaul Moore lsm->enabled = &lsm_enabled_true; 508*67a4b6a8SPaul Moore prepare_lsm(lsm); 509*67a4b6a8SPaul Moore initialize_lsm(lsm); 510*67a4b6a8SPaul Moore } 511*67a4b6a8SPaul Moore 512*67a4b6a8SPaul Moore return 0; 513*67a4b6a8SPaul Moore } 514*67a4b6a8SPaul Moore 515*67a4b6a8SPaul Moore /** 516*67a4b6a8SPaul Moore * security_init - initializes the security framework 517*67a4b6a8SPaul Moore * 518*67a4b6a8SPaul Moore * This should be called early in the kernel initialization sequence. 519*67a4b6a8SPaul Moore */ 520*67a4b6a8SPaul Moore int __init security_init(void) 521*67a4b6a8SPaul Moore { 522*67a4b6a8SPaul Moore struct lsm_info *lsm; 523*67a4b6a8SPaul Moore 524*67a4b6a8SPaul Moore init_debug("legacy security=%s\n", chosen_major_lsm ? : " *unspecified*"); 525*67a4b6a8SPaul Moore init_debug(" CONFIG_LSM=%s\n", builtin_lsm_order); 526*67a4b6a8SPaul Moore init_debug("boot arg lsm=%s\n", chosen_lsm_order ? : " *unspecified*"); 527*67a4b6a8SPaul Moore 528*67a4b6a8SPaul Moore /* 529*67a4b6a8SPaul Moore * Append the names of the early LSM modules now that kmalloc() is 530*67a4b6a8SPaul Moore * available 531*67a4b6a8SPaul Moore */ 532*67a4b6a8SPaul Moore for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) { 533*67a4b6a8SPaul Moore init_debug(" early started: %s (%s)\n", lsm->name, 534*67a4b6a8SPaul Moore is_enabled(lsm) ? "enabled" : "disabled"); 535*67a4b6a8SPaul Moore if (lsm->enabled) 536*67a4b6a8SPaul Moore lsm_append(lsm->name, &lsm_names); 537*67a4b6a8SPaul Moore } 538*67a4b6a8SPaul Moore 539*67a4b6a8SPaul Moore /* Load LSMs in specified order. */ 540*67a4b6a8SPaul Moore ordered_lsm_init(); 541*67a4b6a8SPaul Moore 542*67a4b6a8SPaul Moore return 0; 543*67a4b6a8SPaul Moore } 544