CVE-2021-47128

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---
Configurations

Configuration 1 (hide)

OR cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.13:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.13:rc2:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.13:rc3:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.13:rc4:*:*:*:*:*:*

History

13 Mar 2025, 21:24

Type Values Removed Values Added
References () https://git.kernel.org/stable/c/acc43fc6cf0d50612193813c5906a1ab9d433e1e - () https://git.kernel.org/stable/c/acc43fc6cf0d50612193813c5906a1ab9d433e1e - Patch
References () https://git.kernel.org/stable/c/ff40e51043af63715ab413995ff46996ecf9583f - () https://git.kernel.org/stable/c/ff40e51043af63715ab413995ff46996ecf9583f - Patch
References () https://git.kernel.org/stable/c/ff5039ec75c83d2ed5b781dc7733420ee8c985fc - () https://git.kernel.org/stable/c/ff5039ec75c83d2ed5b781dc7733420ee8c985fc - Patch
CWE CWE-667
First Time Linux linux Kernel
Linux
CPE cpe:2.3:o:linux:linux_kernel:5.13:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.13:rc4:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.13:rc3:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.13:rc2:*:*:*:*:*:*
CVSS v2 : unknown
v3 : unknown
v2 : unknown
v3 : 5.5

21 Nov 2024, 06:35

Type Values Removed Values Added
Summary
  • (es) En el kernel de Linux, se resolvió la siguiente vulnerabilidad: bpf, bloqueo, auditoría: se corrigieron las comprobaciones de permisos de bloqueo de SELinux con errores. El commit 59438b46471a ("seguridad, bloqueo, selinux: implementar bloqueo de SELinux") agregó una implementación del gancho LSM lock_down a SELinux. con el objetivo de restringir qué dominios pueden realizar operaciones que violarían el bloqueo. Indirectamente, esto también implica involucrar al subsistema de auditoría para informar eventos. Esto último es problemático, como informaron Ondrej y Serhei, ya que puede hacer caer todo el sistema a través de una auditoría: 1) Los eventos de auditoría que se activan debido a llamadas a security_locked_down() pueden OOM matar una máquina, vea los detalles a continuación [0] . 2) También parece estar causando un punto muerto a través de avc_has_perm()/slow_avc_audit() cuando se intenta activar kauditd, por ejemplo, cuando se usa el punto de seguimiento trace_sched_switch(), consulte los detalles en [1]. Esto no se activó a través de algún caso hipotético de esquina, sino con herramientas existentes como runqlat y runqslower de bcc, por ejemplo, que hacen uso de este punto de seguimiento. La secuencia de llamada aproximada es así: rq_lock(rq) -&gt; -------------------------+ trace_sched_switch() -&gt; | bpf_prog_xyz() -&gt; +-&gt; punto muerto selinux_lockdown() -&gt; | audit_log_end() -&gt; | wake_up_interruptible() -&gt; | try_to_wake_up() -&gt; | rq_lock(rq) --------------+ Lo que es peor es que la intención de 59438b46471a de restringir aún más la configuración de bloqueo para aplicaciones específicas con respecto a la política de bloqueo global no es válida para BPF. La regla de política de SELinux para la verificación de bloqueo actual se parece a esto: permitir : bloqueo { }; Sin embargo, esto no coincide con la tarea 'actual' donde se ejecuta security_locked_down(), ejemplo: httpd realiza una llamada al sistema. Hay un programa de seguimiento adjunto a la llamada al sistema que activa la ejecución de un programa BPF, que termina realizando una llamada de ayuda bpf_probe_read_kernel{,_str}(). El gancho selinux_lockdown() realiza la verificación de permisos con respecto a 'actual', es decir, httpd en este ejemplo. httpd tiene literalmente cero relación con este programa de rastreo, y no tendría sentido tener que escribir una regla de política SELinux contra httpd para permitir que pase el asistente de rastreo. La política en este caso debe ser contra la entidad que está instalando el programa BPF. Por ejemplo, si bpftrace generara un histograma de recuentos de llamadas al sistema por aplicación de espacio de usuario: bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }' bpftrace luego generaría un programa BPF a partir de esto internamente. Una forma de hacerlo [por el bien del ejemplo] podría ser llamar al asistente bpf_get_current_task() y luego acceder a current-&gt;comm a través de uno de los asistentes bpf_probe_read_kernel{,_str}(). Entonces, el programa en sí no tiene nada que ver con httpd o cualquier otra aplicación aleatoria que realice una llamada al sistema aquí. El programa BPF _inició explícitamente_ la verificación del bloqueo. La política de permitir/denegar pertenece al contexto de bpftrace: es decir, desea otorgar acceso a bpftrace para usar estos asistentes, pero otros rastreadores en el sistema como my_random_tracer _no_. Por lo tanto, solucione los tres problemas al mismo tiempo adoptando un enfoque completamente diferente para el enlace security_locked_down(), es decir, mueva la verificación a la fase de verificación del programa donde realmente recuperamos el protocolo de función BPF. Esto también obtiene de manera confiable la tarea (actual) que está intentando instalar el programa de rastreo de BPF, por ejemplo, bpftrace/bcc/perf/systemtap/etc,---truncado---
References () https://git.kernel.org/stable/c/acc43fc6cf0d50612193813c5906a1ab9d433e1e - () https://git.kernel.org/stable/c/acc43fc6cf0d50612193813c5906a1ab9d433e1e -
References () https://git.kernel.org/stable/c/ff40e51043af63715ab413995ff46996ecf9583f - () https://git.kernel.org/stable/c/ff40e51043af63715ab413995ff46996ecf9583f -
References () https://git.kernel.org/stable/c/ff5039ec75c83d2ed5b781dc7733420ee8c985fc - () https://git.kernel.org/stable/c/ff5039ec75c83d2ed5b781dc7733420ee8c985fc -

15 Mar 2024, 21:15

Type Values Removed Values Added
New CVE

Information

Published : 2024-03-15 21:15

Updated : 2025-03-13 21:24


NVD link : CVE-2021-47128

Mitre link : CVE-2021-47128

CVE.ORG link : CVE-2021-47128


JSON object : View

Products Affected

linux

  • linux_kernel
CWE
CWE-667

Improper Locking