File Index
Files and directories
Sign in
FILE

lsm_init.c

File preview with syntax highlighting.

linux-6.19.14/security/lsm_init.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * LSM initialization functions
  4 */
  5
  6#define pr_fmt(fmt) "LSM: " fmt
  7
  8#include <linux/init.h>
  9#include <linux/lsm_hooks.h>
 10
 11#include "lsm.h"
 12
 13/* LSM enabled constants. */
 14static __initdata int lsm_enabled_true = 1;
 15static __initdata int lsm_enabled_false = 0;
 16
 17/* Pointers to LSM sections defined in include/asm-generic/vmlinux.lds.h */
 18extern struct lsm_info __start_lsm_info[], __end_lsm_info[];
 19extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[];
 20
 21/* Number of "early" LSMs */
 22static __initdata unsigned int lsm_count_early;
 23
 24/* Build and boot-time LSM ordering. */
 25static __initconst const char *const lsm_order_builtin = CONFIG_LSM;
 26static __initdata const char *lsm_order_cmdline;
 27static __initdata const char *lsm_order_legacy;
 28
 29/* Ordered list of LSMs to initialize. */
 30static __initdata struct lsm_info *lsm_order[MAX_LSM_COUNT + 1];
 31static __initdata struct lsm_info *lsm_exclusive;
 32
 33#define lsm_order_for_each(iter)					\
 34	for ((iter) = lsm_order; *(iter); (iter)++)
 35#define lsm_for_each_raw(iter)						\
 36	for ((iter) = __start_lsm_info;					\
 37	     (iter) < __end_lsm_info; (iter)++)
 38#define lsm_early_for_each_raw(iter)					\
 39	for ((iter) = __start_early_lsm_info;				\
 40	     (iter) < __end_early_lsm_info; (iter)++)
 41
 42#define lsm_initcall(level)						\
 43	({								\
 44		int _r, _rc = 0;					\
 45		struct lsm_info **_lp, *_l;				\
 46		lsm_order_for_each(_lp) {				\
 47			_l = *_lp;					\
 48			if (!_l->initcall_##level)			\
 49				continue;				\
 50			lsm_pr_dbg("running %s %s initcall",		\
 51				   _l->id->name, #level);		\
 52			_r = _l->initcall_##level();			\
 53			if (_r) {					\
 54				pr_warn("failed LSM %s %s initcall with errno %d\n", \
 55					_l->id->name, #level, _r);	\
 56				if (!_rc)				\
 57					_rc = _r;			\
 58			}						\
 59		}							\
 60		_rc;							\
 61	})
 62
 63/**
 64 * lsm_choose_security - Legacy "major" LSM selection
 65 * @str: kernel command line parameter
 66 */
 67static int __init lsm_choose_security(char *str)
 68{
 69	lsm_order_legacy = str;
 70	return 1;
 71}
 72__setup("security=", lsm_choose_security);
 73
 74/**
 75 * lsm_choose_lsm - Modern LSM selection
 76 * @str: kernel command line parameter
 77 */
 78static int __init lsm_choose_lsm(char *str)
 79{
 80	lsm_order_cmdline = str;
 81	return 1;
 82}
 83__setup("lsm=", lsm_choose_lsm);
 84
 85/**
 86 * lsm_debug_enable - Enable LSM framework debugging
 87 * @str: kernel command line parameter
 88 *
 89 * Currently we only provide debug info during LSM initialization, but we may
 90 * want to expand this in the future.
 91 */
 92static int __init lsm_debug_enable(char *str)
 93{
 94	lsm_debug = true;
 95	return 1;
 96}
 97__setup("lsm.debug", lsm_debug_enable);
 98
 99/**
100 * lsm_enabled_set - Mark a LSM as enabled
101 * @lsm: LSM definition
102 * @enabled: enabled flag
103 */
104static void __init lsm_enabled_set(struct lsm_info *lsm, bool enabled)
105{
106	/*
107	 * When an LSM hasn't configured an enable variable, we can use
108	 * a hard-coded location for storing the default enabled state.
109	 */
110	if (!lsm->enabled ||
111	    lsm->enabled == &lsm_enabled_true ||
112	    lsm->enabled == &lsm_enabled_false) {
113		lsm->enabled = enabled ? &lsm_enabled_true : &lsm_enabled_false;
114	} else {
115		*lsm->enabled = enabled;
116	}
117}
118
119/**
120 * lsm_is_enabled - Determine if a LSM is enabled
121 * @lsm: LSM definition
122 */
123static inline bool lsm_is_enabled(struct lsm_info *lsm)
124{
125	return (lsm->enabled ? *lsm->enabled : false);
126}
127
128/**
129 * lsm_order_exists - Determine if a LSM exists in the ordered list
130 * @lsm: LSM definition
131 */
132static bool __init lsm_order_exists(struct lsm_info *lsm)
133{
134	struct lsm_info **check;
135
136	lsm_order_for_each(check) {
137		if (*check == lsm)
138			return true;
139	}
140
141	return false;
142}
143
144/**
145 * lsm_order_append - Append a LSM to the ordered list
146 * @lsm: LSM definition
147 * @src: source of the addition
148 *
149 * Append @lsm to the enabled LSM array after ensuring that it hasn't been
150 * explicitly disabled, is a duplicate entry, or would run afoul of the
151 * LSM_FLAG_EXCLUSIVE logic.
152 */
153static void __init lsm_order_append(struct lsm_info *lsm, const char *src)
154{
155	/* Ignore duplicate selections. */
156	if (lsm_order_exists(lsm))
157		return;
158
159	/* Skip explicitly disabled LSMs. */
160	if (lsm->enabled && !lsm_is_enabled(lsm)) {
161		lsm_pr_dbg("skip previously disabled LSM %s:%s\n",
162			   src, lsm->id->name);
163		return;
164	}
165
166	if (lsm_active_cnt == MAX_LSM_COUNT) {
167		pr_warn("exceeded maximum LSM count on %s:%s\n",
168			src, lsm->id->name);
169		lsm_enabled_set(lsm, false);
170		return;
171	}
172
173	if (lsm->flags & LSM_FLAG_EXCLUSIVE) {
174		if (lsm_exclusive) {
175			lsm_pr_dbg("skip exclusive LSM conflict %s:%s\n",
176				   src, lsm->id->name);
177			lsm_enabled_set(lsm, false);
178			return;
179		} else {
180			lsm_pr_dbg("select exclusive LSM %s:%s\n",
181				   src, lsm->id->name);
182			lsm_exclusive = lsm;
183		}
184	}
185
186	lsm_enabled_set(lsm, true);
187	lsm_order[lsm_active_cnt] = lsm;
188	lsm_idlist[lsm_active_cnt++] = lsm->id;
189
190	lsm_pr_dbg("enabling LSM %s:%s\n", src, lsm->id->name);
191}
192
193/**
194 * lsm_order_parse - Parse the comma delimited LSM list
195 * @list: LSM list
196 * @src: source of the list
197 */
198static void __init lsm_order_parse(const char *list, const char *src)
199{
200	struct lsm_info *lsm;
201	char *sep, *name, *next;
202
203	/* Handle any Legacy LSM exclusions if one was specified. */
204	if (lsm_order_legacy) {
205		/*
206		 * To match the original "security=" behavior, this explicitly
207		 * does NOT fallback to another Legacy Major if the selected
208		 * one was separately disabled: disable all non-matching
209		 * Legacy Major LSMs.
210		 */
211		lsm_for_each_raw(lsm) {
212			if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) &&
213			     strcmp(lsm->id->name, lsm_order_legacy)) {
214				lsm_enabled_set(lsm, false);
215				lsm_pr_dbg("skip legacy LSM conflict %s:%s\n",
216					   src, lsm->id->name);
217			}
218		}
219	}
220
221	/* LSM_ORDER_FIRST */
222	lsm_for_each_raw(lsm) {
223		if (lsm->order == LSM_ORDER_FIRST)
224			lsm_order_append(lsm, "first");
225	}
226
227	/* Normal or "mutable" LSMs */
228	sep = kstrdup(list, GFP_KERNEL);
229	next = sep;
230	/* Walk the list, looking for matching LSMs. */
231	while ((name = strsep(&next, ",")) != NULL) {
232		lsm_for_each_raw(lsm) {
233			if (!strcmp(lsm->id->name, name) &&
234			    lsm->order == LSM_ORDER_MUTABLE)
235				lsm_order_append(lsm, src);
236		}
237	}
238	kfree(sep);
239
240	/* Legacy LSM if specified. */
241	if (lsm_order_legacy) {
242		lsm_for_each_raw(lsm) {
243			if (!strcmp(lsm->id->name, lsm_order_legacy))
244				lsm_order_append(lsm, src);
245		}
246	}
247
248	/* LSM_ORDER_LAST */
249	lsm_for_each_raw(lsm) {
250		if (lsm->order == LSM_ORDER_LAST)
251			lsm_order_append(lsm, "last");
252	}
253
254	/* Disable all LSMs not previously enabled. */
255	lsm_for_each_raw(lsm) {
256		if (lsm_order_exists(lsm))
257			continue;
258		lsm_enabled_set(lsm, false);
259		lsm_pr_dbg("skip disabled LSM %s:%s\n", src, lsm->id->name);
260	}
261}
262
263/**
264 * lsm_blob_size_update - Update the LSM blob size and offset information
265 * @sz_req: the requested additional blob size
266 * @sz_cur: the existing blob size
267 */
268static void __init lsm_blob_size_update(unsigned int *sz_req,
269					unsigned int *sz_cur)
270{
271	unsigned int offset;
272
273	if (*sz_req == 0)
274		return;
275
276	offset = ALIGN(*sz_cur, sizeof(void *));
277	*sz_cur = offset + *sz_req;
278	*sz_req = offset;
279}
280
281/**
282 * lsm_prepare - Prepare the LSM framework for a new LSM
283 * @lsm: LSM definition
284 */
285static void __init lsm_prepare(struct lsm_info *lsm)
286{
287	struct lsm_blob_sizes *blobs = lsm->blobs;
288
289	if (!blobs)
290		return;
291
292	/* Register the LSM blob sizes. */
293	blobs = lsm->blobs;
294	lsm_blob_size_update(&blobs->lbs_cred, &blob_sizes.lbs_cred);
295	lsm_blob_size_update(&blobs->lbs_file, &blob_sizes.lbs_file);
296	lsm_blob_size_update(&blobs->lbs_ib, &blob_sizes.lbs_ib);
297	/* inode blob gets an rcu_head in addition to LSM blobs. */
298	if (blobs->lbs_inode && blob_sizes.lbs_inode == 0)
299		blob_sizes.lbs_inode = sizeof(struct rcu_head);
300	lsm_blob_size_update(&blobs->lbs_inode, &blob_sizes.lbs_inode);
301	lsm_blob_size_update(&blobs->lbs_ipc, &blob_sizes.lbs_ipc);
302	lsm_blob_size_update(&blobs->lbs_key, &blob_sizes.lbs_key);
303	lsm_blob_size_update(&blobs->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
304	lsm_blob_size_update(&blobs->lbs_perf_event,
305			     &blob_sizes.lbs_perf_event);
306	lsm_blob_size_update(&blobs->lbs_sock, &blob_sizes.lbs_sock);
307	lsm_blob_size_update(&blobs->lbs_superblock,
308			     &blob_sizes.lbs_superblock);
309	lsm_blob_size_update(&blobs->lbs_task, &blob_sizes.lbs_task);
310	lsm_blob_size_update(&blobs->lbs_tun_dev, &blob_sizes.lbs_tun_dev);
311	lsm_blob_size_update(&blobs->lbs_xattr_count,
312			     &blob_sizes.lbs_xattr_count);
313	lsm_blob_size_update(&blobs->lbs_bdev, &blob_sizes.lbs_bdev);
314	lsm_blob_size_update(&blobs->lbs_bpf_map, &blob_sizes.lbs_bpf_map);
315	lsm_blob_size_update(&blobs->lbs_bpf_prog, &blob_sizes.lbs_bpf_prog);
316	lsm_blob_size_update(&blobs->lbs_bpf_token, &blob_sizes.lbs_bpf_token);
317}
318
319/**
320 * lsm_init_single - Initialize a given LSM
321 * @lsm: LSM definition
322 */
323static void __init lsm_init_single(struct lsm_info *lsm)
324{
325	int ret;
326
327	if (!lsm_is_enabled(lsm))
328		return;
329
330	lsm_pr_dbg("initializing %s\n", lsm->id->name);
331	ret = lsm->init();
332	WARN(ret, "%s failed to initialize: %d\n", lsm->id->name, ret);
333}
334
335/**
336 * lsm_static_call_init - Initialize a LSM's static calls
337 * @hl: LSM hook list
338 */
339static int __init lsm_static_call_init(struct security_hook_list *hl)
340{
341	struct lsm_static_call *scall = hl->scalls;
342	int i;
343
344	for (i = 0; i < MAX_LSM_COUNT; i++) {
345		/* Update the first static call that is not used yet */
346		if (!scall->hl) {
347			__static_call_update(scall->key, scall->trampoline,
348					     hl->hook.lsm_func_addr);
349			scall->hl = hl;
350			static_branch_enable(scall->active);
351			return 0;
352		}
353		scall++;
354	}
355
356	return -ENOSPC;
357}
358
359/**
360 * security_add_hooks - Add a LSM's hooks to the LSM framework's hook lists
361 * @hooks: LSM hooks to add
362 * @count: number of hooks to add
363 * @lsmid: identification information for the LSM
364 *
365 * Each LSM has to register its hooks with the LSM framework.
366 */
367void __init security_add_hooks(struct security_hook_list *hooks, int count,
368			       const struct lsm_id *lsmid)
369{
370	int i;
371
372	for (i = 0; i < count; i++) {
373		hooks[i].lsmid = lsmid;
374		if (lsm_static_call_init(&hooks[i]))
375			panic("exhausted LSM callback slots with LSM %s\n",
376			      lsmid->name);
377	}
378}
379
380/**
381 * early_security_init - Initialize the early LSMs
382 */
383int __init early_security_init(void)
384{
385	struct lsm_info *lsm;
386
387	/* NOTE: lsm_pr_dbg() doesn't work here as lsm_debug is not yet set */
388
389	lsm_early_for_each_raw(lsm) {
390		lsm_enabled_set(lsm, true);
391		lsm_order_append(lsm, "early");
392		lsm_prepare(lsm);
393		lsm_init_single(lsm);
394		lsm_count_early++;
395	}
396
397	return 0;
398}
399
400/**
401 * security_init - Initializes the LSM framework
402 *
403 * This should be called early in the kernel initialization sequence.
404 */
405int __init security_init(void)
406{
407	unsigned int cnt;
408	struct lsm_info **lsm;
409
410	if (lsm_debug) {
411		struct lsm_info *i;
412
413		cnt = 0;
414		lsm_pr("available LSMs: ");
415		lsm_early_for_each_raw(i)
416			lsm_pr_cont("%s%s(E)", (cnt++ ? "," : ""), i->id->name);
417		lsm_for_each_raw(i)
418			lsm_pr_cont("%s%s", (cnt++ ? "," : ""), i->id->name);
419		lsm_pr_cont("\n");
420
421		lsm_pr("built-in LSM config: %s\n", lsm_order_builtin);
422
423		lsm_pr("legacy LSM parameter: %s\n", lsm_order_legacy);
424		lsm_pr("boot LSM parameter: %s\n", lsm_order_cmdline);
425
426		/* see the note about lsm_pr_dbg() in early_security_init() */
427		lsm_early_for_each_raw(i)
428			lsm_pr("enabled LSM early:%s\n", i->id->name);
429	}
430
431	if (lsm_order_cmdline) {
432		if (lsm_order_legacy)
433			lsm_order_legacy = NULL;
434		lsm_order_parse(lsm_order_cmdline, "cmdline");
435	} else
436		lsm_order_parse(lsm_order_builtin, "builtin");
437
438	lsm_order_for_each(lsm)
439		lsm_prepare(*lsm);
440
441	if (lsm_debug) {
442		lsm_pr("blob(cred) size %d\n", blob_sizes.lbs_cred);
443		lsm_pr("blob(file) size %d\n", blob_sizes.lbs_file);
444		lsm_pr("blob(ib) size %d\n", blob_sizes.lbs_ib);
445		lsm_pr("blob(inode) size %d\n", blob_sizes.lbs_inode);
446		lsm_pr("blob(ipc) size %d\n", blob_sizes.lbs_ipc);
447		lsm_pr("blob(key) size %d\n", blob_sizes.lbs_key);
448		lsm_pr("blob(msg_msg)_size %d\n", blob_sizes.lbs_msg_msg);
449		lsm_pr("blob(sock) size %d\n", blob_sizes.lbs_sock);
450		lsm_pr("blob(superblock) size %d\n", blob_sizes.lbs_superblock);
451		lsm_pr("blob(perf_event) size %d\n", blob_sizes.lbs_perf_event);
452		lsm_pr("blob(task) size %d\n", blob_sizes.lbs_task);
453		lsm_pr("blob(tun_dev) size %d\n", blob_sizes.lbs_tun_dev);
454		lsm_pr("blob(xattr) count %d\n", blob_sizes.lbs_xattr_count);
455		lsm_pr("blob(bdev) size %d\n", blob_sizes.lbs_bdev);
456		lsm_pr("blob(bpf_map) size %d\n", blob_sizes.lbs_bpf_map);
457		lsm_pr("blob(bpf_prog) size %d\n", blob_sizes.lbs_bpf_prog);
458		lsm_pr("blob(bpf_token) size %d\n", blob_sizes.lbs_bpf_token);
459	}
460
461	if (blob_sizes.lbs_file)
462		lsm_file_cache = kmem_cache_create("lsm_file_cache",
463						   blob_sizes.lbs_file, 0,
464						   SLAB_PANIC, NULL);
465	if (blob_sizes.lbs_inode)
466		lsm_inode_cache = kmem_cache_create("lsm_inode_cache",
467						    blob_sizes.lbs_inode, 0,
468						    SLAB_PANIC, NULL);
469
470	if (lsm_cred_alloc((struct cred *)unrcu_pointer(current->cred),
471			   GFP_KERNEL))
472		panic("early LSM cred alloc failed\n");
473	if (lsm_task_alloc(current))
474		panic("early LSM task alloc failed\n");
475
476	cnt = 0;
477	lsm_order_for_each(lsm) {
478		/* skip the "early" LSMs as they have already been setup */
479		if (cnt++ < lsm_count_early)
480			continue;
481		lsm_init_single(*lsm);
482	}
483
484	return 0;
485}
486
487/**
488 * security_initcall_pure - Run the LSM pure initcalls
489 */
490static int __init security_initcall_pure(void)
491{
492	return lsm_initcall(pure);
493}
494pure_initcall(security_initcall_pure);
495
496/**
497 * security_initcall_early - Run the LSM early initcalls
498 */
499static int __init security_initcall_early(void)
500{
501	return lsm_initcall(early);
502}
503early_initcall(security_initcall_early);
504
505/**
506 * security_initcall_core - Run the LSM core initcalls
507 */
508static int __init security_initcall_core(void)
509{
510	int rc_sfs, rc_lsm;
511
512	rc_sfs = securityfs_init();
513	rc_lsm = lsm_initcall(core);
514
515	return (rc_sfs ? rc_sfs : rc_lsm);
516}
517core_initcall(security_initcall_core);
518
519/**
520 * security_initcall_subsys - Run the LSM subsys initcalls
521 */
522static int __init security_initcall_subsys(void)
523{
524	return lsm_initcall(subsys);
525}
526subsys_initcall(security_initcall_subsys);
527
528/**
529 * security_initcall_fs - Run the LSM fs initcalls
530 */
531static int __init security_initcall_fs(void)
532{
533	return lsm_initcall(fs);
534}
535fs_initcall(security_initcall_fs);
536
537/**
538 * security_initcall_device - Run the LSM device initcalls
539 */
540static int __init security_initcall_device(void)
541{
542	return lsm_initcall(device);
543}
544device_initcall(security_initcall_device);
545
546/**
547 * security_initcall_late - Run the LSM late initcalls
548 */
549static int __init security_initcall_late(void)
550{
551	int rc;
552
553	rc = lsm_initcall(late);
554	lsm_pr_dbg("all enabled LSMs fully activated\n");
555	call_blocking_lsm_notifier(LSM_STARTED_ALL, NULL);
556
557	return rc;
558}
559late_initcall(security_initcall_late);
~/ Read-only file preview.