[PATCH] LSM: check if lsmprop_to_secctx call is supported by LSM
Sebastian Bockholt
sebastian.bockholt at bevuta.com
Thu Jun 25 15:24:07 UTC 2026
On Wed Jun 24, 2026 at 9:36 PM CEST, Casey Schaufler wrote:
> On 6/24/2026 10:44 AM, Sebastian Bockholt wrote:
>> On Fri Jun 19, 2026 at 7:44 PM CEST, Casey Schaufler wrote:
>>> If you want to help with the multiple LSM support, there's still
>>> plenty of work to do. Let me know.
>> This is my first time trying to contribute to the kernel. If this is the wrong
>> mailing list or wrong format to discuss this, please tell me directly.
>
> You have come to the right place.
>
Thank you and very much appreciated.
>>> If the BPF LSM (the BPF LSM infrastructure, not the eBPF programs)
>>> is going to support security contexts you need to mark it
>>> LSM_FLAGS_EXCLUSIVE.
>> [...]
>>
>>> Until then your choices are:
>>>
>>> - Make the BPF LSM exclusive
>>> - Do not use any of the security context or secid based hooks
>>>
>> I am not trying to load any BPF myself but I am debugging issues when using
>> auditd and apparmor in parallel.
>
> Where does BPF appear in your LSM order?
>
> % cat /sys/kernel/security/lsm
>
> If bpf shows up ahead of apparmor you will see this problem.
>
You were right:
% cat /sys/kernel/security/lsm
capability,landlock,yama,bpf,apparmor
Reordering the LSM order to capability,landlock,yama,apparmor,bpf fixed
the issue.
Thank you
>> As soon as I try to load audit rules from
>> userspace our logs get spammed with "error in audit_log_subj_ctx" messages.
>> According to my analysis, the function call chain leading to the bug is:
>>
>> 1. audit_log_subj_ctx defined in kernel/audit.c
>> // the only LSM enabled is apparmor -> audit_subj_secctx_cnt == 1
>> // confirmed using bpftrace
>> if (audit_subj_secctx_cnt < 2) {
>> error = security_lsmprop_to_secctx(prop, &ctx, LSM_ID_UNDEF);
>> if (error < 0) {
>> if (error != -EINVAL)
>> goto error_path; // produces err msgs in logs
>> return 0;
>> }
>> audit_log_format(ab, " subj=%s", ctx.context);
>> security_release_secctx(&ctx);
>> }
>>
>> 2. security_lsmprop_to_secctx defined in security/security.c
>> // lsm_for_each_hook iterates over all registered LSMs
>> // lsm_id == LSM_ID_UNDEF -> the first lsmprop_to_secctx hook is used
>> // tracing the following probes using bpftrace
>> // kretprobe:apparmor_lsmprop_to_secctx
>> // kretprobe:selinux_lsmprop_to_secctx
>> // kretprobe:smack_lsmprop_to_secctx
>> // kretprobe:bpf_lsm_lsmprop_to_secctx
>> // kretprobe:security_lsmprop_to_scctx
>> // bpf_lsm_lsmprop_to_secctx hook is executed and returns -EOPNOTSUPP
>> lsm_for_each_hook(scall, lsmprop_to_secctx) {
>> if (lsmid != LSM_ID_UNDEF && lsmid != scall->hl->lsmid->id)
>> continue;
>> return scall->hl->hook.lsmprop_to_secctx(prop, cp);
>> }
>>
>> 3. bpf_lsm_lsmprop_to_secctx
>> is defined through #include <linux/lsm_hook_defs.h> and returns
>> -EOPNOTSUPP default. The return value is propagated up the call stack
>> up to security_lsmprop_to_secctx and then to audit_log_subj_ctx.
>> audit_log_subj_ctx checks for error return values and prints the
>> audit_panic "error in audit_log_subj_ctx"
>>
>> My patch could check for any errors or lsmprop_to_secctx but since some might
>> be useful to check by another function in the call stack, i decided to only
>> check if the hook is supported by the LSM.
More information about the Linux-security-module-archive
mailing list