Public bug reported:
[Impact]
Ubuntu kernels build the bpf LSM (CONFIG_BPF_LSM=y) but omit "bpf" from
CONFIG_LSM, so the bpf LSM is compiled in and never initialized at boot:
$ uname -r
7.0.0-28-generic
$ grep -h '^CONFIG_LSM=' /boot/config-$(uname -r)
CONFIG_LSM="landlock,lockdown,yama,integrity,apparmor"
$ grep -h '^CONFIG_BPF_LSM=' /boot/config-$(uname -r)
CONFIG_BPF_LSM=y
$ cat /sys/kernel/security/lsm
lockdown,capability,landlock,yama,apparmor,ima,evm
Projects that use the bpf LSM detect its absence and fall back to weaker
mechanisms, or disable some of their features entirely:
- systemd gates several protection features on the bpf LSM being in
the active LSM list. Without it, RestrictFileSystems= is silently
skipped; systemd-nsresourced disables its user-namespace delegation
interfaces; and RestrictFileSystemAccess= (newer systemd), which has
no non-LSM implementation, causes PID 1 startup to fail if enabled.
- Tetragon refuses to load TracingPolicy objects that use LSM hooks,
and its error message directs users to add lsm=bpf to the kernel
command line. Enforcement must instead use kprobe-based Sigkill or
Override actions, the latter limited to functions annotated for
error injection.
- KubeArmor falls back from the bpf LSM to AppArmor, with documented
gaps in what can be enforced.
Bespoke BPF_PROG_TYPE_LSM programs load and attach without error and are
never invoked, since neither the bpf verifier nor the bpf trampoline
check whether the LSM was initialized.
The only workaround is to add "bpf" to the lsm= kernel command-line
parameter and reboot. That is not available where the command line is
not under the user's control before first boot, or cannot be changed
without rebuilding the image: cloud instances, image-based and immutable
deployments, or managed Kubernetes nodes.
This state was deliberate and its rationale no longer holds. When
CONFIG_BPF_LSM was enabled for Ubuntu (LP: #1905975; Groovy and Hirsute,
patch authored by KP Singh, 2020), bpf was intentionally left out of
CONFIG_LSM because activating it registered an empty callback on every
LSM hook, each costing an indirect, retpoline-mitigated call through
security_hook_heads. That bug records the intent to activate the LSM by
default once upstream work to remove the overhead landed. The same
author later landed that work:
417c5643cd67 ("lsm: replace indirect LSM hook calls with static
calls")
merged in 6.12, converts LSM hook dispatch from indirect calls to static
calls guarded by per-hook static keys. With bpf enabled, each hook site
now makes a direct call to the bpf_lsm_<hook> stub rather than an
indirect call via retpoline. The specific cost that LP: #1905975 named
as the blocker is gone, and has been absent from every Ubuntu kernel
since 25.04 (6.14).
Upstream security/Kconfig has listed bpf in every CONFIG_LSM default
since 5.7, via 520b7aa00d8c ("bpf: lsm: Initialize the BPF LSM hooks").
Ubuntu's explicit CONFIG_LSM value predates that commit. This request
brings Ubuntu's value into line with the upstream default rather than
introducing new policy.
[Fix]
Append bpf to CONFIG_LSM in debian.master/config/annotations for all
supported architectures:
-CONFIG_LSM policy<{'amd64': '"landlock,lockdown,yama,integrity,apparmor"',
...}>
+CONFIG_LSM policy<{'amd64': 'landlock,lockdown,yama,integrity,apparmor,bpf',
...}>
bpf is placed last, matching upstream ordering. No source changes are
required; the hooks are already built (CONFIG_BPF_LSM=y).
[Where problems could occur]
Ordering and exclusivity: AppArmor is the only LSM in Ubuntu's list
carrying LSM_FLAG_EXCLUSIVE; bpf, like landlock, lockdown and yama,
carries no such flag and cannot displace it regardless of position. bpf
is placed after apparmor, matching upstream, so hooks reach bpf programs
only for operations AppArmor has already permitted; AppArmor's own
decisions are unaffected. Systems booting with lsm= are unaffected,
since that parameter replaces the built-in list. Systems booting with
security=apparmor will gain bpf, as that parameter only selects among
exclusive LSMs.
Hook dispatch cost: the indirect-call overhead that motivated leaving
bpf inactive no longer exists on kernels with 417c5643cd67. What remains
is a direct call to an empty noinline stub per hook invocation when no
program is attached; the static key for the bpf slot is enabled at boot
because the bpf LSM registers a callback on every hook. A follow-up to
gate that key on program attachment was posted with the series (v13 5/5,
June 2024) but has not been merged. Two further caveats: a small number
of hooks were left as function pointers in the static-call conversion,
and on architectures without CONFIG_STATIC_CALL the framework falls back
to indirect calls.
Hook presence: the unmerged follow-up notes that some LSM hooks behave
differently when any callback is registered, independent of the
callback's return value. Enabling bpf registers a callback on every
hook. No specific behavioural change has been identified for Ubuntu's
configuration; reviewers may want to confirm this for hooks where
default behaviour depends on a callback being present.
Memory: the bpf LSM declares an inode security blob of one pointer
(bpf_lsm_blob_sizes.lbs_inode) for bpf inode local storage, allocated
per inode regardless of whether a program is loaded. The former task
blob and task_free hook were removed upstream in late 2024, so no
per-task cost remains.
Privilege: enabling the LSM allows processes holding CAP_BPF and
CAP_MAC_ADMIN to attach programs to LSM security hooks. Nothing changes
for unprivileged users.
Always-on hook: bpf_inode_storage_free is registered directly on
inode_free_security and runs on inode teardown irrespective of attach
state. It is a single pointer check when no storage is in use.
[Other Info]
Origin of the current state: LP: #1905975 enabled CONFIG_BPF_LSM and
documents why bpf was left out of CONFIG_LSM.
Precedent: LP: #1953192 added landlock to CONFIG_LSM by exactly this
route (annotations change plus patch to kernel-team@, filed and mailed
the same day). An earlier request for the same landlock change, LP:
#1950381, and three prior requests for bpf, LP: #1964941 (2022), LP:
#2036281 (2023, "activate bpf LSM by default") and LP: #2054810 (2024, a
repost of #1964941 after it expired, asking for 24.04 LTS), went
unactioned. This is the fourth time the request has been made.
Other distributions: every other major distribution initializes the bpf
LSM by default. Ubuntu is the outlier.
RHEL / Fedora (and Rocky, AlmaLinux as rebuilds):
CONFIG_LSM="lockdown,yama,integrity,selinux,bpf"
Enabled March 2021 via kernel-ark MR 922, whose rationale reads:
"It should have almost no performance impact unless userspace
attaches some BPF programs to the hooks."
SUSE (SLES 16 / openSUSE):
CONFIG_LSM="landlock,lockdown,yama,integrity,selinux,bpf"
Debian:
CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo,bpf,ipe"
Arch:
CONFIG_LSM="landlock,lockdown,yama,integrity,bpf"
Oracle Linux Server 10.1:
CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity,selinux,
smack,tomoyo,apparmor,bpf"
added bpf to CONFIG_LSM in an errata release (UEK R7U3); release notes
state it
"previously required setting the lsm=bpf boot command line option".
Upstream references:
520b7aa00d8c ("bpf: lsm: Initialize the BPF LSM hooks")
417c5643cd67 ("lsm: replace indirect LSM hook calls with static calls")
** Affects: linux (Ubuntu)
Importance: Undecided
Status: New
** Tags: resolute
** Tags added: resolute
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2166235
Title:
append bpf to CONFIG_LSM
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2166235/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs