microsoft / ebpf-for-windows

eBPF implementation that runs on top of Windows
MIT License
2.85k stars 221 forks source link

eBPF program Code Signing Infrastructure #181

Open magicalo opened 3 years ago

magicalo commented 3 years ago

I could not find any documentation on eBPF code-singing (WSDL-like program). Is this in the works?

dthaler commented 3 years ago

@qmonnet Can you paste the link to what Linux is working on? Thanks!

qmonnet commented 3 years ago

Sure. On Linux, Alexei has been exploring several ways to implement signature for eBPF programs. He finally went for an approach including a special “loader” eBPF program. As I understand it, the signature would be computed on this loader program, which would embed the other (regular) eBPF program.

Status: The first parts of this work have been merged in bpf-next, and from there into net-next, and it should land into Linux 5.14. But the feature is not complete yet, and some follow-up work is necessary before program signing is supported.

Here is the link to the thread for the patchset that was merged.

Description from the cover letter ``` This is a first step towards signed bpf programs [...] To make it work the following new concepts are introduced: 1. syscall bpf program type A kind of bpf program that can do sys_bpf and sys_close syscalls. It can only execute in user context. 2. FD array or FD index. Traditionally BPF instructions are patched with FDs. What it means that maps has to be created first and then instructions modified which breaks signature verification if the program is signed. Instead of patching each instruction with FD patch it with an index into array of FDs. That makes the program signature stable if it uses maps. 3. loader program that is generated as "strace of libbpf". When libbpf is loading bpf_file.o it does a bunch of sys_bpf() syscalls to load BTF, create maps, populate maps and finally load programs. Instead of actually doing the syscalls generate a trace of what libbpf would have done and represent it as the "loader program". The "loader program" consists of single map and single bpf program that does those syscalls. Executing such "loader program" via bpf_prog_test_run() command will replay the sequence of syscalls that libbpf would have done which will result the same maps created and programs loaded as specified in the elf file. The "loader program" removes libelf and majority of libbpf dependency from program loading process. 4. light skeleton Instead of embedding the whole elf file into skeleton and using libbpf to parse it later generate a loader program and embed it into "light skeleton". Such skeleton can load the same set of elf files, but it doesn't need libbpf and libelf to do that. It only needs few sys_bpf wrappers. Future steps: - support CO-RE in the kernel. This patch set is already too big, so that critical feature is left for the next step. - generate light skeleton in golang to allow such users use BTF and all other features provided by libbpf - generate light skeleton for kernel, so that bpf programs can be embeded in the kernel module. The UMD usage in bpf_preload will be replaced with such skeleton, so bpf_preload would become a standard kernel module without user space dependency. - finally do the signing of the loader program. ``` The “skeletons” refer to skeletons that libbpf can generate for creating user space applications to load and manage eBPF programs, here extended to create eBPF-loader programs too. They can be generated with `bpftool gen skeleton` for example.

An early version of this set was also the subject for a LWN.net article.