[PATCH v3 20/34] lsm: cleanup the debug and console output in lsm_init.c

John Johansen john.johansen at canonical.com
Wed Sep 3 10:22:05 UTC 2025


On 8/14/25 15:50, Paul Moore wrote:
> Move away from an init specific init_debug() macro to a more general
> lsm_pr()/lsm_pr_cont()/lsm_pr_dbg() set of macros that are available
> both before and after init.  In the process we do a number of minor
> changes to improve the LSM initialization output and cleanup the code
> somewhat.
> 
> Reviewed-by: Casey Schaufler <casey at schaufler-ca.com>
> Signed-off-by: Paul Moore <paul at paul-moore.com>

Reviewed-by: John Johansen <john.johansen at canonical.com>

> ---
>   security/lsm.h      |  11 ++++
>   security/lsm_init.c | 123 +++++++++++++++++++-------------------------
>   security/security.c |   2 +
>   3 files changed, 66 insertions(+), 70 deletions(-)
> 
> diff --git a/security/lsm.h b/security/lsm.h
> index dbe755c45e57..8dc267977ae0 100644
> --- a/security/lsm.h
> +++ b/security/lsm.h
> @@ -6,9 +6,20 @@
>   #ifndef _LSM_H_
>   #define _LSM_H_
>   
> +#include <linux/printk.h>
>   #include <linux/lsm_hooks.h>
>   #include <linux/lsm_count.h>
>   
> +/* LSM debugging */
> +extern bool lsm_debug;
> +#define lsm_pr(...)		pr_info(__VA_ARGS__)
> +#define lsm_pr_cont(...)	pr_cont(__VA_ARGS__)
> +#define lsm_pr_dbg(...)							\
> +	do {								\
> +		if (lsm_debug)						\
> +			pr_info(__VA_ARGS__);				\
> +	} while (0)
> +
>   /* List of configured LSMs */
>   extern unsigned int lsm_active_cnt;
>   extern const struct lsm_id *lsm_idlist[];
> diff --git a/security/lsm_init.c b/security/lsm_init.c
> index 37593805ba9e..2f7ae26fca0f 100644
> --- a/security/lsm_init.c
> +++ b/security/lsm_init.c
> @@ -30,13 +30,6 @@ static __initdata const char *lsm_order_legacy;
>   static __initdata struct lsm_info *lsm_order[MAX_LSM_COUNT + 1];
>   static __initdata struct lsm_info *lsm_exclusive;
>   
> -static __initdata bool debug;
> -#define init_debug(...)							\
> -	do {								\
> -		if (debug)						\
> -			pr_info(__VA_ARGS__);				\
> -	} while (0)
> -
>   #define lsm_order_for_each(iter)					\
>   	for ((iter) = lsm_order; *(iter); (iter)++)
>   #define lsm_for_each_raw(iter)						\
> @@ -77,7 +70,7 @@ __setup("lsm=", lsm_choose_lsm);
>    */
>   static int __init lsm_debug_enable(char *str)
>   {
> -	debug = true;
> +	lsm_debug = true;
>   	return 1;
>   }
>   __setup("lsm.debug", lsm_debug_enable);
> @@ -143,22 +136,28 @@ static void __init lsm_order_append(struct lsm_info *lsm, const char *src)
>   		return;
>   
>   	/* Skip explicitly disabled LSMs. */
> -	if (lsm->enabled && !lsm_is_enabled(lsm))
> -		goto out;
> +	if (lsm->enabled && !lsm_is_enabled(lsm)) {
> +		lsm_pr_dbg("skip previously disabled LSM %s:%s\n",
> +			   src, lsm->id->name);
> +		return;
> +	}
>   
> -	if (WARN(lsm_active_cnt == MAX_LSM_COUNT,
> -		 "%s: out of LSM static calls!?\n", src)) {
> +	if (lsm_active_cnt == MAX_LSM_COUNT) {
> +		pr_warn("exceeded maximum LSM count on %s:%s\n",
> +			src, lsm->id->name);
>   		lsm_enabled_set(lsm, false);
> -		goto out;
> +		return;
>   	}
>   
>   	if (lsm->flags & LSM_FLAG_EXCLUSIVE) {
>   		if (lsm_exclusive) {
> -			init_debug("exclusive disabled: %s\n", lsm->id->name);
> +			lsm_pr_dbg("skip exclusive LSM conflict %s:%s\n",
> +				   src, lsm->id->name);
>   			lsm_enabled_set(lsm, false);
> -			goto out;
> +			return;
>   		} else {
> -			init_debug("exclusive chosen:   %s\n", lsm->id->name);
> +			lsm_pr_dbg("select exclusive LSM %s:%s\n",
> +				   src, lsm->id->name);
>   			lsm_exclusive = lsm;
>   		}
>   	}
> @@ -167,9 +166,7 @@ static void __init lsm_order_append(struct lsm_info *lsm, const char *src)
>   	lsm_order[lsm_active_cnt] = lsm;
>   	lsm_idlist[lsm_active_cnt++] = lsm->id;
>   
> -out:
> -	init_debug("%s ordered: %s (%s)\n", src, lsm->id->name,
> -		   lsm_is_enabled(lsm) ? "enabled" : "disabled");
> +	lsm_pr_dbg("enabling LSM %s:%s\n", src, lsm->id->name);
>   }
>   
>   /**
> @@ -239,7 +236,7 @@ static void __init lsm_init_single(struct lsm_info *lsm)
>   	if (!lsm_is_enabled(lsm))
>   		return;
>   
> -	init_debug("initializing %s\n", lsm->id->name);
> +	lsm_pr_dbg("initializing %s\n", lsm->id->name);
>   	ret = lsm->init();
>   	WARN(ret, "%s failed to initialize: %d\n", lsm->id->name, ret);
>   }
> @@ -266,8 +263,8 @@ static void __init lsm_order_parse(const char *list, const char *src)
>   			if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) &&
>   			     strcmp(lsm->id->name, lsm_order_legacy)) {
>   				lsm_enabled_set(lsm, false);
> -				init_debug("security=%s disabled: %s (only one legacy major LSM)\n",
> -					   lsm_order_legacy, lsm->id->name);
> +				lsm_pr_dbg("skip legacy LSM conflict %s:%s\n",
> +					   src, lsm->id->name);
>   			}
>   		}
>   	}
> @@ -310,8 +307,7 @@ static void __init lsm_order_parse(const char *list, const char *src)
>   		if (lsm_order_exists(lsm))
>   			continue;
>   		lsm_enabled_set(lsm, false);
> -		init_debug("%s skipped: %s (not in requested order)\n",
> -			   src, lsm->id->name);
> +		lsm_pr_dbg("skip disabled LSM %s:%s\n", src, lsm->id->name);
>   	}
>   }
>   
> @@ -319,7 +315,7 @@ static void __init lsm_order_parse(const char *list, const char *src)
>    * lsm_static_call_init - Initialize a LSM's static calls
>    * @hl: LSM hook list
>    */
> -static void __init lsm_static_call_init(struct security_hook_list *hl)
> +static int __init lsm_static_call_init(struct security_hook_list *hl)
>   {
>   	struct lsm_static_call *scall = hl->scalls;
>   	int i;
> @@ -331,11 +327,12 @@ static void __init lsm_static_call_init(struct security_hook_list *hl)
>   					     hl->hook.lsm_func_addr);
>   			scall->hl = hl;
>   			static_branch_enable(scall->active);
> -			return;
> +			return 0;
>   		}
>   		scall++;
>   	}
> -	panic("%s - Ran out of static slots.\n", __func__);
> +
> +	return -ENOSPC;
>   }
>   
>   /**
> @@ -353,7 +350,9 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
>   
>   	for (i = 0; i < count; i++) {
>   		hooks[i].lsmid = lsmid;
> -		lsm_static_call_init(&hooks[i]);
> +		if (lsm_static_call_init(&hooks[i]))
> +			panic("exhausted LSM callback slots with LSM %s\n",
> +			      lsmid->name);
>   	}
>   }
>   
> @@ -384,19 +383,16 @@ int __init security_init(void)
>   {
>   	unsigned int cnt;
>   	struct lsm_info **lsm;
> -	struct lsm_info *early;
> -	unsigned int first = 0;
>   
> -	init_debug("legacy security=%s\n", lsm_order_legacy ? : " *unspecified*");
> -	init_debug("  CONFIG_LSM=%s\n", lsm_order_builtin);
> -	init_debug("boot arg lsm=%s\n", lsm_order_cmdline ? : " *unspecified*");
> +	if (lsm_debug) {
> +		lsm_pr("built-in LSM list: %s\n", lsm_order_builtin);
> +		lsm_pr("legacy LSM parameter: %s\n", lsm_order_legacy);
> +		lsm_pr("boot LSM parameter: %s\n", lsm_order_cmdline);
> +	}
>   
>   	if (lsm_order_cmdline) {
> -		if (lsm_order_legacy) {
> -			pr_warn("security=%s is ignored because it is superseded by lsm=%s\n",
> -				lsm_order_legacy, lsm_order_cmdline);
> +		if (lsm_order_legacy)
>   			lsm_order_legacy = NULL;
> -		}
>   		lsm_order_parse(lsm_order_cmdline, "cmdline");
>   	} else
>   		lsm_order_parse(lsm_order_builtin, "builtin");
> @@ -404,38 +400,25 @@ int __init security_init(void)
>   	lsm_order_for_each(lsm)
>   		lsm_prepare(*lsm);
>   
> -	pr_info("initializing lsm=");
> -	lsm_early_for_each_raw(early) {
> -		if (lsm_is_enabled(early))
> -			pr_cont("%s%s",
> -				first++ == 0 ? "" : ",", early->id->name);
> +	if (lsm_debug) {
> +		lsm_pr("blob(cred) size %d\n", blob_sizes.lbs_cred);
> +		lsm_pr("blob(file) size %d\n", blob_sizes.lbs_file);
> +		lsm_pr("blob(ib) size %d\n", blob_sizes.lbs_ib);
> +		lsm_pr("blob(inode) size %d\n", blob_sizes.lbs_inode);
> +		lsm_pr("blob(ipc) size %d\n", blob_sizes.lbs_ipc);
> +		lsm_pr("blob(key) size %d\n", blob_sizes.lbs_key);
> +		lsm_pr("blob(msg_msg)_size %d\n", blob_sizes.lbs_msg_msg);
> +		lsm_pr("blob(sock) size %d\n", blob_sizes.lbs_sock);
> +		lsm_pr("blob(superblock) size %d\n", blob_sizes.lbs_superblock);
> +		lsm_pr("blob(perf_event) size %d\n", blob_sizes.lbs_perf_event);
> +		lsm_pr("blob(task) size %d\n", blob_sizes.lbs_task);
> +		lsm_pr("blob(tun_dev) size %d\n", blob_sizes.lbs_tun_dev);
> +		lsm_pr("blob(xattr) count %d\n", blob_sizes.lbs_xattr_count);
> +		lsm_pr("blob(bdev) size %d\n", blob_sizes.lbs_bdev);
> +		lsm_pr("blob(bpf_map) size %d\n", blob_sizes.lbs_bpf_map);
> +		lsm_pr("blob(bpf_prog) size %d\n", blob_sizes.lbs_bpf_prog);
> +		lsm_pr("blob(bpf_token) size %d\n", blob_sizes.lbs_bpf_token);
>   	}
> -	lsm_order_for_each(lsm) {
> -		if (lsm_is_enabled(*lsm))
> -			pr_cont("%s%s",
> -				first++ == 0 ? "" : ",", (*lsm)->id->name);
> -	}
> -	pr_cont("\n");
> -
> -	init_debug("cred blob size       = %d\n", blob_sizes.lbs_cred);
> -	init_debug("file blob size       = %d\n", blob_sizes.lbs_file);
> -	init_debug("ib blob size         = %d\n", blob_sizes.lbs_ib);
> -	init_debug("inode blob size      = %d\n", blob_sizes.lbs_inode);
> -	init_debug("ipc blob size        = %d\n", blob_sizes.lbs_ipc);
> -#ifdef CONFIG_KEYS
> -	init_debug("key blob size        = %d\n", blob_sizes.lbs_key);
> -#endif /* CONFIG_KEYS */
> -	init_debug("msg_msg blob size    = %d\n", blob_sizes.lbs_msg_msg);
> -	init_debug("sock blob size       = %d\n", blob_sizes.lbs_sock);
> -	init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
> -	init_debug("perf event blob size = %d\n", blob_sizes.lbs_perf_event);
> -	init_debug("task blob size       = %d\n", blob_sizes.lbs_task);
> -	init_debug("tun device blob size = %d\n", blob_sizes.lbs_tun_dev);
> -	init_debug("xattr slots          = %d\n", blob_sizes.lbs_xattr_count);
> -	init_debug("bdev blob size       = %d\n", blob_sizes.lbs_bdev);
> -	init_debug("bpf map blob size    = %d\n", blob_sizes.lbs_bpf_map);
> -	init_debug("bpf prog blob size   = %d\n", blob_sizes.lbs_bpf_prog);
> -	init_debug("bpf token blob size  = %d\n", blob_sizes.lbs_bpf_token);
>   
>   	if (blob_sizes.lbs_file)
>   		lsm_file_cache = kmem_cache_create("lsm_file_cache",
> @@ -447,9 +430,9 @@ int __init security_init(void)
>   						    SLAB_PANIC, NULL);
>   
>   	if (lsm_cred_alloc((struct cred *)current->cred, GFP_KERNEL))
> -		panic("%s: early cred alloc failed.\n", __func__);
> +		panic("early LSM cred alloc failed\n");
>   	if (lsm_task_alloc(current))
> -		panic("%s: early task alloc failed.\n", __func__);
> +		panic("early LSM task alloc failed\n");
>   
>   	cnt = 0;
>   	lsm_order_for_each(lsm) {
> diff --git a/security/security.c b/security/security.c
> index add46073af0c..c9642020755e 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -73,6 +73,8 @@ const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX + 1] = {
>   	[LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality",
>   };
>   
> +bool lsm_debug __ro_after_init;
> +
>   unsigned int lsm_active_cnt __ro_after_init;
>   const struct lsm_id *lsm_idlist[MAX_LSM_COUNT];
>   




More information about the Linux-security-module-archive mailing list