xref: /linux/security/lsm_init.c (revision 67a4b6a89b99aff0883114e4ecba4b11aedc29a5)
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