mbox series

[RFC,v2,0/4] LSM: Officially support appending LSM hooks after boot.

Message ID 93b5e861-c1ec-417c-b21e-56d0c4a3ae79@I-love.SAKURA.ne.jp (mailing list archive)
Headers show
Series LSM: Officially support appending LSM hooks after boot. | expand

Message

Tetsuo Handa Nov. 20, 2023, 1:27 p.m. UTC
This functionality will be used by TOMOYO security module.

In order to officially use an LSM module, that LSM module has to be
built into vmlinux. This limitation has been a big barrier for allowing
distribution kernel users to use LSM modules which the organization who
builds that distribution kernel cannot afford supporting [1]. Therefore,
I've been asking for ability to append LSM hooks from LKM-based LSMs so
that distribution kernel users can use LSMs which the organization who
builds that distribution kernel cannot afford supporting.

In order to unofficially use LSMs which are not built into vmlinux,
I've been maintaining AKARI as an LKM-based LSM which can run on kernels
between 2.6.0 and 6.6. But KP Singh's "Reduce overhead of LSMs with static
calls" proposal will make AKARI more difficult to run because it removes
the linked list. Therefore, reviving ability to officially append LSM
hooks from LKM-based LSMs became an urgent matter.

KP Singh suggested me to implement such LSMs as eBPF programs. But the
result is that eBPF is too restricted to emulate such LSMs [2]. Therefore,
I still need ability to append LSM hooks from LKM-based LSMs.

KP Singh commented

  I think what you can do is send patches for an API for LKM based LSMs
  and have it merged before my series, I will work with the code I have
  and make LKM based LSMs work. If this work gets merged, and your
  use-case is accepted (I think I can speak for at least Kees [if not
  others] too here) we will help you if you get stuck with MAX_LSM_COUNT
  or a dual static call and linked list based approach.

at [3] and I posted one at [4] but I didn't get any response.

Anyway, here is an updated version. This version focused on how to
implement an LSM module which calls LSM hooks in the LKM based LSMs
(mod_lsm). Since there are a lot of duplication between
security/security.c and security/mod_lsm.c , I tried to auto-genarate
typical functions using macros.

The result is that, although I succeeded to avoid bloating total lines
of source code, I feel that it might become less readable. Therefore,
I came to think that we don't need to implement an LSM module which calls
LSM hooks in the LKM based LSMs.

 b/include/linux/bpf_lsm.h       |    1
 b/include/linux/lsm_hook_args.h |  250 +++++++++++++++++++++++++
 b/include/linux/lsm_hook_defs.h |    3
 b/include/linux/lsm_hooks.h     |    2
 b/kernel/bpf/bpf_lsm.c          |    3
 b/security/Makefile             |    2
 b/security/bpf/hooks.c          |    1
 b/security/mod_lsm.c            |  321 ++++++++++++++++++++++++++++++++
 b/security/security.c           |    3
 include/linux/lsm_hook_defs.h   |  780 ++++++++++++++++++++++++++++++++++++++++++-------------------------------------
 include/linux/lsm_hooks.h       |    9
 security/security.c             |  752 ++--------------------------------------------------------------------------
 12 files changed, 1035 insertions(+), 1092 deletions(-)

Instead, directly embedding the code to call LSM hooks in the LKM based
LSMs into call_int_hook() and call_void_hook() macros will save a lot of
symbols compared to implementing functions for calling LSM hooks in the
LKM based LSMs. Since LKM-based LSMs was not officially supported as of
introduction of the lsm= parameter, forcing to call LKM-based LSMs after
calling built-in LSMs will not confuse userspace.

Unless someone has objection on not using an LSM module which calls
LSM hooks in the LKM based LSMs, I'd like to try something like below
in the next version.

 #define call_void_hook(FUNC, ...)				\
 	do {							\
 		struct security_hook_list *P;			\
 								\
 		hlist_for_each_entry(P, &security_hook_heads.FUNC, list) \
 			P->hook.FUNC(__VA_ARGS__);		\
+		if (mod_lsm_enabled) {				\
+			hlist_for_each_entry(P, &mod_lsm_hook_heads.FUNC, list) \
+				P->hook.FUNC(__VA_ARGS__);	\
+		}						\
 	} while (0)
 
 #define call_int_hook(FUNC, IRC, ...) ({			\
 	int RC = IRC;						\
 	do {							\
 		struct security_hook_list *P;			\
 								\
 		hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \
 			RC = P->hook.FUNC(__VA_ARGS__);		\
 			if (RC != 0)				\
 				break;				\
 		}						\
+		if (mod_lsm_enabled) {				\
+			hlist_for_each_entry(P, &mod_lsm_hook_heads.FUNC, list) { \
+				RC = P->hook.FUNC(__VA_ARGS__);	\
+				if (RC != 0)			\
+					break;			\
+			}					\
+		}						\
 	} while (0);						\
 	RC;							\
 })

Link: https://lkml.kernel.org/r/9b006dfe-450e-4d73-8117-9625d2586dad@I-love.SAKURA.ne.jp [1]
Link: https://lkml.kernel.org/r/c588ca5d-c343-4ea2-a1f1-4efe67ebb8e3@I-love.SAKURA.ne.jp [2]
Link: https://lkml.kernel.org/r/CACYkzJ7ght66802wQFKzokfJKMKDOobYgeaCpu5Gx=iX0EuJVg@mail.gmail.com [3]
Link: https://lkml.kernel.org/r/38b318a5-0a16-4cc2-878e-4efa632236f3@I-love.SAKURA.ne.jp [4]

Comments

Paul Moore Nov. 20, 2023, 10:52 p.m. UTC | #1
On Mon, Nov 20, 2023 at 8:28 AM Tetsuo Handa
<penguin-kernel@i-love.sakura.ne.jp> wrote:
>
> This functionality will be used by TOMOYO security module.
>
> In order to officially use an LSM module, that LSM module has to be
> built into vmlinux. This limitation has been a big barrier for allowing
> distribution kernel users to use LSM modules which the organization who
> builds that distribution kernel cannot afford supporting [1]. Therefore,
> I've been asking for ability to append LSM hooks from LKM-based LSMs so
> that distribution kernel users can use LSMs which the organization who
> builds that distribution kernel cannot afford supporting.

It doesn't really matter for this discussion, but based on my days
working for a Linux distro company I would be very surprised if a
commercial distro would support a system running unapproved
third-party kernel modules.

We've talked a lot about this core problem and I maintain that it is
still a disto problem and not something I'm really concerned about
upstream.
Tetsuo Handa Nov. 21, 2023, 1:03 p.m. UTC | #2
On 2023/11/21 7:52, Paul Moore wrote:
> On Mon, Nov 20, 2023 at 8:28 AM Tetsuo Handa
> <penguin-kernel@i-love.sakura.ne.jp> wrote:
>>
>> This functionality will be used by TOMOYO security module.
>>
>> In order to officially use an LSM module, that LSM module has to be
>> built into vmlinux. This limitation has been a big barrier for allowing
>> distribution kernel users to use LSM modules which the organization who
>> builds that distribution kernel cannot afford supporting [1]. Therefore,
>> I've been asking for ability to append LSM hooks from LKM-based LSMs so
>> that distribution kernel users can use LSMs which the organization who
>> builds that distribution kernel cannot afford supporting.
> 
> It doesn't really matter for this discussion, but based on my days
> working for a Linux distro company I would be very surprised if a
> commercial distro would support a system running unapproved
> third-party kernel modules.

A commercial distro does not care about problems that are caused by
using kernel modules that are not included in that distro's kernels.

Those who supply kernel modules that are not included in that distro's
kernels (e.g. antivirus software vendors) care about problems that are
caused by using such kernel modules.

Kernel modules for hardware devices that are not included in that distro's
kernels can be appended after boot.

Kernel modules for filesystems that are not included in that distro's
kernels can be appended after boot.

If a commercial distro does not want to allow use of kernel modules that
are not included in that distro's kernels, that distro would enforce module
signature verification rather than disabling loadable module support.
Keeping loadable module support enabled is a balance that is important for
getting wider developers/users.

> 
> We've talked a lot about this core problem and I maintain that it is
> still a disto problem and not something I'm really concerned about
> upstream.

LSM modules that are not built into vmlinux currently cannot be appended
after boot. Such asymmetry is strange and remains a big barrier.

You are not concerned about this asymmetry, but I am very much concerned.
Please give me feedback on not "I don't need it" but "how we can do it".
Paul Moore Nov. 22, 2023, 4:41 a.m. UTC | #3
On Tue, Nov 21, 2023 at 8:03 AM Tetsuo Handa
<penguin-kernel@i-love.sakura.ne.jp> wrote:
> On 2023/11/21 7:52, Paul Moore wrote:
> > On Mon, Nov 20, 2023 at 8:28 AM Tetsuo Handa
> > <penguin-kernel@i-love.sakura.ne.jp> wrote:
> >>
> >> This functionality will be used by TOMOYO security module.
> >>
> >> In order to officially use an LSM module, that LSM module has to be
> >> built into vmlinux. This limitation has been a big barrier for allowing
> >> distribution kernel users to use LSM modules which the organization who
> >> builds that distribution kernel cannot afford supporting [1]. Therefore,
> >> I've been asking for ability to append LSM hooks from LKM-based LSMs so
> >> that distribution kernel users can use LSMs which the organization who
> >> builds that distribution kernel cannot afford supporting.
> >
> > It doesn't really matter for this discussion, but based on my days
> > working for a Linux distro company I would be very surprised if a
> > commercial distro would support a system running unapproved
> > third-party kernel modules.
>
> A commercial distro does not care about problems that are caused by
> using kernel modules that are not included in that distro's kernels.

My experience has taught me otherwise.

> If a commercial distro does not want to allow use of kernel modules that
> are not included in that distro's kernels, that distro would enforce module
> signature verification rather than disabling loadable module support.
> Keeping loadable module support enabled is a balance that is important for
> getting wider developers/users.

We don't currently support LSMs as dynamically loadable kernel modules
and if the only reasons for doing so are either to A) support
out-of-tree LSMs or B) avoid having to recompile a kernel (to hack an
unsupported LSM into a distro kernel) I have to say (yet again) that I
am not interested.

> > We've talked a lot about this core problem and I maintain that it is
> > still a disto problem and not something I'm really concerned about
> > upstream.
>
> LSM modules that are not built into vmlinux currently cannot be appended
> after boot. Such asymmetry is strange and remains a big barrier.
>
> You are not concerned about this asymmetry, but I am very much concerned.
> Please give me feedback on not "I don't need it" but "how we can do it".

I thought my feedback has been clear up to this point, but perhaps I
need to be more direct.  At this point in time I am not interested in
supporting dynamically loaded LSM kernel modules if the only reasons
are to support out-of-tree LSMs or users who want to hack unsupported
LSMs into pre-built distro kernels; both of these use cases can be
solved today by compiling your own kernel.

As with the other threads involving this topic, I'm going to refrain
from any further comments until I see a new discussion point.

--
paul-moore.com
Tetsuo Handa Nov. 26, 2023, 4:37 a.m. UTC | #4
On 2023/11/22 13:41, Paul Moore wrote:
> both of these use cases can be solved today by compiling your own kernel.

No. Compiling kernels is not a viable option for regular developers/users.

We (who are kernel developers) tend to think that compiling/replacing a
kernel as a trivial thing. But majority of Linux users do not think so.
The kernel is one of most puzzling programs for Linux users, and most of
Linux users afraid compiling/replacing kernels.

Red Hat's support said that Red Hat does not support a rebuilt RHEL kernel
even if that kernel is rebuilt using the same kernel source and the same
kernel config shipped by Red Hat. Let alone kernels which are rebuilt with
the modified kernel config.

Your "compiling your own kernel" answer is asking me to become a Linux
distributor and to support the whole rebuilt kernels. That will include
management of kernel-debuginfo packages needed for analyzing vmcore, and
also management of userspace packages which depend on the kernel package.

What do you think if you are obligated to support whatever problems just because
you want to allow users to use your code? I'm sure that you will say "I can't".
Your answer cannot be satisfied by a kernel developer who can develop/support
an LSM module but cannot afford supporting problems that are irrelevant to
that LSM module.

Being able to use whatever functionality (not only LSM modules but also
device drivers and filesystem drivers) using pre-built distribution kernels
and pre-built kernel-debuginfo packages is the mandatory baseline.

Of course, the best solution is that whatever LSM modules are built into
distributor's kernels. But since such solution is impossible
( https://bugzilla.redhat.com/show_bug.cgi?id=542986 ), the second best
solution will be that distributor's kernels support only ability to load LSM
modules which that distributor's kernels cannot afford supporting as loadable
kernel modules, and somebody else other than distributor provides support for
LSM modules which that distributor's kernels cannot afford supporting.