I am looking for ways to prevent file deletion using eBPF LSM hooks.
I have previously looked into pure LSM solution without eBPF but I had to give up on that because that would have required me to use security_add_hooks
from security/security.c
which would have meant that I would have needed to compile my own kernel while eBPF would allow me to do it more dynamically.
I found this question: Hook file deletion with EBPF. Here the answer says:
If the above is not a solution for you for any reason you can consider LSM programs. LSM programs allow you to hook eBPF code into LSM hooks also used by SELinux/AppArmor. These are meant for enforcement, and depending on the specific hook you can return a boolean or an error code. This feature requires least kernel version v5.7 and that your kernel be compiled with the CONFIG_BPF_LSM=y config.
I think the path_unlink hook is what you are after. Its description:
From that I understood that while in general eBPF is for monitoring activities there are certain cases where it can be used for enforcement.
If I understand correctly this linked article seem to confirm that: /
To start I confirmed that my kernel is compiled with the CONFIG_BPF_LSM=y
root@debian:~/ebpf2# grep CONFIG_BPF_LSM /boot/config-$(uname -r)
CONFIG_BPF_LSM=y
I tried to write my own eBPF code. To keep the first version simple I wrote it so that it denies all deletes.
#include <linux/types.h>
#include <linux/errno.h>
#include <bpf/bpf_helpers.h>
SEC("lsm/path_unlink")
int BPF_PROG(void *ctx) {
return -EPERM;
}
char LICENSE[] SEC("license") = "GPL";
It compiles without errors:
clang -g -O2 -target bpf -D__TARGET_ARCH_x86_64 -I. -c prevent_delete.c -o prevent_delete.o
And I can load it without errors
bpftool prog load prevent_delete.o /sys/fs/bpf/prevent_delete
And I can confirm that it is loaded:
root@debian:~/ebpf2# bpftool prog show
93: lsm name BPF_PROG tag 59904229c5a1f55d gpl
loaded_at 2025-03-19T01:11:01+0200 uid 0
xlated 24B jited 19B memlock 4096B
btf_id 224
But when I try to delete some files then then I can still delete them - this eBPF program is not preventing it. I also tried inode_unlink
just to be sure that I didn't have to hook that instead since from here .4/security/lsm-development.html I wasn't 100% sure which one to choose.
Did I write something wrong in my C code or did I misunderstood that