Se ha identificado una vulnerabilidad en el núcleo de Linux (CVE-2022-0847) que permite sobrescribir el contenido de la caché de página para cualquier archivo, incluyendo aquellos en modo solo lectura, abiertos con el flag O_RDONLY o ubicados en sistemas de archivos montados en modo solo lectura. Desde un punto de vista práctico, la vulnerabilidad puede ser utilizada para inyectar código en procesos arbitrarios o alterar datos en archivos abiertos. Por ejemplo, se puede modificar el contenido del archivo authorized_keys para el proceso sshd. Se dispone de un prototipo de exploit para su prueba.
A la problemática se le ha asignado el nombre en clave Dirty Pipe, en analogía con la crítica vulnerabilidad Dirty COW descubierta en 2016. Se señala que, en términos de nivel de peligro, Dirty Pipe se sitúa a la par con Dirty COW, pero es considerablemente más fácil de explotar. La vulnerabilidad se identificó durante la revisión de quejas sobre la corrupción periódica de archivos descargados a través de la red en un sistema que carga archivos comprimidos desde un servidor de logs (37 corrupciones en 3 meses en un sistema con alta carga), donde se utilizó la operación splice() y tuberías anónimas.
La vulnerabilidad se manifiesta a partir del núcleo de Linux 5.8, lanzado en agosto de 2020, es decir, está presente en Debian 11, pero no afecta el núcleo base en Ubuntu 20.04 LTS. Los núcleos de RHEL 8.x y openSUSE/SUSE 15 se basan inicialmente en ramas antiguas, pero no se puede descartar que la modificación que causó el problema haya sido retroportada en ellos (no hay datos exactos por el momento). Se puede hacer seguimiento a las publicaciones de actualizaciones de paquetes en las siguientes páginas: Debian, SUSE, Ubuntu, RHEL, Fedora, Gentoo, Arch Linux. Se ha propuesto una corrección para la vulnerabilidad en las versiones 5.16.11, 5.15.25 y 5.10.102. La corrección también ha sido incluida en el núcleo utilizado en la plataforma Android.
La vulnerabilidad se debe a la falta de inicialización del valor «buf->flags» en el código de las funciones copy_page_to_iter_pipe() y push_pipe(), dado que la memoria no se limpia al asignar la estructura, y con ciertas manipulaciones en los canales sin nombre, puede haber un valor de otra operación en «buf->flags». Utilizando esta característica, un usuario local no privilegiado puede lograr que en la bandera aparezca el valor PIPE_BUF_FLAG_CAN_MERGE, el cual permite organizar la sobrescritura de datos en la caché de páginas a través de una simple escritura de nuevos datos en un canal sin nombre (pipe) preparado específicamente.
Para llevar a cabo el ataque, el archivo objetivo debe estar disponible para lectura, y dado que al escribir en el pipe no se verifican los permisos de acceso, la sustitución en la caché de páginas puede realizarse incluso para archivos que se encuentran en secciones montadas solo para lectura (por ejemplo, archivos de un CD-ROM). Después de reemplazar la información en la caché de páginas, el proceso al leer datos desde el archivo obtendrá datos no reales, sino sustituidos.
La explotación consiste en crear un canal sin nombre y llenarlo con datos arbitrarios para lograr que se establezca el flag PIPE_BUF_FLAG_CAN_MERGE en todas las estructuras de anillo relacionadas. Luego, los datos se leen desde el canal, pero el flag permanece establecido en todas las instancias de la estructura pipe_buffer en las estructuras anulares pipe_inode_info. Luego se realiza una llamada a splice() para leer datos desde el archivo objetivo al canal sin nombre, comenzando desde el desplazamiento requerido. Al escribir datos en este canal sin nombre, debido al flag establecido PIPE_BUF_FLAG_CAN_MERGE, los datos en la caché de páginas serán sobrescritos en lugar de crear una nueva instancia de la estructura pipe_buffer.
Fuente: opennet.ru
