Vulnerabilidad en Kernel de Linux (CVE-2021-47069)
Gravedad CVSS v3.1:
ALTA
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
01/03/2024
Última modificación:
09/01/2025
Descripción
En el kernel de Linux, se resolvió la siguiente vulnerabilidad: ipc/mqueue, msg, sem: evite confiar en una referencia de pila después de su vencimiento do_mq_timedreceive llama a wq_sleep con una dirección local de pila. El remitente (do_mq_timedsend) usa esta dirección para luego llamar a pipelined_send. Esto conduce a una ejecución muy difícil de desencadenar en la que una llamada do_mq_timedreceive puede regresar y dejar que do_mq_timedsend dependa de una dirección no válida, lo que provoca el siguiente bloqueo: RIP: 0010:wake_q_add_safe+0x13/0x60 Seguimiento de llamadas: __x64_sys_mq_timedsend+0x2a9/0x490 do_syscall_64+0x80 /0x680 Entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x7f5928e40343 La ejecución ocurre como: 1. do_mq_timedreceive llama a wq_sleep con la dirección de `struct ext_wait_queue` en la pila de funciones (alias `ewq_addr` aquí): contiene una `struct ext_wait_queue * válida ` siempre y cuando la pila no haya sido sobrescrita. 2. `ewq_addr` se agrega a info->e_wait_q[RECV].list en wq_add, y do_mq_timedsend lo recibe a través de wq_get_first_waiter(info, RECV) para llamar a __pipelined_op. 3. El remitente llama a __pipelined_op::smp_store_release(&this->state, STATE_READY). Aquí es donde comienza la ventana de ejecución. (`esto` es `ewq_addr`.) 4. Si el receptor se activa ahora en do_mq_timedreceive::wq_sleep, verá `state == STATE_READY` y se interrumpirá. 5. do_mq_timedreceive regresa y ya no se garantiza que `ewq_addr` sea una `struct ext_wait_queue *` ya que estaba en la pila de do_mq_timedreceive. (Aunque es posible que la dirección no se sobrescriba hasta que otra función la toque, lo que significa que puede persistir por un tiempo indefinido). 6. do_mq_timedsend::__pipelined_op() todavía cree que `ewq_addr` es una `struct ext_wait_queue *`, y lo usa para encontrar una task_struct para pasar a la llamada wake_q_add_safe. En el afortunado caso de que nada haya sobrescrito `ewq_addr` todavía, `ewq_addr->task` es la estructura de tarea correcta. En el desafortunado caso, __pipelined_op::wake_q_add_safe recibe una dirección falsa como la task_struct del receptor que causa el bloqueo. do_mq_timedsend::__pipelined_op() no debe eliminar la referencia a "esto" después de configurar STATE_READY, ya que la contraparte del receptor ahora puede regresar. Cambie __pipelined_op para llamar a wake_q_add_safe en el task_struct del receptor devuelto por get_task_struct, en lugar de desreferenciar "this" que se encuentra en la pila del receptor. Como señaló Manfred, la ejecución también existe potencialmente en ipc/msg.c::expunge_all e ipc/sem.c::wake_up_sem_queue_prepare. Arréglelos de la misma manera.
Impacto
Puntuación base 3.x
7.00
Gravedad 3.x
ALTA
Productos y versiones vulnerables
CPE | Desde | Hasta |
---|---|---|
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.6 (incluyendo) | 5.10.40 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.11 (incluyendo) | 5.12.7 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:5.13:rc1:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:5.13:rc2:*:*:*:*:*:* |
Para consultar la lista completa de nombres de CPE con productos y versiones, ver esta página
Referencias a soluciones, herramientas e información
- https://git.kernel.org/stable/c/4528c0c323085e645b8765913b4a7fd42cf49b65
- https://git.kernel.org/stable/c/807fa14536b26803b858da878b643be72952a097
- https://git.kernel.org/stable/c/a11ddb37bf367e6b5239b95ca759e5389bb46048
- https://git.kernel.org/stable/c/4528c0c323085e645b8765913b4a7fd42cf49b65
- https://git.kernel.org/stable/c/807fa14536b26803b858da878b643be72952a097
- https://git.kernel.org/stable/c/a11ddb37bf367e6b5239b95ca759e5389bb46048