Instituto Nacional de ciberseguridad. Sección Incibe
Instituto Nacional de Ciberseguridad. Sección INCIBE-CERT

Vulnerabilidad en kernel de Linux (CVE-2021-47465)

Gravedad CVSS v3.1:
MEDIA
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
22/05/2024
Última modificación:
24/09/2025

Descripción

En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: KVM: PPC: Book3S HV: Arreglar el manejo de la pila en idle_kvm_start_guest() En el commit 10d91611f426 ("powerpc/64s: Reimplementar el código inactivo de book3s en C") kvm_start_guest() se convirtió en idle_kvm_start_guest() . El código antiguo asignaba un marco de pila en la pila de emergencia, pero no usaba el marco para almacenar nada y tampoco almacenaba nada en el marco de la persona que llama. idle_kvm_start_guest(), por otro lado, se escribe más como una función C normal, crea un marco al ingresar y también almacena CR/LR en el marco de la persona que llama (según la ABI). El problema es que no hay ningún marco de llamada en la pila de emergencia. La pila de emergencia para una CPU determinada se asigna con: paca_ptrs[i]->emergency_sp = alloc_stack(limit, i) + THREAD_SIZE; Entonces, Emergency_sp en realidad apunta a la primera dirección encima de la asignación de pila de emergencia para una CPU determinada; no debemos almacenar encima de ella sin primero disminuirla para crear un marco. Esto es diferente a la pila normal del kernel, paca->kstack, que se inicializa para apuntar a un marco inicial que está listo para usar. idle_kvm_start_guest() almacena la cadena posterior, CR y LR, todos los cuales escriben fuera de la asignación para la pila de emergencia. Luego crea un marco de pila y guarda los registros no volátiles. Desafortunadamente, el marco que crea no es lo suficientemente grande para acomodar los registros no volátiles, por lo que guardar los registros no volátiles también escribe fuera de la asignación de pila de emergencia. El resultado final es que corrompemos todo lo que esté entre 0 y 24 bytes y entre 112 y 248 bytes por encima de la asignación de pila de emergencia. En la práctica, esto ha pasado desapercibido porque la memoria inmediatamente encima de la pila de emergencia se usa para otras asignaciones de pila, ya sea otra CPU mc_emergency_sp o una pila IRQ. Vea el orden de las llamadas a irqstack_early_init() y Emergency_stack_init(). Las direcciones bajas de otra pila están en la parte superior de esa pila, por lo que solo se usan si esa pila está bajo una presión extrema, lo que esencialmente nunca sucede en la práctica, y si así fuera, existe una alta probabilidad de que fallemos debido a que esa pila se desborde. . Aún así, no deberíamos estar corrompiendo la pila de otra persona, y es pura suerte que no estemos corrompiendo algo más. Para solucionarlo, guardamos CR/LR en el marco de la persona que llama usando el r1 existente en la entrada, luego creamos un marco SWITCH_FRAME_SIZE (que tiene espacio para pt_regs) en la pila de emergencia con la cadena posterior apuntando a la pila existente, y finalmente cambiamos al nuevo marco en la pila de emergencia.

Productos y versiones vulnerables

CPE Desde Hasta
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.2 (incluyendo) 5.4.156 (excluyendo)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.5 (incluyendo) 5.10.76 (excluyendo)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.11 (incluyendo) 5.14.15 (excluyendo)
cpe:2.3:o:linux:linux_kernel:5.15:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.15:rc2:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.15:rc3:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.15:rc4:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.15:rc5:*:*:*:*:*:*