On 2023/10/22 0:20, KP Singh wrote: >> Since printk() is not callable, most of functions which TOMOYO/AKARI/CaitSith-like >> programs use seem to be not callable. > > It seems like you are trying to 1:1 re-implement an existing LSM's > code base in BPF, Yes, that is the goal. Since you said "Until I hear the real limitations of using BPF, it's a NAK from me." at https://lkml.kernel.org/r/CACYkzJ5k7oYxFgWp9bz1Wmp3n6LcU39Mh-HXFWTKnZnpY-Ef7w@xxxxxxxxxxxxxx , I want to know whether it is possible to re-implement TOMOYO LSM as an eBPF program. If it is possible to re-implement TOMOYO LSM as an eBPF program, my desire to allow appending LKM-based LSMs after boot will be significantly reduced, which in turn will become my ACK to "security: Count the LSMs enabled at compile time" in your "Reduce overhead of LSMs with static calls" proposal. > that's surely not going to work. You need to think > about the use-case / policy you are trying to implement and then write > the code in BPF independently. Please share concrete examples of the > policy you want to implement and we try to help you. Asking for > features where you want a 1:1 parity with kernel code without concrete > policy use-cases is not going to enable us to help you. The code which I want to re-implement using eBPF is all of security/tomoyo/ directory. >> 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. > > you cannot call any function from within BPF. If you need to call > something they need to be exported as a kfunc (you need to send > patches on the mailing list for it). This is because we want to ensure > that BPF programs can be verified. TOMOYO needs to be able to call d_absolute_path() in order to calculate requested pathname, call call_usermodehelper(UMH_WAIT_PROC) in order to load policy upon activation, call get_mm_exe_file() in order to know the pathname of executable, get_user_pages_remote() in order to examine argv/envp passed to execve() system call etc. etc. in addition to performing complicated comparison including loop like https://elixir.bootlin.com/linux/v6.6-rc6/source/security/tomoyo/group.c#L120 . If any of above requirements cannot be satisfied in eBPF, that will become the real limitations of using BPF. >> 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 > > Programs can also be pinned on /sys/bpf similar to maps, this allows > them to persist even after the loading program goes away. > > Here's an example of a pinned program: > > https://elixir.bootlin.com/linux/latest/source/tools/testing/selftests/bpf/flow_dissector_load.c#L39 > >> 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 > > Not needed as programs can be pinned too. > That's good but not enough. We will need to forbid unlink/umount because detach_program() says "/* To unpin, it is necessary and sufficient to just remove this dir */". Hooking security_inode_unlink()/security_sb_umount() and return an error if the requested file was the eBPF version of TOMOYO (or maps etc. related to the eBPF version of TOMOYO) or the requested filesystem was sysfs might be able to forbid "unpin" operation... That would be the next step to check if re-implementing all of security/tomoyo/ directory using eBPF is possible...