cve-2021-47128
Vulnerability from cvelistv5
Published
2024-03-15 20:14
Modified
2024-11-04 11:59
Severity ?
EPSS score ?
Summary
bpf, lockdown, audit: Fix buggy SELinux lockdown permission checks
References
{ "containers": { "adp": [ { "metrics": [ { "other": { "content": { "id": "CVE-2021-47128", "options": [ { "Exploitation": "none" }, { "Automatable": "no" }, { "Technical Impact": "partial" } ], "role": "CISA Coordinator", "timestamp": "2024-03-18T18:49:12.497745Z", "version": "2.0.3" }, "type": "ssvc" } } ], "providerMetadata": { "dateUpdated": "2024-06-04T17:14:25.049Z", "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "shortName": "CISA-ADP" }, "title": "CISA ADP Vulnrichment" }, { "providerMetadata": { "dateUpdated": "2024-08-04T05:24:39.912Z", "orgId": "af854a3a-2127-422b-91ae-364da2661108", "shortName": "CVE" }, "references": [ { "tags": [ "x_transferred" ], "url": "https://git.kernel.org/stable/c/ff5039ec75c83d2ed5b781dc7733420ee8c985fc" }, { "tags": [ "x_transferred" ], "url": "https://git.kernel.org/stable/c/acc43fc6cf0d50612193813c5906a1ab9d433e1e" }, { "tags": [ "x_transferred" ], "url": "https://git.kernel.org/stable/c/ff40e51043af63715ab413995ff46996ecf9583f" } ], "title": "CVE Program Container" } ], "cna": { "affected": [ { "defaultStatus": "unaffected", "product": "Linux", "programFiles": [ "kernel/bpf/helpers.c", "kernel/trace/bpf_trace.c" ], "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "vendor": "Linux", "versions": [ { "lessThan": "ff5039ec75c8", "status": "affected", "version": "59438b46471a", "versionType": "git" }, { "lessThan": "acc43fc6cf0d", "status": "affected", "version": "59438b46471a", "versionType": "git" }, { "lessThan": "ff40e51043af", "status": "affected", "version": "59438b46471a", "versionType": "git" } ] }, { "defaultStatus": "affected", "product": "Linux", "programFiles": [ "kernel/bpf/helpers.c", "kernel/trace/bpf_trace.c" ], "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "vendor": "Linux", "versions": [ { "status": "affected", "version": "5.6" }, { "lessThan": "5.6", "status": "unaffected", "version": "0", "versionType": "semver" }, { "lessThanOrEqual": "5.10.*", "status": "unaffected", "version": "5.10.43", "versionType": "semver" }, { "lessThanOrEqual": "5.12.*", "status": "unaffected", "version": "5.12.10", "versionType": "semver" }, { "lessThanOrEqual": "*", "status": "unaffected", "version": "5.13", "versionType": "original_commit_for_fix" } ] } ], "descriptions": [ { "lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nbpf, lockdown, audit: Fix buggy SELinux lockdown permission checks\n\nCommit 59438b46471a (\"security,lockdown,selinux: implement SELinux lockdown\")\nadded an implementation of the locked_down LSM hook to SELinux, with the aim\nto restrict which domains are allowed to perform operations that would breach\nlockdown. This is indirectly also getting audit subsystem involved to report\nevents. The latter is problematic, as reported by Ondrej and Serhei, since it\ncan bring down the whole system via audit:\n\n 1) The audit events that are triggered due to calls to security_locked_down()\n can OOM kill a machine, see below details [0].\n\n 2) It also seems to be causing a deadlock via avc_has_perm()/slow_avc_audit()\n when trying to wake up kauditd, for example, when using trace_sched_switch()\n tracepoint, see details in [1]. Triggering this was not via some hypothetical\n corner case, but with existing tools like runqlat \u0026 runqslower from bcc, for\n example, which make use of this tracepoint. Rough call sequence goes like:\n\n rq_lock(rq) -\u003e -------------------------+\n trace_sched_switch() -\u003e |\n bpf_prog_xyz() -\u003e +-\u003e deadlock\n selinux_lockdown() -\u003e |\n audit_log_end() -\u003e |\n wake_up_interruptible() -\u003e |\n try_to_wake_up() -\u003e |\n rq_lock(rq) --------------+\n\nWhat\u0027s worse is that the intention of 59438b46471a to further restrict lockdown\nsettings for specific applications in respect to the global lockdown policy is\ncompletely broken for BPF. The SELinux policy rule for the current lockdown check\nlooks something like this:\n\n allow \u003cwho\u003e \u003cwho\u003e : lockdown { \u003creason\u003e };\n\nHowever, this doesn\u0027t match with the \u0027current\u0027 task where the security_locked_down()\nis executed, example: httpd does a syscall. There is a tracing program attached\nto the syscall which triggers a BPF program to run, which ends up doing a\nbpf_probe_read_kernel{,_str}() helper call. The selinux_lockdown() hook does\nthe permission check against \u0027current\u0027, that is, httpd in this example. httpd\nhas literally zero relation to this tracing program, and it would be nonsensical\nhaving to write an SELinux policy rule against httpd to let the tracing helper\npass. The policy in this case needs to be against the entity that is installing\nthe BPF program. For example, if bpftrace would generate a histogram of syscall\ncounts by user space application:\n\n bpftrace -e \u0027tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }\u0027\n\nbpftrace would then go and generate a BPF program from this internally. One way\nof doing it [for the sake of the example] could be to call bpf_get_current_task()\nhelper and then access current-\u003ecomm via one of bpf_probe_read_kernel{,_str}()\nhelpers. So the program itself has nothing to do with httpd or any other random\napp doing a syscall here. The BPF program _explicitly initiated_ the lockdown\ncheck. The allow/deny policy belongs in the context of bpftrace: meaning, you\nwant to grant bpftrace access to use these helpers, but other tracers on the\nsystem like my_random_tracer _not_.\n\nTherefore fix all three issues at the same time by taking a completely different\napproach for the security_locked_down() hook, that is, move the check into the\nprogram verification phase where we actually retrieve the BPF func proto. This\nalso reliably gets the task (current) that is trying to install the BPF tracing\nprogram, e.g. bpftrace/bcc/perf/systemtap/etc, and it also fixes the OOM since\nwe\u0027re moving this out of the BPF helper\u0027s fast-path which can be called several\nmillions of times per second.\n\nThe check is then also in line with other security_locked_down() hooks in the\nsystem where the enforcement is performed at open/load time, for example,\nopen_kcore() for /proc/kcore access or module_sig_check() for module signatures\njust to pick f\n---truncated---" } ], "providerMetadata": { "dateUpdated": "2024-11-04T11:59:57.780Z", "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "shortName": "Linux" }, "references": [ { "url": "https://git.kernel.org/stable/c/ff5039ec75c83d2ed5b781dc7733420ee8c985fc" }, { "url": "https://git.kernel.org/stable/c/acc43fc6cf0d50612193813c5906a1ab9d433e1e" }, { "url": "https://git.kernel.org/stable/c/ff40e51043af63715ab413995ff46996ecf9583f" } ], "title": "bpf, lockdown, audit: Fix buggy SELinux lockdown permission checks", "x_generator": { "engine": "bippy-9e1c9544281a" } } }, "cveMetadata": { "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "assignerShortName": "Linux", "cveId": "CVE-2021-47128", "datePublished": "2024-03-15T20:14:32.366Z", "dateReserved": "2024-03-04T18:12:48.839Z", "dateUpdated": "2024-11-04T11:59:57.780Z", "state": "PUBLISHED" }, "dataType": "CVE_RECORD", "dataVersion": "5.1", "meta": { "nvd": "{\"cve\":{\"id\":\"CVE-2021-47128\",\"sourceIdentifier\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"published\":\"2024-03-15T21:15:07.470\",\"lastModified\":\"2024-03-17T22:38:29.433\",\"vulnStatus\":\"Awaiting Analysis\",\"descriptions\":[{\"lang\":\"en\",\"value\":\"In the Linux kernel, the following vulnerability has been resolved:\\n\\nbpf, lockdown, audit: Fix buggy SELinux lockdown permission checks\\n\\nCommit 59438b46471a (\\\"security,lockdown,selinux: implement SELinux lockdown\\\")\\nadded an implementation of the locked_down LSM hook to SELinux, with the aim\\nto restrict which domains are allowed to perform operations that would breach\\nlockdown. This is indirectly also getting audit subsystem involved to report\\nevents. The latter is problematic, as reported by Ondrej and Serhei, since it\\ncan bring down the whole system via audit:\\n\\n 1) The audit events that are triggered due to calls to security_locked_down()\\n can OOM kill a machine, see below details [0].\\n\\n 2) It also seems to be causing a deadlock via avc_has_perm()/slow_avc_audit()\\n when trying to wake up kauditd, for example, when using trace_sched_switch()\\n tracepoint, see details in [1]. Triggering this was not via some hypothetical\\n corner case, but with existing tools like runqlat \u0026 runqslower from bcc, for\\n example, which make use of this tracepoint. Rough call sequence goes like:\\n\\n rq_lock(rq) -\u003e -------------------------+\\n trace_sched_switch() -\u003e |\\n bpf_prog_xyz() -\u003e +-\u003e deadlock\\n selinux_lockdown() -\u003e |\\n audit_log_end() -\u003e |\\n wake_up_interruptible() -\u003e |\\n try_to_wake_up() -\u003e |\\n rq_lock(rq) --------------+\\n\\nWhat\u0027s worse is that the intention of 59438b46471a to further restrict lockdown\\nsettings for specific applications in respect to the global lockdown policy is\\ncompletely broken for BPF. The SELinux policy rule for the current lockdown check\\nlooks something like this:\\n\\n allow \u003cwho\u003e \u003cwho\u003e : lockdown { \u003creason\u003e };\\n\\nHowever, this doesn\u0027t match with the \u0027current\u0027 task where the security_locked_down()\\nis executed, example: httpd does a syscall. There is a tracing program attached\\nto the syscall which triggers a BPF program to run, which ends up doing a\\nbpf_probe_read_kernel{,_str}() helper call. The selinux_lockdown() hook does\\nthe permission check against \u0027current\u0027, that is, httpd in this example. httpd\\nhas literally zero relation to this tracing program, and it would be nonsensical\\nhaving to write an SELinux policy rule against httpd to let the tracing helper\\npass. The policy in this case needs to be against the entity that is installing\\nthe BPF program. For example, if bpftrace would generate a histogram of syscall\\ncounts by user space application:\\n\\n bpftrace -e \u0027tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }\u0027\\n\\nbpftrace would then go and generate a BPF program from this internally. One way\\nof doing it [for the sake of the example] could be to call bpf_get_current_task()\\nhelper and then access current-\u003ecomm via one of bpf_probe_read_kernel{,_str}()\\nhelpers. So the program itself has nothing to do with httpd or any other random\\napp doing a syscall here. The BPF program _explicitly initiated_ the lockdown\\ncheck. The allow/deny policy belongs in the context of bpftrace: meaning, you\\nwant to grant bpftrace access to use these helpers, but other tracers on the\\nsystem like my_random_tracer _not_.\\n\\nTherefore fix all three issues at the same time by taking a completely different\\napproach for the security_locked_down() hook, that is, move the check into the\\nprogram verification phase where we actually retrieve the BPF func proto. This\\nalso reliably gets the task (current) that is trying to install the BPF tracing\\nprogram, e.g. bpftrace/bcc/perf/systemtap/etc, and it also fixes the OOM since\\nwe\u0027re moving this out of the BPF helper\u0027s fast-path which can be called several\\nmillions of times per second.\\n\\nThe check is then also in line with other security_locked_down() hooks in the\\nsystem where the enforcement is performed at open/load time, for example,\\nopen_kcore() for /proc/kcore access or module_sig_check() for module signatures\\njust to pick f\\n---truncated---\"},{\"lang\":\"es\",\"value\":\"En el kernel de Linux, se resolvi\u00f3 la siguiente vulnerabilidad: bpf, bloqueo, auditor\u00eda: se corrigieron las comprobaciones de permisos de bloqueo de SELinux con errores. El commit 59438b46471a (\\\"seguridad, bloqueo, selinux: implementar bloqueo de SELinux\\\") agreg\u00f3 una implementaci\u00f3n del gancho LSM lock_down a SELinux. con el objetivo de restringir qu\u00e9 dominios pueden realizar operaciones que violar\u00edan el bloqueo. Indirectamente, esto tambi\u00e9n implica involucrar al subsistema de auditor\u00eda para informar eventos. Esto \u00faltimo es problem\u00e1tico, como informaron Ondrej y Serhei, ya que puede hacer caer todo el sistema a trav\u00e9s de una auditor\u00eda: 1) Los eventos de auditor\u00eda que se activan debido a llamadas a security_locked_down() pueden OOM matar una m\u00e1quina, vea los detalles a continuaci\u00f3n [0] . 2) Tambi\u00e9n parece estar causando un punto muerto a trav\u00e9s 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\u00f3 a trav\u00e9s de alg\u00fan caso hipot\u00e9tico 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\u00ed: rq_lock(rq) -\u0026gt; -------------------------+ trace_sched_switch() -\u0026gt; | bpf_prog_xyz() -\u0026gt; +-\u0026gt; punto muerto selinux_lockdown() -\u0026gt; | audit_log_end() -\u0026gt; | wake_up_interruptible() -\u0026gt; | try_to_wake_up() -\u0026gt; | rq_lock(rq) --------------+ Lo que es peor es que la intenci\u00f3n de 59438b46471a de restringir a\u00fan m\u00e1s la configuraci\u00f3n de bloqueo para aplicaciones espec\u00edficas con respecto a la pol\u00edtica de bloqueo global no es v\u00e1lida para BPF. La regla de pol\u00edtica de SELinux para la verificaci\u00f3n de bloqueo actual se parece a esto: permitir : bloqueo { }; Sin embargo, esto no coincide con la tarea \u0027actual\u0027 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\u00f3n de un programa BPF, que termina realizando una llamada de ayuda bpf_probe_read_kernel{,_str}(). El gancho selinux_lockdown() realiza la verificaci\u00f3n de permisos con respecto a \u0027actual\u0027, es decir, httpd en este ejemplo. httpd tiene literalmente cero relaci\u00f3n con este programa de rastreo, y no tendr\u00eda sentido tener que escribir una regla de pol\u00edtica SELinux contra httpd para permitir que pase el asistente de rastreo. La pol\u00edtica en este caso debe ser contra la entidad que est\u00e1 instalando el programa BPF. Por ejemplo, si bpftrace generara un histograma de recuentos de llamadas al sistema por aplicaci\u00f3n de espacio de usuario: bpftrace -e \u0027tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }\u0027 bpftrace luego generar\u00eda un programa BPF a partir de esto internamente. Una forma de hacerlo [por el bien del ejemplo] podr\u00eda ser llamar al asistente bpf_get_current_task() y luego acceder a current-\u0026gt;comm a trav\u00e9s de uno de los asistentes bpf_probe_read_kernel{,_str}(). Entonces, el programa en s\u00ed no tiene nada que ver con httpd o cualquier otra aplicaci\u00f3n aleatoria que realice una llamada al sistema aqu\u00ed. El programa BPF _inici\u00f3 expl\u00edcitamente_ la verificaci\u00f3n del bloqueo. La pol\u00edtica 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\u00f3n a la fase de verificaci\u00f3n del programa donde realmente recuperamos el protocolo de funci\u00f3n BPF. Esto tambi\u00e9n obtiene de manera confiable la tarea (actual) que est\u00e1 intentando instalar el programa de rastreo de BPF, por ejemplo, bpftrace/bcc/perf/systemtap/etc,---truncado---\"}],\"metrics\":{},\"references\":[{\"url\":\"https://git.kernel.org/stable/c/acc43fc6cf0d50612193813c5906a1ab9d433e1e\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/ff40e51043af63715ab413995ff46996ecf9583f\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/ff5039ec75c83d2ed5b781dc7733420ee8c985fc\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"}]}}" } }
Loading...
Loading...
- Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
- Confirmed: The vulnerability is confirmed from an analyst perspective.
- Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
- Patched: This vulnerability was successfully patched by the user reporting the sighting.
- Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
- Not confirmed: The user expresses doubt about the veracity of the vulnerability.
- Not patched: This vulnerability was not successfully patched by the user reporting the sighting.