Thread (29 messages) 29 messages, 9 authors, 2023-10-22

Re: [RFC PATCH 1/2] LSM: Allow dynamically appendable LSM modules.

From: KP Singh <kpsingh@kernel.org>
Date: 2023-10-01 14:43:41
Also in: bpf

On Sun, Oct 1, 2023 at 1:08 PM Tetsuo Handa
[off-list ref] wrote:
On 2023/09/28 1:02, KP Singh wrote:
quoted
quoted
Question for KP Singh would be how can we allow dynamically appendable
LSM modules if current linked list is replaced with static calls with
minimal-sized array...
As I suggested in the other thread:

https://lore.kernel.org/bpf/20230918212459.1937798-1-kpsingh@kernel.org/T/#md21b9d9cc769f39e451d20364857b693d3fcb587 (local)

You can add extra static call slots and fallback to a linked list
based implementation if you have more than say N modules [1] and
fallback to a linked list implementation [2].
As I explained in the other thread:

https://lkml.kernel.org/r/c1683052-aa5a-e0d5-25ae-40316273ed1b@I-love.SAKURA.ne.jp

build-time configuration does not help at all.
quoted
for [1] you can just do MAX_LSM_COUNT you can just do:

#ifdef CONFIG_MODULAR_LSM
#define MODULAR_LSM_ENABLED "1,1,1,1"
#endif

and use it in the LSM_COUNT.

for [2] you can choose to export a better module API than directly
exposing security_hook_heads.

Now, comes the question of whether we need dynamically loaded LSMs, I
am not in favor of this. Please share your limitations of BPF as you
mentioned and what's missing to implement dynamic LSMs. My question
still remains unanswered.

Until I hear the real limitations of using BPF, it's a NAK from me.
Simple questions that TOMOYO/AKARI/CaitSith LSMs depend:

  Q1: How can the BPF allow allocating permanent memory (e.g. kmalloc()) that remains
      the lifetime of the kernel (e.g. before starting the global init process till
      the content of RAM is lost by stopping electric power supply) ?
This is very much possible using global BPF maps. Maps can be "pinned"
so that they remain allocated until explicitly freed [or RAM is lost
by stopping electric power supply"]

Here's an example of BPF program that allocates maps:

    https://elixir.bootlin.com/linux/latest/source/tools/testing/selftests/bpf/progs/test_pinning.c#L26

and the corresponding userspace code that does the pinning:

    https://elixir.bootlin.com/linux/latest/source/tools/testing/selftests/bpf/prog_tests/pinning.c

Specifically for LSMs, we also added support for security blobs which
are tied to a particular object and are free with the object, have a
look at the storage which is allocated in the program:

   https://elixir.bootlin.com/linux/latest/source/tools/testing/selftests/bpf/progs/local_storage.c#L79

Again, code and context on what you want to do will let me help you more here.
  Q2: How can the BPF allow interacting with other process (e.g. inter process communication
      using read()/write()) which involves opening some file on the filesystem and sleeping
      for arbitrary duration?
The BPF program runs in the kernel context, so yes all of this is
possible. IPC can be done with the bpf_ring_buffer / maps and BPF also
has the ability to send signals. One can poll on the ring buffer on
events and data from the BPF program and do a lots of things.

* e.g. receive and log command line parameters (e.g. from the security
hook bprm_committed_creds).
* Trigger various actions in user space.

Can you share your module code here, so that one can provide more
concrete suggestions?

- KP

quoted
quoted
 struct security_hook_heads security_hook_heads __ro_after_init;
+EXPORT_SYMBOL_GPL(security_hook_heads);
Rather than exposting security_hook_heads, this should actually export
security_hook_module_register. This should internally handle any data
structures used and also not need the special magic that you did for
__ro_after_init.
I'm fine if security_hook_module_register() (and related code) cannot be
disabled by the kernel configuration.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help