On 5/9/2024 1:14 PM, KP Singh wrote: > These macros are a clever trick to determine a count of the number of > LSMs that are enabled in the config to ascertain the maximum number of > static calls that need to be configured per LSM hook. > > Without this one would need to generate static calls for the total > number of LSMs in the kernel (even if they are not compiled) times the > number of LSM hooks which ends up being quite wasteful. > > Suggested-by: Kui-Feng Lee <sinquersw@xxxxxxxxx> > Suggested-by: Andrii Nakryiko <andrii@xxxxxxxxxx> > Acked-by: Song Liu <song@xxxxxxxxxx> > Acked-by: Andrii Nakryiko <andrii@xxxxxxxxxx> > Reviewed-by: Kees Cook <keescook@xxxxxxxxxxxx> > Signed-off-by: KP Singh <kpsingh@xxxxxxxxxx> Reviewed-by: Casey Schaufler <casey@xxxxxxxxxxxxxxxx> > --- > include/linux/args.h | 6 +- > include/linux/lsm_count.h | 128 ++++++++++++++++++++++++++++++++++++++ > 2 files changed, 131 insertions(+), 3 deletions(-) > create mode 100644 include/linux/lsm_count.h > > diff --git a/include/linux/args.h b/include/linux/args.h > index 8ff60a54eb7d..2e8e65d975c7 100644 > --- a/include/linux/args.h > +++ b/include/linux/args.h > @@ -17,9 +17,9 @@ > * that as _n. > */ > > -/* This counts to 12. Any more, it will return 13th argument. */ > -#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n > -#define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) > +/* This counts to 15. Any more, it will return 16th argument. */ > +#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _n, X...) _n > +#define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) > > /* Concatenate two parameters, but allow them to be expanded beforehand. */ > #define __CONCAT(a, b) a ## b > diff --git a/include/linux/lsm_count.h b/include/linux/lsm_count.h > new file mode 100644 > index 000000000000..73c7cc81349b > --- /dev/null > +++ b/include/linux/lsm_count.h > @@ -0,0 +1,128 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > + > +/* > + * Copyright (C) 2023 Google LLC. > + */ > + > +#ifndef __LINUX_LSM_COUNT_H > +#define __LINUX_LSM_COUNT_H > + > +#include <linux/args.h> > + > +#ifdef CONFIG_SECURITY > + > +/* > + * Macros to count the number of LSMs enabled in the kernel at compile time. > + */ > + > +/* > + * Capabilities is enabled when CONFIG_SECURITY is enabled. > + */ > +#if IS_ENABLED(CONFIG_SECURITY) > +#define CAPABILITIES_ENABLED 1, > +#else > +#define CAPABILITIES_ENABLED > +#endif > + > +#if IS_ENABLED(CONFIG_SECURITY_SELINUX) > +#define SELINUX_ENABLED 1, > +#else > +#define SELINUX_ENABLED > +#endif > + > +#if IS_ENABLED(CONFIG_SECURITY_SMACK) > +#define SMACK_ENABLED 1, > +#else > +#define SMACK_ENABLED > +#endif > + > +#if IS_ENABLED(CONFIG_SECURITY_APPARMOR) > +#define APPARMOR_ENABLED 1, > +#else > +#define APPARMOR_ENABLED > +#endif > + > +#if IS_ENABLED(CONFIG_SECURITY_TOMOYO) > +#define TOMOYO_ENABLED 1, > +#else > +#define TOMOYO_ENABLED > +#endif > + > +#if IS_ENABLED(CONFIG_SECURITY_YAMA) > +#define YAMA_ENABLED 1, > +#else > +#define YAMA_ENABLED > +#endif > + > +#if IS_ENABLED(CONFIG_SECURITY_LOADPIN) > +#define LOADPIN_ENABLED 1, > +#else > +#define LOADPIN_ENABLED > +#endif > + > +#if IS_ENABLED(CONFIG_SECURITY_LOCKDOWN_LSM) > +#define LOCKDOWN_ENABLED 1, > +#else > +#define LOCKDOWN_ENABLED > +#endif > + > +#if IS_ENABLED(CONFIG_SECURITY_SAFESETID) > +#define SAFESETID_ENABLED 1, > +#else > +#define SAFESETID_ENABLED > +#endif > + > +#if IS_ENABLED(CONFIG_BPF_LSM) > +#define BPF_LSM_ENABLED 1, > +#else > +#define BPF_LSM_ENABLED > +#endif > + > +#if IS_ENABLED(CONFIG_SECURITY_LANDLOCK) > +#define LANDLOCK_ENABLED 1, > +#else > +#define LANDLOCK_ENABLED > +#endif > + > +#if IS_ENABLED(CONFIG_IMA) > +#define IMA_ENABLED 1, > +#else > +#define IMA_ENABLED > +#endif > + > +#if IS_ENABLED(CONFIG_EVM) > +#define EVM_ENABLED 1, > +#else > +#define EVM_ENABLED > +#endif > + > +/* > + * There is a trailing comma that we need to be accounted for. This is done by > + * using a skipped argument in __COUNT_LSMS > + */ > +#define __COUNT_LSMS(skipped_arg, args...) COUNT_ARGS(args...) > +#define COUNT_LSMS(args...) __COUNT_LSMS(args) > + > +#define MAX_LSM_COUNT \ > + COUNT_LSMS( \ > + CAPABILITIES_ENABLED \ > + SELINUX_ENABLED \ > + SMACK_ENABLED \ > + APPARMOR_ENABLED \ > + TOMOYO_ENABLED \ > + YAMA_ENABLED \ > + LOADPIN_ENABLED \ > + LOCKDOWN_ENABLED \ > + SAFESETID_ENABLED \ > + BPF_LSM_ENABLED \ > + LANDLOCK_ENABLED \ > + IMA_ENABLED \ > + EVM_ENABLED) > + > +#else > + > +#define MAX_LSM_COUNT 0 > + > +#endif /* CONFIG_SECURITY */ > + > +#endif /* __LINUX_LSM_COUNT_H */