Lucene search

K
ubuntucveUbuntu.comUB:CVE-2021-47128
HistoryMar 15, 2024 - 12:00 a.m.

CVE-2021-47128

2024-03-1500:00:00
ubuntu.com
ubuntu.com
5
linux kernel
selinux
oom
deadlock
audit
bpf

6.5 Medium

AI Score

Confidence

High

0.0004 Low

EPSS

Percentile

15.7%

In the Linux kernel, the following vulnerability has been resolved: bpf,
lockdown, audit: Fix buggy SELinux lockdown permission checks Commit
59438b46471a (“security,lockdown,selinux: implement SELinux lockdown”)
added an implementation of the locked_down LSM hook to SELinux, with the
aim to restrict which domains are allowed to perform operations that would
breach lockdown. This is indirectly also getting audit subsystem involved
to report events. The latter is problematic, as reported by Ondrej and
Serhei, since it can bring down the whole system via audit: 1) The audit
events that are triggered due to calls to security_locked_down() can OOM
kill a machine, see below details [0]. 2) It also seems to be causing a
deadlock via avc_has_perm()/slow_avc_audit() when trying to wake up
kauditd, for example, when using trace_sched_switch() tracepoint, see
details in [1]. Triggering this was not via some hypothetical corner case,
but with existing tools like runqlat & runqslower from bcc, for example,
which make use of this tracepoint. Rough call sequence goes like:
rq_lock(rq) -> -------------------------+ trace_sched_switch() -> |
bpf_prog_xyz() -> ±> deadlock selinux_lockdown() -> | audit_log_end() -> |
wake_up_interruptible() -> | try_to_wake_up() -> | rq_lock(rq)
--------------+ What’s worse is that the intention of 59438b46471a to
further restrict lockdown settings for specific applications in respect to
the global lockdown policy is completely broken for BPF. The SELinux policy
rule for the current lockdown check looks something like this: allow <who>
<who> : lockdown { <reason> }; However, this doesn’t match with the
‘current’ task where the security_locked_down() is executed, example: httpd
does a syscall. There is a tracing program attached to the syscall which
triggers a BPF program to run, which ends up doing a
bpf_probe_read_kernel{,_str}() helper call. The selinux_lockdown() hook
does the permission check against ‘current’, that is, httpd in this
example. httpd has literally zero relation to this tracing program, and it
would be nonsensical having to write an SELinux policy rule against httpd
to let the tracing helper pass. The policy in this case needs to be against
the entity that is installing the BPF program. For example, if bpftrace
would generate a histogram of syscall counts by user space application:
bpftrace -e ‘tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }’
bpftrace would then go and generate a BPF program from this internally. One
way of doing it [for the sake of the example] could be to call
bpf_get_current_task() helper and then access current->comm via one of
bpf_probe_read_kernel{,_str}() helpers. So the program itself has nothing
to do with httpd or any other random app doing a syscall here. The BPF
program explicitly initiated the lockdown check. The allow/deny policy
belongs in the context of bpftrace: meaning, you want to grant bpftrace
access to use these helpers, but other tracers on the system like
my_random_tracer not. Therefore fix all three issues at the same time by
taking a completely different approach for the security_locked_down() hook,
that is, move the check into the program verification phase where we
actually retrieve the BPF func proto. This also reliably gets the task
(current) that is trying to install the BPF tracing program, e.g.
bpftrace/bcc/perf/systemtap/etc, and it also fixes the OOM since we’re
moving this out of the BPF helper’s fast-path which can be called several
millions of times per second. The check is then also in line with other
security_locked_down() hooks in the system where the enforcement is
performed at open/load time, for example, open_kcore() for /proc/kcore
access or module_sig_check() for module signatures just to pick f
—truncated—

6.5 Medium

AI Score

Confidence

High

0.0004 Low

EPSS

Percentile

15.7%