Enable the bpf LSM: `CONFIG_BPF_LSM=y` is set, but `bpf` is missing from `CONFIG_LSM`
- Dominant language
- C++
- Stars
- 33.7k
- Forks
- 1.8k
- Avg merge
- 3d 17h
- Merged PRs (30d)
- 116
Description
**Is your feature request related to a problem? Please describe.**
BPF LSM programs can't be attached on the WSL2 kernel, even though `CONFIG_BPF_LSM=y`.
`bpf` is missing from the ordered LSM list, so the hooks are built in but never registered. On today's kernel (`6.18.33.1-microsoft-standard-WSL2`):
```
$ cat /sys/kernel/security/lsm
capability,landlock,yama,safesetid,selinux,ima
```
and in `Microsoft/config-wsl`, on both `linux-msft-wsl-6.6.y` and `linux-msft-wsl-6.18.y`:
```
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_LSM=y
CONFIG_DEBUG_INFO_BTF=y
CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,selinux,apparmor,tomoyo"
```
`DEFINE_LSM(bpf)` is `LSM_ORDER_MUTABLE`, so anything left off that list is ignored, and attaching (`link.AttachLSM`, `bpftool prog attach`) fails.
Amusingly the two halves have never been on at the same time 😅:
| branch | `CONFIG_BPF_LSM` | `bpf` in `CONFIG_LSM` |
| --- | --- | --- |
| `linux-msft-wsl-5.15.y` | not set | yes |
| `linux-msft-wsl-6.1.y` | not set | yes |
| `linux-msft-wsl-6.6.y` | `y` | no |
| `linux-msft-wsl-6.18.y` | `y` | no |
I think it's unintentional? Upstream `security/Kconfig` has `bpf` in every branch of the `config LSM` default, including the `DEFAULT_SECURITY_SELINUX` one the WSL config selects. The 6.6 string looks like it was written from an older default: it still carries `integrity`, and it's missing `smack` and `ipe` as well.
**Describe the solution you'd like**
Add `bpf` to `CONFIG_LSM` in `Microsoft/config-wsl` and `Microsoft/config-wsl-arm64`:
```
CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,selinux,apparmor,tomoyo,bpf"
```
That's the whole ask, everything else is already in place. It costs nothing when no program is attached, and it's what upstream defaults to.
The use case I have in mind is a small `lsm/socket_create` or `lsm/socket_connect` program to decide which address families workloads inside the VM are allowed to use. That's a handful of lines with the LSM hooks, which see the arguments as plain values whatever the syscall entry path. Without them the only option left is seccomp, which is a poor substitute: it can only look at scalar syscall arguments, it can't follow a pointer, and the kernel allows a single user-notification listener per filter stack, so anything else in the VM that wants one collides with you. I'd guess I'm not the only one in that spot, Cilium, Tetragon, Falco, tracee and friends all want the same hooks (#11238).
**Describe alternatives you've considered**
- `kernelCommandLine=lsm=…,bpf` in `.wslconfig`. It should work, but it's per-user global config, it needs a `wsl --shutdown`, and it pins a list that then goes stale against whatever the kernel ships. Not something you can rely on being there on someone else's machine.
- Shipping a custom kernel. Fine for a one-off test, not for a wide audience.
- Staying on seccomp. It works, it's just more code and more caveats for a weaker guarantee.
**Additional context**
- #9819 asked for `CONFIG_BPF_LSM=y` back in 2023 and was auto-closed as stale a year later. It's actually satisfied now, since 6.6, it's only the LSM list that's still missing.
- #11238 is the broader "eBPF on WSL" request, still open.
- `CONFIG_BPF_SYSCALL=y` and `CONFIG_DEBUG_INFO_BTF=y` are already set, so nothing else is needed on the config side.
- Happy to send the config PR against `linux-msft-wsl-6.18.y` if that helps.
Contributor guide
Assessment
This issue has not been assessed yet.