[RFC PATCH 1/2] LSM: Allow dynamically appendable LSM modules.
Tetsuo Handa
penguin-kernel at I-love.SAKURA.ne.jp
Sat Oct 21 14:19:43 UTC 2023
On 2023/10/04 0:09, KP Singh wrote:
>> What I expected is "allocate memory where amount is determined at runtime" (e.g. alloc(), realloc()).
>
> One can use dynamically sized allocations on the ring buffer with
> dynamic pointers:
>
> http://vger.kernel.org/bpfconf2022_material/lsfmmbpf2022-dynptr.pdf
>
> Furthermore, there are some use cases that seemingly need dynamic
> memory allocation but not really. e.g. there was a need to audit
> command line arguments and while it seems dynamic and one can chunk
> the allocation to finite sizes, put these on a ring buffer and process
> the chunks.
>
> It would be nice to see more details of where the dynamic allocation
> is needed. Security blobs are allocated dynamically but have a fixed
> size.
Dynamic allocation is not for security blobs. Dynamic allocation is for
holding requested pathnames (short-lived allocation), holding audit logs
(FIFO allocation), holding/appending access control rules (long-lived
allocation).
>> Some of core requirements for implementing TOMOYO/AKARI/CaitSith-like programs
>> using BPF will be:
>>
>> The program registered cannot be stopped/removed by the root user.
>> This is made possible by either building the program into vmlinux or loading
>> the program as a LKM without module_exit() callback. Is it possible to guaranee
>> that a BPF program cannot be stopped/removed by user's operations?
>
> Yes, there is a security_bpf hook where a BPF MAC policy can be
> implemented and other LSMs do that already.
>
>>
>> The program registered cannot be terminated by safety mechanisms (e.g. excessive
>> CPU time consumption). Are there mechanisms in BPF that wouldn't have terminated
>> a program if the program were implemented as a LKM rather than a BPF program?
>>
>
> The kernel does not terminate BPF LSM programs, once a BPF program is
> loaded and attached to the LSM hook, it's JITed into a native code.
> From there onwards, as far as the kernel is concerned it's just like
> any other kernel function.
I was finally able to build and load tools/testing/selftests/bpf/progs/lsm.c and
tools/testing/selftests/bpf/prog_tests/test_lsm.c , and I found fatal limitation
that the program registered is terminated when the file descriptor which refers to
tools/testing/selftests/bpf/lsm.bpf.o is closed (due to e.g. process termination).
That is, eBPF programs are not reliable/robust enough to implement TOMOYO/AKARI/
CaitSith-like programs. Re-registering when the file descriptor is closed is racy
because some critical operations might fail to be traced/checked by the LSM hooks.
Also, I think that automatic cleanup upon closing the file descriptor implies that
allocating resources (or getting reference counts) that are not managed by the BPF
(e.g. files under /sys/kernel/securitytomoyo/ directory) is not permitted. That's
very bad.
>
>>
>> Amount of memory needed for managing data is not known at compile time. Thus, I need
>> kmalloc()-like memory allocation mechanism rather than allocating from some pool, and
>> manage chunk of memory regions using linked list. Does BPF have kmalloc()-like memory
>> allocation mechanism that allows allocating up to 32KB (8 pages if PAGE_SIZE=4096).
>>
>
> You use the ring buffer as a large pool and use dynamic pointers to
> carve chunks out of it, if truly dynamic memory is needed.
TOMOYO/AKARI/CaitSith-like programs do need dynamic memory allocation, as max amount of
memory varies from less than 1MB to more than 10MB. Preallocation is too much wasteful.
>
>> And maybe somewhere documented question:
>>
>> What kernel functions can a BPF program call / what kernel data can a BPF program access?
>
> BPF programs can access kernel data dynamically (accesses relocated at
> load time without needing a recompile) There are lot of good details
> in:
>
> https://nakryiko.com/posts/bpf-core-reference-guide/
>
>
>> The tools/testing/selftests/bpf/progs/test_d_path.c suggests that a BPF program can call
>> d_path() defined in fs/d_path.c . But is that because d_path() is marked as EXPORT_SYMBOL() ?
>> Or can a BPF program call almost all functions (like SystemTap script can insert hooks into
>> almost all functions)? Even functions / data in LKM can be accessed by a BPF program?
>>
>
> It's not all kernel functions, but there is a wide range of helpers
> and kfuncs (examples in tools/testing/selftests/bpf) and if there is
> something missing, we will help you.
I couldn't build tools/testing/selftests/bpf/progs/lsm.c with printk() added.
Sending to /sys/kernel/debug/tracing/trace_pipe via bpf_printk() is not enough for
reporting critical/urgent problems. Synchronous operation is important.
Since printk() is not callable, most of functions which TOMOYO/AKARI/CaitSith-like
programs use seem to be not callable.
More information about the Linux-security-module-archive
mailing list