Message ID | 20230918212459.1937798-3-kpsingh@kernel.org (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Paul Moore |
Headers | show |
Series | Reduce overhead of LSMs with static calls | expand |
On Mon, Sep 18, 2023 at 11:24:56PM +0200, 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 (number of > possible LSMs * number of LSM hooks) which ends up being quite wasteful > especially when some LSMs are not compiled into the kernel. > > Suggested-by: Kui-Feng Lee <sinquersw@gmail.com> > Suggested-by: Andrii Nakryiko <andrii@kernel.org > Signed-off-by: KP Singh <kpsingh@kernel.org> I may extract this into a separate header in the future -- I have plans to make strscpy() take a variable number of arguments. ;) Regardless, for the LSM usage: Reviewed-by: Kees Cook <keescook@chromium.org>
On 9/18/2023 2:24 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 (number of > possible LSMs * number of LSM hooks) which ends up being quite wasteful > especially when some LSMs are not compiled into the kernel. > > Suggested-by: Kui-Feng Lee <sinquersw@gmail.com> > Suggested-by: Andrii Nakryiko <andrii@kernel.org > Signed-off-by: KP Singh <kpsingh@kernel.org> Much better than previous versions. Reviewed-by: Casey Schaufler <casey@schaufler-ca.com> > --- > include/linux/lsm_count.h | 106 ++++++++++++++++++++++++++++++++++++++ > 1 file changed, 106 insertions(+) > create mode 100644 include/linux/lsm_count.h > > diff --git a/include/linux/lsm_count.h b/include/linux/lsm_count.h > new file mode 100644 > index 000000000000..0c0ff3c7dddc > --- /dev/null > +++ b/include/linux/lsm_count.h > @@ -0,0 +1,106 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > + > +/* > + * Copyright (C) 2023 Google LLC. > + */ > + > +#ifndef __LINUX_LSM_COUNT_H > +#define __LINUX_LSM_COUNT_H > + > +#include <linux/kconfig.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_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 > + > + > +#define __COUNT_COMMAS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n > +#define COUNT_COMMAS(a, X...) __COUNT_COMMAS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) > +#define ___COUNT_COMMAS(args...) COUNT_COMMAS(args) > + > + > +#define MAX_LSM_COUNT \ > + ___COUNT_COMMAS( \ > + CAPABILITIES_ENABLED \ > + SELINUX_ENABLED \ > + SMACK_ENABLED \ > + APPARMOR_ENABLED \ > + TOMOYO_ENABLED \ > + YAMA_ENABLED \ > + LOADPIN_ENABLED \ > + LOCKDOWN_ENABLED \ > + BPF_LSM_ENABLED \ > + LANDLOCK_ENABLED) > + > +#else > + > +#define MAX_LSM_COUNT 0 > + > +#endif /* CONFIG_SECURITY */ > + > +#endif /* __LINUX_LSM_COUNT_H */
On 9/18/2023 2:24 PM, KP Singh wrote: > [...] > +#define __COUNT_COMMAS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n > +#define COUNT_COMMAS(a, X...) __COUNT_COMMAS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) > +#define ___COUNT_COMMAS(args...) COUNT_COMMAS(args) Oh! Oops, I missed that this _DOES_ already exist in Linux: cf14f27f82af ("macro: introduce COUNT_ARGS() macro") now in include/linux/args.h as COUNT_ARGS(): #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) I think this can be refactored to use that? -Kees
On Wed, Sep 20, 2023 at 9:24 PM Kees Cook <keescook@chromium.org> wrote: > > On 9/18/2023 2:24 PM, KP Singh wrote: > > [...] > > +#define __COUNT_COMMAS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n > > +#define COUNT_COMMAS(a, X...) __COUNT_COMMAS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) > > +#define ___COUNT_COMMAS(args...) COUNT_COMMAS(args) > > Oh! Oops, I missed that this _DOES_ already exist in Linux: > > cf14f27f82af ("macro: introduce COUNT_ARGS() macro") > > now in include/linux/args.h as COUNT_ARGS(): > > #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) > > I think this can be refactored to use that? Thanks, yeah I was able to do this with: diff --git a/include/linux/lsm_count.h b/include/linux/lsm_count.h index 0c0ff3c7dddc..969b6bf60718 100644 --- a/include/linux/lsm_count.h +++ b/include/linux/lsm_count.h @@ -7,7 +7,7 @@ #ifndef __LINUX_LSM_COUNT_H #define __LINUX_LSM_COUNT_H -#include <linux/kconfig.h> +#include <linux/args.h> #ifdef CONFIG_SECURITY @@ -79,13 +79,15 @@ #endif -#define __COUNT_COMMAS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) > -#define COUNT_COMMAS(a, X...) __COUNT_COMMAS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, > -#define ___COUNT_COMMAS(args...) COUNT_COMMAS(args) - +/* + * 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_COMMAS( \ + COUNT_LSMS( \ CAPABILITIES_ENABLED \ SELINUX_ENABLED \ SMACK_ENABLED \ > > -Kees > > -- > Kees Cook >
On 2023/09/19 6:24, 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. As a LKM-based LSM user, indirect function calls using a linked list have an advantage which this series kills. There always is a situation where a LSM cannot be built into vmlinux (and hence has to be loaded as a LKM-based LSM) due to distributor's support policy. Therefore, honestly speaking, I don't want LSM infrastructure to define the maximum number of "slots" or "static calls"... > > Without this one would need to generate static calls for (number of > possible LSMs * number of LSM hooks) which ends up being quite wasteful > especially when some LSMs are not compiled into the kernel. I can't interpret "number of possible LSMs * number of LSM hooks" part. Is this tokenized as "number of possible LSMs" (an integer) * (multipled by) "number of LSM hooks" (an integer) ? But the next patch includes struct lsm_static_calls_table { #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ struct lsm_static_call NAME[MAX_LSM_COUNT]; #include <linux/lsm_hook_defs.h> #undef LSM_HOOK } __randomize_layout; which seems to me that lsm_static_calls_table will get "number of possible LSMs" static calls for each LSM hook defined in linux/lsm_hook_defs.h . How did this patch help reducing static calls? What does "possible LSMs" mean? Should "number of possible LSMs" be replaced with "number of built-in LSMs" ? > Suggested-by: Andrii Nakryiko <andrii@kernel.org Trailing ">" is missing. > +/* > + * Macros to count the number of LSMs enabled in the kernel at compile time. > + */ > +#define MAX_LSM_COUNT \ > + ___COUNT_COMMAS( \ > + CAPABILITIES_ENABLED \ > + SELINUX_ENABLED \ > + SMACK_ENABLED \ > + APPARMOR_ENABLED \ > + TOMOYO_ENABLED \ > + YAMA_ENABLED \ > + LOADPIN_ENABLED \ > + LOCKDOWN_ENABLED \ > + BPF_LSM_ENABLED \ > + LANDLOCK_ENABLED) Since IS_ENABLED(CONFIG_FOO) is evaluated to either 1 or 0, why can't you directly do like IS_ENABLED(CONFIG_FOO) + IS_ENABLED(CONFIG_BAR) + IS_ENABLED(CONFIG_BUZ) ? If you can't do direct "+", can't you still do indirect "+" like something below? #if IS_ENABLED(CONFIG_FOO) #define FOO_ENABLED 1 #else #define FOO_ENABLED 0 #endif
On Thu, Sep 21, 2023 at 3:21 PM Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> wrote: > > On 2023/09/19 6:24, 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. > > As a LKM-based LSM user, indirect function calls using a linked list have > an advantage which this series kills. There always is a situation where a > LSM cannot be built into vmlinux (and hence has to be loaded as a LKM-based > LSM) due to distributor's support policy. Therefore, honestly speaking, > I don't want LSM infrastructure to define the maximum number of "slots" or > "static calls"... > Yeah, LSMs are not meant to be used from a kernel module. The data structure is actually __ro_after_init. So, I am not even sure how you are using it in kernel modules (unless you are patching this out). And, if you are really patching stuff to get your out of tree LSMs to work, then you might as well add your "custom" LSM config here or just override this count. The performance benefits here outweigh the need for a completely unsupported use case. > > > > Without this one would need to generate static calls for (number of > > possible LSMs * number of LSM hooks) which ends up being quite wasteful > > especially when some LSMs are not compiled into the kernel. > > I can't interpret "number of possible LSMs * number of LSM hooks" part. > Is this tokenized as "number of possible LSMs" (an integer) * (multipled by) > "number of LSM hooks" (an integer) ? But the next patch includes > > struct lsm_static_calls_table { > #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ > struct lsm_static_call NAME[MAX_LSM_COUNT]; > #include <linux/lsm_hook_defs.h> > #undef LSM_HOOK > } __randomize_layout; > > which seems to me that lsm_static_calls_table will get "number of possible > LSMs" static calls for each LSM hook defined in linux/lsm_hook_defs.h . > How did this patch help reducing static calls? What does "possible LSMs" mean? > Should "number of possible LSMs" be replaced with "number of built-in LSMs" ? > > > Suggested-by: Andrii Nakryiko <andrii@kernel.org > > Trailing ">" is missing. > > > +/* > > + * Macros to count the number of LSMs enabled in the kernel at compile time. > > + */ > > +#define MAX_LSM_COUNT \ > > + ___COUNT_COMMAS( \ > > + CAPABILITIES_ENABLED \ > > + SELINUX_ENABLED \ > > + SMACK_ENABLED \ > > + APPARMOR_ENABLED \ > > + TOMOYO_ENABLED \ > > + YAMA_ENABLED \ > > + LOADPIN_ENABLED \ > > + LOCKDOWN_ENABLED \ > > + BPF_LSM_ENABLED \ > > + LANDLOCK_ENABLED) > > Since IS_ENABLED(CONFIG_FOO) is evaluated to either 1 or 0, why can't you directly > do like IS_ENABLED(CONFIG_FOO) + IS_ENABLED(CONFIG_BAR) + IS_ENABLED(CONFIG_BUZ) ? You cannot do this because this is not evaluated in the preprocessor and is used to generate the variable names. If you have a working snippet of code, please share. > If you can't do direct "+", can't you still do indirect "+" like something below? > > #if IS_ENABLED(CONFIG_FOO) > #define FOO_ENABLED 1 > #else > #define FOO_ENABLED 0 > #endif How is this an indirect addition? I am not following. The end goal is that when the preprocessor runs MAX_LSM_COUNT is a constant number and not an expression like (1 + 1 + 1) if you have ideas please share the actual code. - KP >
On Thu, Sep 21, 2023 at 3:21 PM Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> wrote: > > On 2023/09/19 6:24, 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. > > As a LKM-based LSM user, indirect function calls using a linked list have > an advantage which this series kills. There always is a situation where a > LSM cannot be built into vmlinux (and hence has to be loaded as a LKM-based > LSM) due to distributor's support policy. Therefore, honestly speaking, > I don't want LSM infrastructure to define the maximum number of "slots" or > "static calls"... > > > > > Without this one would need to generate static calls for (number of > > possible LSMs * number of LSM hooks) which ends up being quite wasteful > > especially when some LSMs are not compiled into the kernel. > > I can't interpret "number of possible LSMs * number of LSM hooks" part. > Is this tokenized as "number of possible LSMs" (an integer) * (multipled by) > "number of LSM hooks" (an integer) ? But the next patch includes > The tokenization is in the name of the static call slots. you cannot have __SCT__lsm_static_call_bprm_check_security_1+1+1 it's not a valid name. You may want to build security/security.i to see what's going on (and actually try disabling some of the DEFINE_STATIC_CALL macros to reduce further expansion of macros. > struct lsm_static_calls_table { > #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ > struct lsm_static_call NAME[MAX_LSM_COUNT]; Each LSM that is compiled in the kernel can theoretically register a callback, so we add MAX_LSM_COUNT slots. Now the word "possible" because one may compile the LSM but not choose to enable it with the lsm= parameter. > #include <linux/lsm_hook_defs.h> > #undef LSM_HOOK > } __randomize_layout; > > which seems to me that lsm_static_calls_table will get "number of possible > LSMs" static calls for each LSM hook defined in linux/lsm_hook_defs.h . > How did this patch help reducing static calls? What does "possible LSMs" mean? If the kernel is compiled only with CONFIG_BPF_LSM, CONFIG_SELINUX and CONFIG_SECURITY (for capabilities) and not any other LSM, then one does not need to generate 12 slots for all each LSM hook when there are only 3 LSMs compiled in (capabilities being implicitly behind CONFIG_SECURITY). > Should "number of possible LSMs" be replaced with "number of built-in LSMs" ? Sure. I think "compiled LSMs" is a better word here. > > > Suggested-by: Andrii Nakryiko <andrii@kernel.org > > Trailing ">" is missing. Fixed. > > > +/* > > + * Macros to count the number of LSMs enabled in the kernel at compile time. > > + */ > > +#define MAX_LSM_COUNT \ > > + ___COUNT_COMMAS( \ > > + CAPABILITIES_ENABLED \ > > + SELINUX_ENABLED \ > > + SMACK_ENABLED \ > > + APPARMOR_ENABLED \ > > + TOMOYO_ENABLED \ > > + YAMA_ENABLED \ > > + LOADPIN_ENABLED \ > > + LOCKDOWN_ENABLED \ > > + BPF_LSM_ENABLED \ > > + LANDLOCK_ENABLED) > > Since IS_ENABLED(CONFIG_FOO) is evaluated to either 1 or 0, why can't you directly > do like IS_ENABLED(CONFIG_FOO) + IS_ENABLED(CONFIG_BAR) + IS_ENABLED(CONFIG_BUZ) ? > If you can't do direct "+", can't you still do indirect "+" like something below? > > #if IS_ENABLED(CONFIG_FOO) > #define FOO_ENABLED 1 > #else > #define FOO_ENABLED 0 > #endif >
On Thu, Sep 21, 2023 at 1:41 AM KP Singh <kpsingh@kernel.org> wrote: > > On Wed, Sep 20, 2023 at 9:24 PM Kees Cook <keescook@chromium.org> wrote: > > > > On 9/18/2023 2:24 PM, KP Singh wrote: > > > [...] > > > +#define __COUNT_COMMAS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n > > > +#define COUNT_COMMAS(a, X...) __COUNT_COMMAS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) > > > +#define ___COUNT_COMMAS(args...) COUNT_COMMAS(args) > > > > Oh! Oops, I missed that this _DOES_ already exist in Linux: > > > > cf14f27f82af ("macro: introduce COUNT_ARGS() macro") > > > > now in include/linux/args.h as COUNT_ARGS(): > > > > #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) > > > > I think this can be refactored to use that? Aha, I noticed the same thing when backporting the set to 6.4 for testing. (Some dependency of this set uses args.h). > > Thanks, yeah I was able to do this with: With this fixed: Acked-by: Song Liu <song@kernel.org> > > diff --git a/include/linux/lsm_count.h b/include/linux/lsm_count.h > index 0c0ff3c7dddc..969b6bf60718 100644 > --- a/include/linux/lsm_count.h > +++ b/include/linux/lsm_count.h > @@ -7,7 +7,7 @@ > #ifndef __LINUX_LSM_COUNT_H > #define __LINUX_LSM_COUNT_H > > -#include <linux/kconfig.h> > +#include <linux/args.h> > > #ifdef CONFIG_SECURITY > > @@ -79,13 +79,15 @@ > #endif > > > -#define __COUNT_COMMAS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, > _11, _12, _n, X...) > > -#define COUNT_COMMAS(a, X...) __COUNT_COMMAS(, ##X, 12, 11, 10, 9, 8, > 7, 6, 5, 4, 3, 2, > > -#define ___COUNT_COMMAS(args...) COUNT_COMMAS(args) > - > +/* > + * 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_COMMAS( \ > + COUNT_LSMS( \ > CAPABILITIES_ENABLED \ > SELINUX_ENABLED \ > SMACK_ENABLED \ > > > > > > > -Kees > > > > -- > > Kees Cook > >
On 2023/09/21 22:58, KP Singh wrote: > On Thu, Sep 21, 2023 at 3:21 PM Tetsuo Handa > <penguin-kernel@i-love.sakura.ne.jp> wrote: >> >> On 2023/09/19 6:24, 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. >> >> As a LKM-based LSM user, indirect function calls using a linked list have >> an advantage which this series kills. There always is a situation where a > > >> LSM cannot be built into vmlinux (and hence has to be loaded as a LKM-based >> LSM) due to distributor's support policy. Therefore, honestly speaking, >> I don't want LSM infrastructure to define the maximum number of "slots" or >> "static calls"... >> > > Yeah, LSMs are not meant to be used from a kernel module. The data > structure is actually __ro_after_init. So, I am not even sure how you > are using it in kernel modules (unless you are patching this out). > And, if you are really patching stuff to get your out of tree LSMs to > work, then you might as well add your "custom" LSM config here or just > override this count. I'm using LKM-based LSM with any version between 2.6.0 and 6.6-rc2, without patching __ro_after_init out. We can load LKM-based LSMs, without patching the original kernel. And it seems to me that several proprietary security products for Linux are using this trick, for LSMs for such products cannot be built into distributor's kernels... ---------- [ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-6.6.0-rc2+ root=/dev/sda1 ro vconsole.keymap=jp106 vconsole.font=latarcyrheb-sun16 security=none sysrq_always_enabled console=ttyS0,115200n8 console=tty0 LANG=en_US.UTF-8 init=/sbin/akari-init (...snipped...) [ 147.238458] AKARI: 1.0.48 2023/05/27 [ 147.244867] Access Keeping And Regulating Instrument registered. [ 147.261232] Calling /sbin/ccs-init to load policy. Please wait. 239 domains. 11807 ACL entries. 1938 KB used by policy. [ 147.768694] CCSecurity: 1.8.9 2021/04/01 [ 147.768740] Mandatory Access Control activated. ---------- > > The performance benefits here outweigh the need for a completely > unsupported use case. LKM-based LSMs are not officially supported since 2.6.24. But people need LKM-based LSMs. It is very sad that the LSM community is trying to lock out out of tree LSMs ( https://lkml.kernel.org/r/ec37cd2f-24ee-3273-c253-58d480569117@I-love.SAKURA.ne.jp ). The LSM interface is a common property for *all* Linux users. I'm not objecting the performance benefits by replacing with static calls. I'm not happy that the LSM community ignores the Torvald's comment at https://lkml.org/lkml/2007/10/1/192 and does not listen to minority's voices.
On Fri, Sep 22, 2023 at 1:25 PM Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> wrote: > > On 2023/09/21 22:58, KP Singh wrote: > > On Thu, Sep 21, 2023 at 3:21 PM Tetsuo Handa > > <penguin-kernel@i-love.sakura.ne.jp> wrote: > >> > >> On 2023/09/19 6:24, 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. > >> > >> As a LKM-based LSM user, indirect function calls using a linked list have > >> an advantage which this series kills. There always is a situation where a > > > > > >> LSM cannot be built into vmlinux (and hence has to be loaded as a LKM-based > >> LSM) due to distributor's support policy. Therefore, honestly speaking, > >> I don't want LSM infrastructure to define the maximum number of "slots" or > >> "static calls"... > >> > > > > Yeah, LSMs are not meant to be used from a kernel module. The data > > structure is actually __ro_after_init. So, I am not even sure how you > > are using it in kernel modules (unless you are patching this out). > > And, if you are really patching stuff to get your out of tree LSMs to > > work, then you might as well add your "custom" LSM config here or just > > override this count. > > I'm using LKM-based LSM with any version between 2.6.0 and 6.6-rc2, without patching > __ro_after_init out. We can load LKM-based LSMs, without patching the original kernel. Then __ro_after_init is broken in your tree and you are missing some patches. > And it seems to me that several proprietary security products for Linux are using > this trick, for LSMs for such products cannot be built into distributor's kernels... > > ---------- > [ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-6.6.0-rc2+ root=/dev/sda1 ro vconsole.keymap=jp106 vconsole.font=latarcyrheb-sun16 security=none sysrq_always_enabled console=ttyS0,115200n8 console=tty0 LANG=en_US.UTF-8 init=/sbin/akari-init > (...snipped...) > [ 147.238458] AKARI: 1.0.48 2023/05/27 > [ 147.244867] Access Keeping And Regulating Instrument registered. > [ 147.261232] Calling /sbin/ccs-init to load policy. Please wait. > 239 domains. 11807 ACL entries. > 1938 KB used by policy. > [ 147.768694] CCSecurity: 1.8.9 2021/04/01 > [ 147.768740] Mandatory Access Control activated. > ---------- > > > > > The performance benefits here outweigh the need for a completely > > unsupported use case. > > LKM-based LSMs are not officially supported since 2.6.24. But people need LKM-based LSMs. > It is very sad that the LSM community is trying to lock out out of tree LSMs > ( https://lkml.kernel.org/r/ec37cd2f-24ee-3273-c253-58d480569117@I-love.SAKURA.ne.jp ). > The LSM interface is a common property for *all* Linux users. Again, I don't understand how this locks out out-of-tree LSMs. One can go and patch static calls the same way one hacked around by directly adding stuff to the security_hook_heads. I am not going to suggest any hacks here but there are pretty obvious solutions out there.; My recommendation would be to use BPF LSM for any custom MAC policy logic. That's the whole goal of the BPF LSM is to safely enable these use cases without relying on LSM internals and hacks. - KP > > I'm not objecting the performance benefits by replacing with static calls. > I'm not happy that the LSM community ignores the Torvald's comment at https://lkml.org/lkml/2007/10/1/192 > and does not listen to minority's voices. >
On Fri, Sep 22, 2023 at 7:25 AM Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> wrote: > On 2023/09/21 22:58, KP Singh wrote: > > Yeah, LSMs are not meant to be used from a kernel module. The data > > structure is actually __ro_after_init. So, I am not even sure how you > > are using it in kernel modules (unless you are patching this out). > > And, if you are really patching stuff to get your out of tree LSMs to > > work, then you might as well add your "custom" LSM config here or just > > override this count. > > I'm using LKM-based LSM with any version between 2.6.0 and 6.6-rc2, without patching > __ro_after_init out. We can load LKM-based LSMs, without patching the original kernel. > And it seems to me that several proprietary security products for Linux are using > this trick, for LSMs for such products cannot be built into distributor's kernels... ... > > The performance benefits here outweigh the need for a completely > > unsupported use case. > > LKM-based LSMs are not officially supported since 2.6.24. But people need LKM-based LSMs. > It is very sad that the LSM community is trying to lock out out of tree LSMs > ( https://lkml.kernel.org/r/ec37cd2f-24ee-3273-c253-58d480569117@I-love.SAKURA.ne.jp ). > The LSM interface is a common property for *all* Linux users. > > I'm not objecting the performance benefits by replacing with static calls. > I'm not happy that the LSM community ignores the Torvald's comment at https://lkml.org/lkml/2007/10/1/192 > and does not listen to minority's voices. Despite a previous comment that I was done engaging with Tetsuo on this topic, I feel it is worth commenting here as there are a number of people on the To/CC line that have likely not been following the related discussion threads on the LSM list. First and foremost I want to reiterate that the LSM community's first priority are those LSMs which have been accepted and merged into the upstream Linux kernel. While I have no intention, or desire, to harm out-of-tree LSMs, I stand firm that we should not compromise designs for in-tree LSMs/functionality solely to benefit out-of-tree LSMs. I believe this is consistent, or at least compatible, with the general Linux kernel community's stance on in-tree vs out-of-tree code. The (relatively) newly proposed LSM syscalls have proven to be a contentious topic between Tetsuo and the LSM community as a whole; I won't rehash the arguments here, as they are all available on lore.kernel.org (simply look for any threads that Tetsuo has been involved in over the past several months) but we have discussed this issue at great length and Tetsuo remains the only opposing opinion. It was my hope that Tetsuo would respect the opinion of the upstream LSM community, even if he didn't agree with the details. After all, this is how we move forward in cases where differing opinions cannot all be accommodated in the code. Unfortunately Tetsuo's continued and stubborn refusal to accept the majority opinion has started to spill into other discussion threads, disrupting the discussion there and twisting some of the core issues to better fit his arguments. Not only is this frustrating, it is becoming rather disruptive. My suggestion is to simply follow some classic Internet advice and "don't feed the trolls". As we discussed off-list (and in-person!) this week, I am generally supportive of work that improves performance, but correctness will always be my priority with maintainability a close second. We have a few more pressing issues at the LSM layer which are demanding my time at the moment, but I do promise to come back to this issue/patchset as these other high priority issues are resolved. Thanks for your patience and understanding KP :)
On 2023/09/22 23:45, KP Singh wrote: >> I'm using LKM-based LSM with any version between 2.6.0 and 6.6-rc2, without patching >> __ro_after_init out. We can load LKM-based LSMs, without patching the original kernel. > > Then __ro_after_init is broken in your tree and you are missing some patches. This fact applies to vanilla upstream kernel tree; __ro_after_init is not broken and some patches are not missing. See https://akari.osdn.jp/1.0/chapter-3.html.en for details. >>> >>> The performance benefits here outweigh the need for a completely >>> unsupported use case. >> >> LKM-based LSMs are not officially supported since 2.6.24. But people need LKM-based LSMs. >> It is very sad that the LSM community is trying to lock out out of tree LSMs >> ( https://lkml.kernel.org/r/ec37cd2f-24ee-3273-c253-58d480569117@I-love.SAKURA.ne.jp ). >> The LSM interface is a common property for *all* Linux users. > > Again, I don't understand how this locks out out-of-tree LSMs. One can > go and patch static calls the same way one hacked around by directly > adding stuff to the security_hook_heads. I am not going to suggest any > hacks here but there are pretty obvious solutions out there.; The change that locks out out-of-tree LSMs (regardless of whether that LSM is LKM-based LSM or not) is a series including "[PATCH v15 01/11] LSM: Identify modules by more than name". I was not pushing LKM-based LSM because the LSM community wanted to make it possible to enable arbitrary combinations (e.g. enabling selinux and smack at the same time) before making it possible to use LKM-based LSMs. According to https://marc.info/?l=linux-security-module&m=123232076329805 (Jan 2009), Casey said that "SELinux and Smack should never be stacked in the same kernel.". I'm personally wondering how many users will enable selinux and smack at the same time. But in that post, Casey also said "You could revive the notion of loadable modules while you're at it." while implementing LSM Multiplexer LSM. According to https://marc.info/?l=linux-security-module&m=133055410107878 (Feb 2012), Casey said that support for multiple concurrent LSMs should be able to handle loadable/unloadable LSMs. The reason for removing unload support was that no in-tree users needed it, and out of tree use-cases are generally not supported in mainline. That is, when the LSM interface became static, the LSM community was not seeing the reality. I don't think that rmmod support for LKM-based LSMs is needed, but I believe that insmod support for LKM-based LSMs is needed. According to https://lkml.kernel.org/r/50ABE354.1040407@schaufler-ca.com (Nov 2012), Casey said that reintroducing LSMs as loadable modules is a work for another day and a separate battle to fight. These postings (just picked up from LSM mailing list archives matching keyword "loadable" and sent from Casey) indicate that the LSM community was not making changes that forever makes LKM-based LSMs impossible. Finally, pasting Casey's message (Feb 2016) here (because the archive did not find this post): From: Casey Schaufler <casey@schaufler-ca.com> Subject: Re: LSM as a kernel module Date: Mon, 22 Feb 2016 10:17:26 -0800 Message-ID: <56CB50B6.6060702@schaufler-ca.com> To: Roman Kubiak <r.kubiak@samsung.com>, linux-security-module@vger.kernel.org On 2/22/2016 5:37 AM, Roman Kubiak wrote: > I just wanted to make sure that it's not possible and is not planned in the future > to have LSM modules loaded as .ko kernel modules. Is that true for now and the far/near future ? > > best regards Tetsuo Handa is holding out hope for loadable security modules*. The work I've been doing on module stacking does not include support for loadable modules, but I've committed to not making it impossible. There has never really been a major issue with loading a security module, although there are a host of minor ones. The big problem is unloading the module and cleaning up properly. Near term I believe that you can count on not having to worry about dynamically loadable security modules. At some point in the future we may have an important use case, but I don't see that until before some time in the 20s. So now I'm curious. What are you up to that would be spoiled by loadable security modules? --- * The original name for the infrastructure was indeed "Loadable Security Modules". The memory management and security policy implications resulted in steadily diminishing support for any sort of dynamic configuration. It wasn't long before "Loadable" became "Linux". But while I was waiting for "make it possible to enable arbitrary combinations" change, the LSM community started making changes (such as defining the maximum number of "slots" or "static calls" based on all LSMs are built into vmlinux) that violate Casey's promise. As a reminder to tell that I still want to make LKM-based LSM officially supported again, I'm responding to changes (like this patch) that are based on "any LSM must be built into vmlinux". Please be careful not to make changes that forever make LKM-based LSMs impossible. > > My recommendation would be to use BPF LSM for any custom MAC policy > logic. That's the whole goal of the BPF LSM is to safely enable these > use cases without relying on LSM internals and hacks. I'm fine if you can reimplement TOMOYO (or AKARI or CaitSith) using BPF LSM. Since BPF has many limitations, not every custom MAC policy can be implemented using BPF. The need to insmod LKM-based LSMs will remain because the LSM community will not accept whatever LSMs (that are publicly available) and the Linux distributors will not build whatever LSMs (that are publicly available) into their vmlinux. But "LSM: Identify modules by more than name" is the worst change because that change locks out any publicly available out of tree LSMs, far away from allowing LKM-based LSMs.
On Sat, Sep 23, 2023 at 8:57 AM Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> wrote: > > On 2023/09/22 23:45, KP Singh wrote: > >> I'm using LKM-based LSM with any version between 2.6.0 and 6.6-rc2, without patching > >> __ro_after_init out. We can load LKM-based LSMs, without patching the original kernel. > > > > Then __ro_after_init is broken in your tree and you are missing some patches. > > This fact applies to vanilla upstream kernel tree; __ro_after_init is not broken and > some patches are not missing. See https://akari.osdn.jp/1.0/chapter-3.html.en for details. > You are trying to use an unexported symbol from the module with lots of hackery to write to be supported and bring it up in a discussion? Good luck! Regardless, if what you are doing really works after https://lore.kernel.org/all/20200107133154.588958-1-omosnace@redhat.com, then we need to fix this as the security_hook_heads should be immutable after boot. I tried a build where the symbols are exported and sure enough the module is unable to write to it. So, either your kernel has the old CONFIG_SECURITY_HOOKS_WRITABLE, or it should ideally fail with something like: [ 23.990387] kernel tried to execute NX-protected page - exploit attempt? (uid: 0) [ 23.996796] BUG: unable to handle page fault for address: ffffffff83adf270 [ 23.997433] #PF: supervisor instruction fetch in kernel mode [ 23.997936] #PF: error_code(0x0011) - permissions violation [ 23.998416] PGD 3247067 P4D 3247067 PUD 3248063 PMD 100b9e063 PTE 8000000003adf163 [ 23.999069] Oops: 0011 [#1] PREEMPT SMP NOPTI [ 23.999445] CPU: 0 PID: 302 Comm: insmod Tainted: G O 6.6.0-rc2-next-20230921-dirty #13 [ 24.000230] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 [ 24.001024] RIP: 0010:security_add_hooks+0x0/0xa0 If this is not happening, then it's a bug and you chose to report it. > > > >>> > >>> The performance benefits here outweigh the need for a completely > >>> unsupported use case. > >> > >> LKM-based LSMs are not officially supported since 2.6.24. But people need LKM-based LSMs. > >> It is very sad that the LSM community is trying to lock out out of tree LSMs > >> ( https://lkml.kernel.org/r/ec37cd2f-24ee-3273-c253-58d480569117@I-love.SAKURA.ne.jp ). > >> The LSM interface is a common property for *all* Linux users. > > > > Again, I don't understand how this locks out out-of-tree LSMs. One can > > go and patch static calls the same way one hacked around by directly > > adding stuff to the security_hook_heads. I am not going to suggest any > > hacks here but there are pretty obvious solutions out there.; > > The change that locks out out-of-tree LSMs (regardless of whether that LSM is LKM-based LSM > or not) is a series including "[PATCH v15 01/11] LSM: Identify modules by more than name". This does not belong here, please stop cross posting stuff. > > I was not pushing LKM-based LSM because the LSM community wanted to make it possible to > enable arbitrary combinations (e.g. enabling selinux and smack at the same time) before > making it possible to use LKM-based LSMs. > > According to https://marc.info/?l=linux-security-module&m=123232076329805 (Jan 2009), > Casey said that "SELinux and Smack should never be stacked in the same kernel.". > I'm personally wondering how many users will enable selinux and smack at the same time. > But in that post, Casey also said "You could revive the notion of loadable modules > while you're at it." while implementing LSM Multiplexer LSM. > > According to https://marc.info/?l=linux-security-module&m=133055410107878 (Feb 2012), > Casey said that support for multiple concurrent LSMs should be able to handle > loadable/unloadable LSMs. > The reason for removing unload support was that no in-tree users needed it, and > out of tree use-cases are generally not supported in mainline. That is, when the > LSM interface became static, the LSM community was not seeing the reality. > I don't think that rmmod support for LKM-based LSMs is needed, but I believe that > insmod support for LKM-based LSMs is needed. > > According to https://lkml.kernel.org/r/50ABE354.1040407@schaufler-ca.com (Nov 2012), > Casey said that reintroducing LSMs as loadable modules is a work for another day > and a separate battle to fight. > > These postings (just picked up from LSM mailing list archives matching keyword "loadable" > and sent from Casey) indicate that the LSM community was not making changes that forever > makes LKM-based LSMs impossible. > > Finally, pasting Casey's message (Feb 2016) here (because the archive did not find this post): > > From: Casey Schaufler <casey@schaufler-ca.com> > Subject: Re: LSM as a kernel module > Date: Mon, 22 Feb 2016 10:17:26 -0800 > Message-ID: <56CB50B6.6060702@schaufler-ca.com> > To: Roman Kubiak <r.kubiak@samsung.com>, linux-security-module@vger.kernel.org > > On 2/22/2016 5:37 AM, Roman Kubiak wrote: > > I just wanted to make sure that it's not possible and is not planned in the future > > to have LSM modules loaded as .ko kernel modules. Is that true for now and the far/near future ? > > > > best regards > > Tetsuo Handa is holding out hope for loadable security modules*. > The work I've been doing on module stacking does not include > support for loadable modules, but I've committed to not making > it impossible. There has never really been a major issue with > loading a security module, although there are a host of minor > ones. The big problem is unloading the module and cleaning up > properly. > > Near term I believe that you can count on not having to worry > about dynamically loadable security modules. At some point in > the future we may have an important use case, but I don't see > that until before some time in the 20s. > > So now I'm curious. What are you up to that would be spoiled > by loadable security modules? > > > --- > * The original name for the infrastructure was indeed > "Loadable Security Modules". The memory management and > security policy implications resulted in steadily > diminishing support for any sort of dynamic configuration. > It wasn't long before "Loadable" became "Linux". > > But while I was waiting for "make it possible to enable arbitrary combinations" change, > the LSM community started making changes (such as defining the maximum number of "slots" > or "static calls" based on all LSMs are built into vmlinux) that violate Casey's promise. > > As a reminder to tell that I still want to make LKM-based LSM officially supported again, > I'm responding to changes (like this patch) that are based on "any LSM must be built into > vmlinux". Please be careful not to make changes that forever make LKM-based LSMs impossible. > > > > > > > My recommendation would be to use BPF LSM for any custom MAC policy > > logic. That's the whole goal of the BPF LSM is to safely enable these > > use cases without relying on LSM internals and hacks. > > I'm fine if you can reimplement TOMOYO (or AKARI or CaitSith) using BPF LSM. > Since BPF has many limitations, not every custom MAC policy can be implemented using BPF. Please stop making generic statements, either be explicit about your understanding of the limitations or don't claim them without evidence. - KP > > The need to insmod LKM-based LSMs will remain because the LSM community will not accept > whatever LSMs (that are publicly available) and the Linux distributors will not build > whatever LSMs (that are publicly available) into their vmlinux. > > But "LSM: Identify modules by more than name" is the worst change because that change > locks out any publicly available out of tree LSMs, far away from allowing LKM-based LSMs. >
On Fri, Sep 22, 2023 at 4:57 PM Paul Moore <paul@paul-moore.com> wrote: > > On Fri, Sep 22, 2023 at 7:25 AM Tetsuo Handa > <penguin-kernel@i-love.sakura.ne.jp> wrote: > > On 2023/09/21 22:58, KP Singh wrote: > > > Yeah, LSMs are not meant to be used from a kernel module. The data > > > structure is actually __ro_after_init. So, I am not even sure how you > > > are using it in kernel modules (unless you are patching this out). > > > And, if you are really patching stuff to get your out of tree LSMs to > > > work, then you might as well add your "custom" LSM config here or just > > > override this count. > > > > I'm using LKM-based LSM with any version between 2.6.0 and 6.6-rc2, without patching > > __ro_after_init out. We can load LKM-based LSMs, without patching the original kernel. > > And it seems to me that several proprietary security products for Linux are using > > this trick, for LSMs for such products cannot be built into distributor's kernels... > > ... > > > > The performance benefits here outweigh the need for a completely > > > unsupported use case. > > > > LKM-based LSMs are not officially supported since 2.6.24. But people need LKM-based LSMs. > > It is very sad that the LSM community is trying to lock out out of tree LSMs > > ( https://lkml.kernel.org/r/ec37cd2f-24ee-3273-c253-58d480569117@I-love.SAKURA.ne.jp ). > > The LSM interface is a common property for *all* Linux users. > > > > I'm not objecting the performance benefits by replacing with static calls. > > I'm not happy that the LSM community ignores the Torvald's comment at https://lkml.org/lkml/2007/10/1/192 > > and does not listen to minority's voices. > > Despite a previous comment that I was done engaging with Tetsuo on > this topic, I feel it is worth commenting here as there are a number > of people on the To/CC line that have likely not been following the > related discussion threads on the LSM list. > > First and foremost I want to reiterate that the LSM community's first > priority are those LSMs which have been accepted and merged into the > upstream Linux kernel. While I have no intention, or desire, to harm > out-of-tree LSMs, I stand firm that we should not compromise designs > for in-tree LSMs/functionality solely to benefit out-of-tree LSMs. I > believe this is consistent, or at least compatible, with the general > Linux kernel community's stance on in-tree vs out-of-tree code. > > The (relatively) newly proposed LSM syscalls have proven to be a > contentious topic between Tetsuo and the LSM community as a whole; I > won't rehash the arguments here, as they are all available on > lore.kernel.org (simply look for any threads that Tetsuo has been > involved in over the past several months) but we have discussed this > issue at great length and Tetsuo remains the only opposing opinion. > It was my hope that Tetsuo would respect the opinion of the upstream > LSM community, even if he didn't agree with the details. After all, > this is how we move forward in cases where differing opinions cannot > all be accommodated in the code. > > Unfortunately Tetsuo's continued and stubborn refusal to accept the > majority opinion has started to spill into other discussion threads, > disrupting the discussion there and twisting some of the core issues > to better fit his arguments. Not only is this frustrating, it is > becoming rather disruptive. My suggestion is to simply follow some > classic Internet advice and "don't feed the trolls". > > As we discussed off-list (and in-person!) this week, I am generally > supportive of work that improves performance, but correctness will > always be my priority with maintainability a close second. We have a > few more pressing issues at the LSM layer which are demanding my time > at the moment, but I do promise to come back to this issue/patchset as > these other high priority issues are resolved. > > Thanks for your patience and understanding KP :) Thank you for the context Paul, this explains a lot! > > -- > paul-moore.com
On 9/22/2023 11:56 PM, Tetsuo Handa wrote: > ... > The change that locks out out-of-tree LSMs (regardless of whether that LSM is LKM-based LSM > or not) is a series including "[PATCH v15 01/11] LSM: Identify modules by more than name". Please supply patches for your implementation of loadable security modules. This will provide a base from which we can work out what needs changed to accommodate your needs. I have more than 20 years worth of projects that I hope to get to before I would even start to work on loadable security modules.
On 2023/09/24 1:06, KP Singh wrote: >> I was not pushing LKM-based LSM because the LSM community wanted to make it possible to >> enable arbitrary combinations (e.g. enabling selinux and smack at the same time) before >> making it possible to use LKM-based LSMs. (...snipped...) >> As a reminder to tell that I still want to make LKM-based LSM officially supported again, >> I'm responding to changes (like this patch) that are based on "any LSM must be built into >> vmlinux". Please be careful not to make changes that forever make LKM-based LSMs impossible. You did not recognize the core chunk of this post. :-( It is Casey's commitment that the LSM infrastructure will not forbid LKM-based LSMs. We will start allowing LKM-based LSMs. But it is not clear how we can make it possible to allow LKM-based LSMs. Suppose you replace the linked list (which does not need to limit number of LSMs activated) with static calls (which limits number of LSMs activated, due to use of compile-time determined MAX_LSM_COUNT value at struct lsm_static_calls_table { #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ struct lsm_static_call NAME[MAX_LSM_COUNT]; #include <linux/lsm_hook_defs.h> #undef LSM_HOOK } __randomize_layout; . If NAME[MAX_LSM_COUNT] were allocated like NAME = kcalloc(sizeof(struct lsm_static_call), number_of_max_lsms_to_activate, GFP_KERNEL | __GFP_NOFAIL); (where number_of_max_lsms_to_activate is controlled using kernel command line parameter) rater than struct lsm_static_call NAME[MAX_LSM_COUNT]; , it is easy to allow LKM-based LSMs. But if NAME[MAX_LSM_COUNT] is allocated in a way which cannot be expanded using kernel command line parameter (this is what "[PATCH v3 2/5] security: Count the LSMs enabled at compile time" does), how can the LKM-based LSMs be registered? Introduce a LSM module which revives the linked list and registration function (which this patch tried to remove) ? If yes, do we want to use #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ for built-in LSMs and a different macro for LKM-based LSMs? Do we want/agree to manage two different set of macros/functions only for handling both built-in LSMs and loadable LSMs? That's a lot of complication, compared to temporarily making the security_hook_heads writable. > You are trying to use an unexported symbol from the module with lots > of hackery to write to be supported and bring it up in a discussion? > Good luck! Currently LKM-based LSMs is not officially supported. But LKM-based LSMs will become officially supported in the future. Therefore, I respond to any attempt which tries to make LKM-based LSMs impossible. > > Regardless, if what you are doing really works after > https://lore.kernel.org/all/20200107133154.588958-1-omosnace@redhat.com, > then we need to fix this as the security_hook_heads should be > immutable after boot. You should learn how the __ro_after_init works. I will throw NACK if someone tries to add an exception to __ro_after_init handling before we make it possible to allow LKM-based LSMs.
On Mon, Sep 25, 2023 at 1:03 PM Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> wrote: > > On 2023/09/24 1:06, KP Singh wrote: > >> I was not pushing LKM-based LSM because the LSM community wanted to make it possible to > >> enable arbitrary combinations (e.g. enabling selinux and smack at the same time) before > >> making it possible to use LKM-based LSMs. > (...snipped...) > >> As a reminder to tell that I still want to make LKM-based LSM officially supported again, > >> I'm responding to changes (like this patch) that are based on "any LSM must be built into > >> vmlinux". Please be careful not to make changes that forever make LKM-based LSMs impossible. > > You did not recognize the core chunk of this post. :-( > > It is Casey's commitment that the LSM infrastructure will not forbid LKM-based LSMs. > We will start allowing LKM-based LSMs. But it is not clear how we can make it possible to > allow LKM-based LSMs. I think this needs to be discussed if and when we allow LKM based LSMs. > > Suppose you replace the linked list (which does not need to limit number of LSMs activated) > with static calls (which limits number of LSMs activated, due to use of compile-time determined > MAX_LSM_COUNT value at > > struct lsm_static_calls_table { > #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ > struct lsm_static_call NAME[MAX_LSM_COUNT]; > #include <linux/lsm_hook_defs.h> > #undef LSM_HOOK > } __randomize_layout; > > . If NAME[MAX_LSM_COUNT] were allocated like > > NAME = kcalloc(sizeof(struct lsm_static_call), number_of_max_lsms_to_activate, GFP_KERNEL | __GFP_NOFAIL); > > (where number_of_max_lsms_to_activate is controlled using kernel command line parameter) > rater than > > struct lsm_static_call NAME[MAX_LSM_COUNT]; > > , it is easy to allow LKM-based LSMs. > One needs to know MAX_LSM_COUNT at compile time (not via kernel command line), I really suggest you try out your suggestions before posting them. I had explained this to you earlier, you still chose to ignore and keep suggesting stuff that does not work. https://lore.kernel.org/bpf/CACYkzJ7Dn=W1Kd5M_bXOzoomzdjMXBoEZZo5k=cgQ4R6f5G+vw@mail.gmail.com/ It is used in the preprocessor to generate the static calls, it cannot come from the command line. > But if NAME[MAX_LSM_COUNT] is allocated in a way which cannot be expanded using kernel > command line parameter (this is what "[PATCH v3 2/5] security: Count the LSMs enabled > at compile time" does), how can the LKM-based LSMs be registered? Introduce a LSM module > which revives the linked list and registration function (which this patch tried to remove) ? > If yes, do we want to use > > #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ > > for built-in LSMs and a different macro for LKM-based LSMs? > > Do we want/agree to manage two different set of macros/functions only for handling > both built-in LSMs and loadable LSMs? We will see when this happens. I don't think it's a difficult problem and there are many ways to implement this: * Add a new slot(s) for modular LSMs (One can add up to N fast modular LSMs) * Fallback to a linked list for modular LSMs, that's not a complexity. There are serious performance gains and I think it's a fair trade-off. This isn't even complex. Now, this patch and the patch that makes security_hook_heads __ro_after_init by removing CONFIG_SECURITY_HOOKS_WRITABLE breaks your hack. But that hack (https://akari.osdn.jp/1.0/chapter-3.html.en) is unsupported. > > That's a lot of complication, compared to temporarily making the security_hook_heads writable. No, that's not complicated. All I can say is, when the time comes, and if the community agrees on LMK based modules, this patch won't make it any difficult or easy. There are many implementations, even this patch, that can provide LKM based LSMs API (but hacks will be hard, sure!) - KP > > > > > You are trying to use an unexported symbol from the module with lots > > of hackery to write to be supported and bring it up in a discussion? > > Good luck! > > Currently LKM-based LSMs is not officially supported. But LKM-based LSMs will become > officially supported in the future. Therefore, I respond to any attempt which tries > to make LKM-based LSMs impossible. > > > > > Regardless, if what you are doing really works after > > https://lore.kernel.org/all/20200107133154.588958-1-omosnace@redhat.com, > > then we need to fix this as the security_hook_heads should be > > immutable after boot. > > You should learn how the __ro_after_init works. I will throw NACK if someone tries > to add an exception to __ro_after_init handling before we make it possible to allow > LKM-based LSMs. >
On 9/25/2023 4:03 AM, Tetsuo Handa wrote: > On 2023/09/24 1:06, KP Singh wrote: >>> I was not pushing LKM-based LSM because the LSM community wanted to make it possible to >>> enable arbitrary combinations (e.g. enabling selinux and smack at the same time) before >>> making it possible to use LKM-based LSMs. > (...snipped...) >>> As a reminder to tell that I still want to make LKM-based LSM officially supported again, >>> I'm responding to changes (like this patch) that are based on "any LSM must be built into >>> vmlinux". Please be careful not to make changes that forever make LKM-based LSMs impossible. > You did not recognize the core chunk of this post. :-( > > It is Casey's commitment that the LSM infrastructure will not forbid LKM-based LSMs. ... And this code doesn't. I you want LKM based LSM support I suggest you provide patches. If there is anything in the LSM infrastructure that you can't work around I'll help work out how to do it. But I am not going to do it for you, and I don't think anyone else is inclined to, either.
On 2023/09/25 20:22, KP Singh wrote: >> It is Casey's commitment that the LSM infrastructure will not forbid LKM-based LSMs. >> We will start allowing LKM-based LSMs. But it is not clear how we can make it possible to >> allow LKM-based LSMs. > > I think this needs to be discussed if and when we allow LKM based LSMs. It is *now* (i.e. before your proposal is accepted) that we need to discuss. > One needs to know MAX_LSM_COUNT at compile time (not via kernel > command line), I really suggest you try out your suggestions before > posting them. I had explained this to you earlier, you still chose to > ignore and keep suggesting stuff that does not work. Your proposal needs to know MAX_LSM_COUNT at compile time, that's why we need to discuss now. > We will see when this happens. I don't think it's a difficult problem > and there are many ways to implement this: > > * Add a new slot(s) for modular LSMs (One can add up to N fast modular LSMs) > * Fallback to a linked list for modular LSMs, that's not a complexity. > There are serious performance gains and I think it's a fair trade-off. > This isn't even complex. That won't help at all. You became so blind because what you want to use (i.e. SELinux and BPF) are already supported by Linux distributors. The reason I'm insisting on supporting LKM-based LSMs is that Linux distributors cannot afford supporting minor LSMs. Dave Chinner said Downstream distros support all sorts of out of tree filesystems loaded via kernel modules at https://lkml.kernel.org/r/ZQo94mCzV7hOrVkh@dread.disaster.area , and e.g. antivirus software vendors use out of tree filesystems loaded via kernel modules (because neither the upstream kernel community nor the Linux distributors can afford supporting out of tree filesystems used by antivirus software vendors). If Linux distributors decide "we don't allow loading out of tree filesystems via kernel modules because we can't support", that's the end of the world for such filesystems. What I'm saying is nothing but s/filesystem/LSM/g . If Linux distributors decide "we don't allow loading out of tree LSMs via kernel modules because we can't support", that's the end of the world for LKM-based LSMs. The mechanism which makes LKM-based LSMs possible must not be disabled by the person/organization who builds the vmlinux. You might still say that "You can build your vmlinux and distribute it", but that is also impossible in practice. Some device drivers are meant to be loaded for Linux distribution's prebuilt kernels. Also, debuginfo package is needed for analyzing vmcore. Building vmlinux and distributing it is not practical without becoming a well-known Linux distributors enough to get out-of-tree device drivers being prebuilt (such as Red Hat). Again, you are so blind. > Now, this patch and the patch that makes security_hook_heads > __ro_after_init by removing CONFIG_SECURITY_HOOKS_WRITABLE breaks your > hack. Like I demonstrated at https://lkml.kernel.org/r/cc8e16bb-5083-01da-4a77-d251a76dc8ff@I-love.SAKURA.ne.jp , removing CONFIG_SECURITY_HOOKS_WRITABLE does not break my hack.
On Sun, Oct 1, 2023 at 12:51 PM Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> wrote: > > On 2023/09/25 20:22, KP Singh wrote: > >> It is Casey's commitment that the LSM infrastructure will not forbid LKM-based LSMs. > >> We will start allowing LKM-based LSMs. But it is not clear how we can make it possible to > >> allow LKM-based LSMs. > > > > I think this needs to be discussed if and when we allow LKM based LSMs. > > It is *now* (i.e. before your proposal is accepted) that we need to discuss. > > > One needs to know MAX_LSM_COUNT at compile time (not via kernel > > command line), I really suggest you try out your suggestions before > > posting them. I had explained this to you earlier, you still chose to > > ignore and keep suggesting stuff that does not work. > > Your proposal needs to know MAX_LSM_COUNT at compile time, that's why > we need to discuss now. People already mention that you seem to deliberately ignore advice given to you and continue with your own narrative. Here's my last attempt to explain things to you: You are conflating two use cases, built-in out-of-tree LSMS and modular LSMs. However, the proposed changes block neither of the use cases. * For modules that are out-of-tree but compiled into the kernel, they can just modify the MAX_LSM_COUNT * For dynamically loadable LSMs, you anyways want a separate security_hook_heads. The __ro_after_init should not be relaxed on the existing security_hook_heads to prevent any memory corruption from overriding LSM callbacks, this lowers the existing security posture. And then, in the call_int_hook and security_for_each_hook you can iterate over both the static call slots. ^^ I said the above multiple times but you ignored all of it! - KP > > > We will see when this happens. I don't think it's a difficult problem > > and there are many ways to implement this: > > > > * Add a new slot(s) for modular LSMs (One can add up to N fast modular LSMs) > > * Fallback to a linked list for modular LSMs, that's not a complexity. > > There are serious performance gains and I think it's a fair trade-off. > > This isn't even complex. > > That won't help at all. You became so blind because what you want to use (i.e. > SELinux and BPF) are already supported by Linux distributors. The reason I'm > insisting on supporting LKM-based LSMs is that Linux distributors cannot afford > supporting minor LSMs. > > Dave Chinner said > > Downstream distros support all sorts of out of tree filesystems loaded > via kernel modules > > at https://lkml.kernel.org/r/ZQo94mCzV7hOrVkh@dread.disaster.area , and e.g. > antivirus software vendors use out of tree filesystems loaded via kernel > modules (because neither the upstream kernel community nor the Linux distributors > can afford supporting out of tree filesystems used by antivirus software vendors). > > If Linux distributors decide "we don't allow loading out of tree filesystems > via kernel modules because we can't support", that's the end of the world for > such filesystems. > > What I'm saying is nothing but s/filesystem/LSM/g . > If Linux distributors decide "we don't allow loading out of tree LSMs > via kernel modules because we can't support", that's the end of the world for > LKM-based LSMs. > > The mechanism which makes LKM-based LSMs possible must not be disabled by > the person/organization who builds the vmlinux. > > You might still say that "You can build your vmlinux and distribute it", but > that is also impossible in practice. Some device drivers are meant to be loaded > for Linux distribution's prebuilt kernels. Also, debuginfo package is needed for > analyzing vmcore. Building vmlinux and distributing it is not practical without > becoming a well-known Linux distributors enough to get out-of-tree device drivers > being prebuilt (such as Red Hat). > > Again, you are so blind. > > > Now, this patch and the patch that makes security_hook_heads > > __ro_after_init by removing CONFIG_SECURITY_HOOKS_WRITABLE breaks your > > hack. > > Like I demonstrated at https://lkml.kernel.org/r/cc8e16bb-5083-01da-4a77-d251a76dc8ff@I-love.SAKURA.ne.jp , > removing CONFIG_SECURITY_HOOKS_WRITABLE does not break my hack. >
On 10/1/2023 3:51 AM, Tetsuo Handa wrote: > On 2023/09/25 20:22, KP Singh wrote: >>> It is Casey's commitment that the LSM infrastructure will not forbid LKM-based LSMs. >>> We will start allowing LKM-based LSMs. But it is not clear how we can make it possible to >>> allow LKM-based LSMs. >> I think this needs to be discussed if and when we allow LKM based LSMs. > It is *now* (i.e. before your proposal is accepted) that we need to discuss. > >> One needs to know MAX_LSM_COUNT at compile time (not via kernel >> command line), I really suggest you try out your suggestions before >> posting them. I had explained this to you earlier, you still chose to >> ignore and keep suggesting stuff that does not work. > Your proposal needs to know MAX_LSM_COUNT at compile time, that's why > we need to discuss now. > >> We will see when this happens. I don't think it's a difficult problem >> and there are many ways to implement this: >> >> * Add a new slot(s) for modular LSMs (One can add up to N fast modular LSMs) >> * Fallback to a linked list for modular LSMs, that's not a complexity. >> There are serious performance gains and I think it's a fair trade-off. >> This isn't even complex. > That won't help at all. This is exactly the solution I have been contemplating since this discussion began. It will address the bulk of the issue. I'm almost mad/crazy enough to produce the patch to demonstrate it. Almost. There are still a bunch of details (e.g. shared blobs) that it doesn't address. On the other hand, your memory management magic doesn't address those issues either. > You became so blind because what you want to use (i.e. > SELinux and BPF) are already supported by Linux distributors. The reason I'm > insisting on supporting LKM-based LSMs is that Linux distributors cannot afford > supporting minor LSMs. > > Dave Chinner said > > Downstream distros support all sorts of out of tree filesystems loaded > via kernel modules > > at https://lkml.kernel.org/r/ZQo94mCzV7hOrVkh@dread.disaster.area , and e.g. > antivirus software vendors use out of tree filesystems loaded via kernel > modules (because neither the upstream kernel community nor the Linux distributors > can afford supporting out of tree filesystems used by antivirus software vendors). > > If Linux distributors decide "we don't allow loading out of tree filesystems > via kernel modules because we can't support", that's the end of the world for > such filesystems. > > What I'm saying is nothing but s/filesystem/LSM/g . > If Linux distributors decide "we don't allow loading out of tree LSMs > via kernel modules because we can't support", that's the end of the world for > LKM-based LSMs. > > The mechanism which makes LKM-based LSMs possible must not be disabled by > the person/organization who builds the vmlinux. > > You might still say that "You can build your vmlinux and distribute it", but > that is also impossible in practice. Some device drivers are meant to be loaded > for Linux distribution's prebuilt kernels. Also, debuginfo package is needed for > analyzing vmcore. Building vmlinux and distributing it is not practical without > becoming a well-known Linux distributors enough to get out-of-tree device drivers > being prebuilt (such as Red Hat). > > Again, you are so blind. > >> Now, this patch and the patch that makes security_hook_heads >> __ro_after_init by removing CONFIG_SECURITY_HOOKS_WRITABLE breaks your >> hack. > Like I demonstrated at https://lkml.kernel.org/r/cc8e16bb-5083-01da-4a77-d251a76dc8ff@I-love.SAKURA.ne.jp , > removing CONFIG_SECURITY_HOOKS_WRITABLE does not break my hack. >
On 2023/10/02 0:00, Casey Schaufler wrote: > On 10/1/2023 3:51 AM, Tetsuo Handa wrote: >> On 2023/09/25 20:22, KP Singh wrote: >>>> It is Casey's commitment that the LSM infrastructure will not forbid LKM-based LSMs. >>>> We will start allowing LKM-based LSMs. But it is not clear how we can make it possible to >>>> allow LKM-based LSMs. >>> I think this needs to be discussed if and when we allow LKM based LSMs. >> It is *now* (i.e. before your proposal is accepted) that we need to discuss. >> >>> One needs to know MAX_LSM_COUNT at compile time (not via kernel >>> command line), I really suggest you try out your suggestions before >>> posting them. I had explained this to you earlier, you still chose to >>> ignore and keep suggesting stuff that does not work. >> Your proposal needs to know MAX_LSM_COUNT at compile time, that's why >> we need to discuss now. >> >>> We will see when this happens. I don't think it's a difficult problem >>> and there are many ways to implement this: >>> >>> * Add a new slot(s) for modular LSMs (One can add up to N fast modular LSMs) >>> * Fallback to a linked list for modular LSMs, that's not a complexity. >>> There are serious performance gains and I think it's a fair trade-off. >>> This isn't even complex. >> That won't help at all. > > This is exactly the solution I have been contemplating since this > discussion began. It will address the bulk of the issue. I'm almost > mad/crazy enough to produce the patch to demonstrate it. Almost. Yes, please show us one. I'm fine if the mechanism which allows LKM-based LSMs cannot be disabled via the kernel configuration options. I really want a commitment that none of the LSM community objects revival of LKM-based LSMs. I'm worrying that some of the LSM community objects revival of LKM-based LSMs because adding extra slots and/or linked list is e.g. an overhead, increases attack surface etc. Let's consider the Microsoft Windows operating system. Many security vendors are offering security software which can run without recompiling the Windows OS. But what about Linux? Security vendors cannot trivially add a security mechanism because LKM-based LSMs are not supported since 2.6.24. As a result, some chose hijacking LSM hooks, and others chose overwriting system call tables. The Linux kernel is there for providing what the user needs. What about the LSM infrastructure? The LSM infrastructure is too much evolving towards in-tree and built-in security mechanisms. The consequence of such evolving will be "Limited Security Modes" where users cannot use what they need. New ideas cannot be easily tried if rebuild of vmlinux is inevitable, which will also prevent a breath of fresh ideas from reaching the LSM community. Never "discussed *if* we allow LKM based LSMs", for the LSM community cannot afford accepting whatever LSMs and the Linux distributors cannot afford enabling whatever LSMs. I'm not speaking for the security vendors. I'm speaking from the point of view of minority/out-of-tree users. > There are still a bunch of details (e.g. shared blobs) that it doesn't > address. On the other hand, your memory management magic doesn't > address those issues either. Security is always trial-and-error. Just give all Linux users chances to continue trial-and-error. You don't need to forbid LKM-based LSMs just because blob management is not addressed. Please open the LSM infrastructure to anyone.
On Mon, Oct 2, 2023 at 12:56 PM Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> wrote: > > On 2023/10/02 0:00, Casey Schaufler wrote: > > On 10/1/2023 3:51 AM, Tetsuo Handa wrote: > >> On 2023/09/25 20:22, KP Singh wrote: > >>>> It is Casey's commitment that the LSM infrastructure will not forbid LKM-based LSMs. > >>>> We will start allowing LKM-based LSMs. But it is not clear how we can make it possible to > >>>> allow LKM-based LSMs. > >>> I think this needs to be discussed if and when we allow LKM based LSMs. > >> It is *now* (i.e. before your proposal is accepted) that we need to discuss. > >> > >>> One needs to know MAX_LSM_COUNT at compile time (not via kernel > >>> command line), I really suggest you try out your suggestions before > >>> posting them. I had explained this to you earlier, you still chose to > >>> ignore and keep suggesting stuff that does not work. > >> Your proposal needs to know MAX_LSM_COUNT at compile time, that's why > >> we need to discuss now. > >> > >>> We will see when this happens. I don't think it's a difficult problem > >>> and there are many ways to implement this: > >>> > >>> * Add a new slot(s) for modular LSMs (One can add up to N fast modular LSMs) > >>> * Fallback to a linked list for modular LSMs, that's not a complexity. > >>> There are serious performance gains and I think it's a fair trade-off. > >>> This isn't even complex. > >> That won't help at all. > > > > This is exactly the solution I have been contemplating since this > > discussion began. It will address the bulk of the issue. I'm almost > > mad/crazy enough to produce the patch to demonstrate it. Almost. > > Yes, please show us one. I'm fine if the mechanism which allows LKM-based LSMs > cannot be disabled via the kernel configuration options. > > I really want a commitment that none of the LSM community objects revival of > LKM-based LSMs. I'm worrying that some of the LSM community objects revival of > LKM-based LSMs because adding extra slots and/or linked list is e.g. an overhead, > increases attack surface etc. > > Let's consider the Microsoft Windows operating system. Many security vendors are > offering security software which can run without recompiling the Windows OS. > > But what about Linux? Security vendors cannot trivially add a security mechanism > because LKM-based LSMs are not supported since 2.6.24. As a result, some chose > hijacking LSM hooks, and others chose overwriting system call tables. > > The Linux kernel is there for providing what the user needs. What about the LSM > infrastructure? The LSM infrastructure is too much evolving towards in-tree and > built-in security mechanisms. > > The consequence of such evolving will be "Limited Security Modes" where users cannot > use what they need. New ideas cannot be easily tried if rebuild of vmlinux is > inevitable, which will also prevent a breath of fresh ideas from reaching the LSM > community. > > Never "discussed *if* we allow LKM based LSMs", for the LSM community cannot > afford accepting whatever LSMs and the Linux distributors cannot afford enabling > whatever LSMs. > > I'm not speaking for the security vendors. I'm speaking from the point of view of > minority/out-of-tree users. > > > There are still a bunch of details (e.g. shared blobs) that it doesn't > > address. On the other hand, your memory management magic doesn't > > address those issues either. > > Security is always trial-and-error. Just give all Linux users chances to continue > trial-and-error. You don't need to forbid LKM-based LSMs just because blob management > is not addressed. Please open the LSM infrastructure to anyone. It already is, the community is already using BPF LSM. e.g. https://github.com/linux-lock/bpflock >
On 2023/10/02 19:56, Tetsuo Handa wrote: >> This is exactly the solution I have been contemplating since this >> discussion began. It will address the bulk of the issue. I'm almost >> mad/crazy enough to produce the patch to demonstrate it. Almost. > > Yes, please show us one. If "[PATCH v15 01/11] LSM: Identify modules by more than name" does not allow LKM-based LSMs (which are likely out-of-tree) to have stable LSM ID values, lsm_list_modules() provided by "[PATCH v15 05/11] LSM: Create lsm_list_modules system call" cannot report stable string names. And "[PATCH v15 11/11] LSM: selftests for Linux Security Module syscalls" cannot work on LKM-based LSMs. Then, how are LKM-based LSMs activated? LKM-based LSMs can use LSM hooks but cannot use (or show up in) lsm_get_self_attr()/lsm_set_self_attr()/lsm_list_modules() syscalls? That looks quite strange, for the title of "[PATCH v15 01/11]" is not "LSM: Identify only built-in and in-tree modules by more than name". If you think about allowing LKM-based LSMs a bit, you will find that how can the current policy be compatible. We cannot introduce lsm_get_self_attr()/lsm_set_self_attr()/lsm_list_modules() syscalls without admitting stable LSM ID values being assigned to any publicly available LSMs. Simple notification to the LSM community has to be the only requirement for assigning stable LSM ID values. You should not distinguish in-tree and not-in-tree LSMs regarding "[PATCH v15 00/11] LSM: Three basic syscalls". Otherwise, the attempt to introduce these syscalls is a regression that will harm LKM-based LSMs.
diff --git a/include/linux/lsm_count.h b/include/linux/lsm_count.h new file mode 100644 index 000000000000..0c0ff3c7dddc --- /dev/null +++ b/include/linux/lsm_count.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * Copyright (C) 2023 Google LLC. + */ + +#ifndef __LINUX_LSM_COUNT_H +#define __LINUX_LSM_COUNT_H + +#include <linux/kconfig.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_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 + + +#define __COUNT_COMMAS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n +#define COUNT_COMMAS(a, X...) __COUNT_COMMAS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#define ___COUNT_COMMAS(args...) COUNT_COMMAS(args) + + +#define MAX_LSM_COUNT \ + ___COUNT_COMMAS( \ + CAPABILITIES_ENABLED \ + SELINUX_ENABLED \ + SMACK_ENABLED \ + APPARMOR_ENABLED \ + TOMOYO_ENABLED \ + YAMA_ENABLED \ + LOADPIN_ENABLED \ + LOCKDOWN_ENABLED \ + BPF_LSM_ENABLED \ + LANDLOCK_ENABLED) + +#else + +#define MAX_LSM_COUNT 0 + +#endif /* CONFIG_SECURITY */ + +#endif /* __LINUX_LSM_COUNT_H */
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 (number of possible LSMs * number of LSM hooks) which ends up being quite wasteful especially when some LSMs are not compiled into the kernel. Suggested-by: Kui-Feng Lee <sinquersw@gmail.com> Suggested-by: Andrii Nakryiko <andrii@kernel.org Signed-off-by: KP Singh <kpsingh@kernel.org> --- include/linux/lsm_count.h | 106 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 include/linux/lsm_count.h