¿Qué son vdso y vsyscall?

89

yo hice sudo cat /proc/1/maps -vv

Estoy tratando de darle sentido a la salida. Puedo ver muchas bibliotecas compartidas asignadas al segmento de mapeo de memoria como se esperaba.

7f3c00137000-7f3c00179000 r-xp 00000000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c00179000-7f3c00379000 ---p 00042000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c00379000-7f3c0037a000 r--p 00042000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c0037a000-7f3c0037b000 rw-p 00043000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c0037b000-7f3c00383000 r-xp 00000000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00383000-7f3c00583000 ---p 00008000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00583000-7f3c00584000 r--p 00008000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00584000-7f3c00585000 rw-p 00009000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00585000-7f3c0059b000 r-xp 00000000 08:01 21237220                   /lib/x86_64-linux-gnu/libnih.so.1.0.0
7f3c0059b000-7f3c0079b000 ---p 00016000 08:01 21237220                   /lib/x86_64-linux-gnu/libnih.so.1.0.0
7f3c0079b000-7f3c0079c000 r--p 00016000 08:01 21237220                   /lib/x86_64-linux-gnu/libnih.so.1.0.0

Hacia el final hay algo como

7f3c0165b000-7f3c0177e000 rw-p 00000000 00:00 0                          [heap]
7fff97863000-7fff97884000 rw-p 00000000 00:00 0                          [stack]
7fff97945000-7fff97946000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

¿Qué significa vdsoy qué vsyscallsignifica? ¿vsyscall es la parte del kernel de la memoria? Sería genial si alguien pudiera arrojar algo de luz sobre el tema.

liv2hak
fuente
5
Google para VDSO proporciona esta página wikipage de VDSO (que tiene más referencias).
Basile Starynkevitch
procfs , consulte la versión de su kernel de este archivo para conocer los detalles de su sistema.
ruido sin
Creo que para este tema se necesita una mejor explicación de lo que se puede encontrar en la wiki o en la documentación de procfs.
Giuseppe Pes

Respuestas:

150

Los segmentos vsyscall y vDSO son dos mecanismos que se utilizan para acelerar determinadas llamadas al sistema en Linux. Por ejemplo, gettimeofdaygeneralmente se invoca a través de este mecanismo. El primer mecanismo introducido fue vsyscall , que se agregó como una forma de ejecutar llamadas de sistema específicas que no necesitan ningún nivel real de privilegio para ejecutarse con el fin de reducir la sobrecarga de llamadas del sistema. Siguiendo el ejemplo anterior, todo lo que gettimeofdaydebe hacer es leer la hora actual del kernel. Hay aplicaciones que llaman con gettimeofdayfrecuencia (por ejemplo, para generar marcas de tiempo), hasta el punto de que les importa incluso un poco de sobrecarga. Para abordar esta preocupación, el kernel mapea en el espacio del usuario una página que contiene la hora actual y unagettimeofdayimplementación (es decir, solo una función que lee el tiempo ahorrado en vsyscall ). Al usar esta llamada al sistema virtual, la biblioteca C puede proporcionar un rápido gettimeofdayque no tiene la sobrecarga introducida por el cambio de contexto entre el espacio del kernel y el espacio del usuario generalmente introducido por el modelo clásico de llamada al sistema INT 0x80o SYSCALL.

Sin embargo, este mecanismo vsyscall tiene algunas limitaciones: la memoria asignada es pequeña y permite solo 4 llamadas al sistema, y, lo que es más importante y serio, la página vsyscall se asigna estáticamente a la misma dirección en cada proceso, ya que la ubicación de la página vsyscall es clavado en el kernel ABI. Esta asignación estática de vsyscall compromete el beneficio introducido por la asignación al azar del espacio de memoria comúnmente utilizada por Linux. Un atacante, después de comprometer una aplicación explotando un desbordamiento de pila, puede invocar una llamada al sistema desde vsyscallpágina con parámetros arbitrarios. Todo lo que necesita es la dirección de la llamada al sistema, que es fácilmente predecible ya que está asignada estáticamente (si intenta ejecutar nuevamente su comando incluso con diferentes aplicaciones, notará que la dirección de vsyscall no cambia). Sería bueno eliminar o al menos aleatorizar la ubicación de la página vsyscall para frustrar este tipo de ataque. Desafortunadamente, las aplicaciones dependen de la existencia y la dirección exacta de esa página, por lo que no se puede hacer nada.

Este problema de seguridad se ha solucionado reemplazando todas las instrucciones de llamada del sistema en direcciones fijas por una instrucción de captura especial. Una aplicación que intente llamar a la página vsyscall entrará en el kernel, que luego emulará la llamada al sistema virtual deseada en el espacio del kernel. El resultado es una llamada al sistema del núcleo que emula una llamada al sistema virtual que se colocó allí para evitar la llamada al sistema del núcleo en primer lugar. El resultado es una vsyscall que tarda más en ejecutarse pero, lo que es más importante, no rompe la ABI existente. En cualquier caso, la ralentización solo se verá si la aplicación intenta utilizar la página vsyscall en lugar de vDSO .

El vDSO ofrece la misma funcionalidad que el vsyscall, al tiempo que supera sus limitaciones. VDSO (Objetos compartidos virtuales dinámicamente vinculados) es un área de memoria asignada en el espacio del usuario que expone algunas funcionalidades del kernel en el espacio del usuario de manera segura. Esto se ha introducido para resolver las amenazas a la seguridad causadas por vsyscall. El vDSO se asigna dinámicamente, lo que resuelve problemas de seguridad y puede tener más de 4 llamadas al sistema. Los enlaces vDSO se proporcionan a través de la biblioteca glibc. El vinculador se vinculará en la funcionalidad glibc vDSO , siempre que dicha rutina tenga una versión de vDSO adjunta , como gettimeofday. Cuando su programa se ejecuta, si su kernel no tiene vDSO soporte, se realizará una llamada al sistema tradicional.

Créditos y enlaces útiles:

Giuseppe Pes
fuente
3
¿Por qué vsyscall puede tener solo 4 llamadas al sistema? Hay 8 megabytes reservados para llamadas al sistema y solo se usa 1 página (en realidad 3 funciones, asignadas por 1024 toman 1 página).
skap
9

Solo quiero agregar que ahora, en los nuevos kernels, vDSOno se usa solo para llamadas al sistema "seguras", sino que se usa para decidir qué mecanismo de llamada al sistema es el método preferido para invocar una llamada al sistema en el sistema.

incompetente
fuente