For the English version of this alert, click here.
Allele Security Alert
ASA-2019-00654
Identificador(es)
ASA-2019-00654, CVE-2019-19602, CID-59c4bd853abc
Título
Corrupção de memória devido ao uso de fpu_fpregs_owner_ctx em cache
Fabricante(s)
Linux foundation
Produto(s)
Linux kernel
Versão(ões) afetada(s)
Linux kernel versões 5.4.x anteriores a 5.4.2
Linux kernel versões 5.3.x anteriores a 5.3.15
Linux kernel versões com o seguinte commit aplicado:
x86/fpu: Defer FPU state load until return to userspace
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5f409e20b794565e2d60ad333e79334630a6c798
Versão(ões) corrigida(s)
Linux kernel versão 5.4.2
Linux kernel versão 5.3.15
Linux kernel versões com o seguinte commit aplicado:
x86/fpu: Don’t cache access to fpu_fpregs_owner_ctx
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=59c4bd853abcea95eccc167a7d7fd5f1a5f47b98
Prova de Conceito
Desconhecido
Descrição
fpregs_state_valid em arch/x86/include/asm/fpu/internal.h no kernel do Linux, quando o GCC 9 é usado, permite que atacantes dependentes de contexto causem uma negação de serviço (corrupção de memória) ou possivelmente tenham outro impacto não especificado devido ao incorreto armazenamento de fpu_fpregs_owner_ctx em cache, conforme demonstrado pelo manuseio incorreto da preempção não cooperativa baseada em sinal no Go 1.14 prereleases no amd64.
Detalhes técnicos
O estado/proprietário da FPU é salvo em fpu_fpregs_owner_ctx apontando para o contexto que está carregado no momento. Ele nunca muda durante a vida útil de uma tarefa – permaneceu estável/constante.
Depois que foi implementado o carregamento adiado dos registradores da FPU até o retorno para userland, o conteúdo de fpu_fpregs_owner_ctx pode mudar durante a preempção e não deve ser armazenado em cache.
Isso passou despercebido por algum tempo e agora foi percebido, principalmente porque o gcc 9 está armazenando em cache esse carregamento em copy_fpstate_to_sigframe() e reutilizando-o no loop de nova tentativa:
copy_fpstate_to_sigframe() load fpu_fpregs_owner_ctx and save on stack fpregs_lock() copy_fpregs_to_sigframe() /* failed */ fpregs_unlock() *** PREEMPTION, another uses FPU, changes fpu_fpregs_owner_ctx *** fault_in_pages_writeable() /* succeed, retry */ fpregs_lock() __fpregs_load_activate() fpregs_state_valid() /* uses fpu_fpregs_owner_ctx from stack */ copy_fpregs_to_sigframe() /* succeeds, random FPU content */
Esta é uma comparação do assembly produzido pelo gcc 9, sem e com este patch:
| # arch/x86/kernel/fpu/signal.c:173: if (!access_ok(buf, size)) | cmpq %rdx, %rax # tmp183, _4 | jb .L190 #, |-# arch/x86/include/asm/fpu/internal.h:512: return fpu == this_cpu_read_stable(fpu_fpregs_owner_ctx) && cpu == fpu->last_cpu; |-#APP |-# 512 "arch/x86/include/asm/fpu/internal.h" 1 |- movq %gs:fpu_fpregs_owner_ctx,%rax #, pfo_ret__ |-# 0 "" 2 |-#NO_APP |- movq %rax, -88(%rbp) # pfo_ret__, %sfp … |-# arch/x86/include/asm/fpu/internal.h:512: return fpu == this_cpu_read_stable(fpu_fpregs_owner_ctx) && cpu == fpu->last_cpu; |- movq -88(%rbp), %rcx # %sfp, pfo_ret__ |- cmpq %rcx, -64(%rbp) # pfo_ret__, %sfp |+# arch/x86/include/asm/fpu/internal.h:512: return fpu == this_cpu_read(fpu_fpregs_owner_ctx) && cpu == fpu->last_cpu; |+#APP |+# 512 "arch/x86/include/asm/fpu/internal.h" 1 |+ movq %gs:fpu_fpregs_owner_ctx(%rip),%rax # fpu_fpregs_owner_ctx, pfo_ret__ |+# 0 "" 2 |+# arch/x86/include/asm/fpu/internal.h:512: return fpu == this_cpu_read(fpu_fpregs_owner_ctx) && cpu == fpu->last_cpu; |+#NO_APP |+ cmpq %rax, -64(%rbp) # pfo_ret__, %sfp
Créditos
The Go Team
Referência(s)
AVX register corruption from signal delivery
https://bugzilla.kernel.org/show_bug.cgi?id=205663
x86/fpu: Don’t cache access to fpu_fpregs_owner_ctx
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=59c4bd853abcea95eccc167a7d7fd5f1a5f47b98
x86/fpu: Don’t cache access to fpu_fpregs_owner_ctx
https://github.com/torvalds/linux/commit/59c4bd853abcea95eccc167a7d7fd5f1a5f47b98
x86/fpu: Defer FPU state load until return to userspace
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5f409e20b794565e2d60ad333e79334630a6c798
x86/fpu: Defer FPU state load until return to userspace
https://github.com/torvalds/commit/5f409e20b794565e2d60ad333e79334630a6c798
runtime: memory corruption on Linux 5.2+ #35777
https://github.com/golang/go/issues/35777
AVX register corruption from signal delivery
https://lore.kernel.org/lkml/c87e93c3-5f30-f242-74b7-6c7ccc91158a@google.com/
Linux 5.4.2
https://cdn.kernel.org/pub/linux/kernel/v5.x/ChangeLog-5.4.2
Linux 5.3.15
https://cdn.kernel.org/pub/linux/kernel/v5.x/ChangeLog-5.3.15
https://access.redhat.com/security/cve/CVE-2019-19602
CVE-2019-19602
https://security-tracker.debian.org/tracker/CVE-2019-19602
CVE-2019-19602 | SUSE
https://www.suse.com/security/cve/CVE-2019-19602
CVE-2019-19602 in Ubuntu
https://people.canonical.com/~ubuntu-security/cve/CVE-2019-19602.html
CVE-2019-19602
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-19602
CVE-2019-19602
https://nvd.nist.gov/vuln/detail/CVE-2019-19602
Se encontrou algum erro neste alerta ou deseja uma análise compreensiva, entre em contato.
Última modificação: 11 fevereiro 2020