Un módulo de núcleo cargable ( LKM ) es una biblioteca ejecutable que amplía las capacidades del núcleo en ejecución , o núcleo base , de un sistema operativo . Los LKM se utilizan normalmente para añadir compatibilidad con nuevo hardware (como controladores de dispositivos ) y/o sistemas de archivos , o para añadir llamadas al sistema . Cuando la funcionalidad que proporciona un LKM ya no es necesaria, se puede descargar para liberar memoria y otros recursos.
La mayoría de los sistemas actuales tipo Unix y Windows admiten módulos de kernel cargables, pero con nombres diferentes, como módulo de kernel cargable (kld) en FreeBSD , extensión de kernel (kext) en macOS (aunque se está eliminando la compatibilidad con módulos de terceros [ 1 ] ), [ 2 ] módulo de extensión de kernel en AIX , módulo de kernel de carga dinámica en HP-UX , [ 3 ] controlador en modo kernel en Windows NT [ 4 ] y módulo de kernel descargable (DKM) en VxWorks . También se les conoce como módulo de kernel cargable (KLM) o simplemente como módulo de kernel (KMOD).
Ventajas
Sin módulos de núcleo cargables, un sistema operativo tendría que incluir toda la funcionalidad prevista compilada directamente en el núcleo base. Gran parte de esa funcionalidad residiría en la memoria sin utilizarse, desperdiciando memoria , y obligaría a los usuarios a recompilar y reiniciar el núcleo base cada vez que necesitaran una nueva funcionalidad.
Desventajas
Una crítica menor a la preferencia por un núcleo modular sobre uno estático es la denominada penalización por fragmentación . El núcleo base siempre se descomprime en memoria contigua real mediante sus rutinas de configuración; por lo tanto, el código del núcleo base nunca se fragmenta. Una vez que el sistema se encuentra en un estado en el que se pueden insertar módulos, por ejemplo, una vez que se han montado los sistemas de archivos que contienen los módulos, es probable que cualquier nueva inserción de código del núcleo provoque su fragmentación, lo que introduce una pequeña penalización en el rendimiento al utilizar más entradas de la TLB y, por consiguiente, provocar más fallos de la TLB.
Implementaciones en diferentes sistemas operativos
Linux
Los módulos del kernel cargables en Linux se cargan (y descargan) mediante el modprobecomando. Se encuentran en /lib/moduleso /usr/lib/modulesy tienen la extensión .ko("objeto del kernel") desde la versión 2.6 (las versiones anteriores usaban la .oextensión). [ 5 ] El lsmodcomando lista los módulos del kernel cargados. En casos de emergencia, cuando el sistema no arranca debido, por ejemplo, a módulos dañados, se pueden habilitar o deshabilitar módulos específicos modificando la lista de parámetros de arranque del kernel (por ejemplo, si se usa GRUB , pulsando 'e' en el menú de inicio de GRUB y luego editando la línea de parámetros del kernel).
Problemas de licencia
En opinión de los mantenedores de Linux, los módulos LKM son obras derivadas del kernel . Los mantenedores de Linux toleran la distribución de módulos propietarios (como los controladores de GPU de NVIDIA ), pero solo permiten que los módulos con licencia GNU General Public License (GPL) se integren al árbol del kernel principal de Linux.
Cargar un módulo propietario o no compatible con GPL establecerá una bandera de "contaminación" [ 6 ] [ 7 ] en el núcleo en ejecución, lo que significa que cualquier problema o error experimentado será menos probable que los mantenedores investiguen. [ 8 ] [ 9 ] Los LKM se convierten efectivamente en parte del núcleo en ejecución, por lo que pueden corromper las estructuras de datos del núcleo y producir errores que tal vez no puedan investigarse si el módulo es realmente propietario.
Controversia de Linuxant
En 2004, Linuxant, una empresa de consultoría que publica controladores de dispositivos propietarios como módulos de kernel cargables, intentó abusar de un terminador nulo en su MODULE_LICENSE, como se puede ver en el siguiente extracto de código:
MODULE_LICENSE ( "GPL \0 para archivos en el directorio \" GPL \" ; para otros, solo se aplica el archivo LICENSE" );El código de comparación de cadenas utilizado por el kernel en ese momento intentaba determinar si el módulo tenía licencia GPL y se detenía cuando llegaba a un carácter nulo ( \0), por lo que se le engañó haciéndole creer que el módulo declaraba que su licencia era simplemente "GPL". [ 10 ]
FreeBSD
Los módulos del kernel para FreeBSD se almacenan dentro /boot/kernel/de los módulos distribuidos con el sistema operativo , o generalmente /boot/modules/para los módulos instalados desde puertos o paquetes de FreeBSD , o para módulos propietarios o de otro modo binarios únicamente. Los módulos del kernel de FreeBSD generalmente tienen la extensión .ko. Una vez que la máquina ha arrancado, se pueden cargar con el kldloadcomando , descargar con kldunload, y listar con kldstat. Los módulos también se pueden cargar desde el cargador antes de que se inicie el kernel, ya sea automáticamente (a través de /boot/loader.conf) o manualmente.
macOS
Algunos módulos del kernel cargables en macOS se pueden cargar automáticamente. También se pueden cargar mediante el kextloadcomando. Se pueden listar con el kextstatcomando. Los módulos del kernel cargables se encuentran en paquetes con la extensión .kext. Los módulos suministrados con el sistema operativo se almacenan en el /System/Library/Extensionsdirectorio; los módulos suministrados por terceros se encuentran en varios directorios diferentes.
NetWare
Un módulo del núcleo de NetWare se denomina Módulo Cargable de NetWare (NLM). Los NLM se insertan en el núcleo de NetWare mediante el comando LOAD y se eliminan mediante el comando UNLOAD; este modulescomando muestra los módulos del núcleo cargados actualmente. Los NLM pueden residir en cualquier ruta de búsqueda válida asignada en el servidor NetWare y tienen .NLMla extensión de archivo .
VxWorks
Se puede crear un proyecto de tipo módulo de kernel descargable (DKM) para generar un archivo ".out" que luego se puede cargar en el espacio del kernel mediante el comando "ld". Este módulo de kernel descargable se puede descargar mediante el comando "unld".
Solaris
Solaris tiene una ruta de carga de módulos del kernel configurable, que por defecto es /platform/platform-name/kernel /kernel /usr/kernel. La mayoría de los módulos del kernel se encuentran en subdirectorios dentro de /kernel; aquellos que no se consideran necesarios para arrancar el sistema hasta el punto en que init pueda iniciarse suelen encontrarse (pero no siempre) en /usr/kernel. Al ejecutar una compilación del kernel DEBUG, el sistema intenta activamente descargar los módulos.
Compatibilidad binaria
Linux no proporciona una API ni una ABI estables para los módulos del kernel. Esto implica que existen diferencias en la estructura y el funcionamiento internos entre las distintas versiones del kernel, lo que puede causar problemas de compatibilidad. Para mitigar estos problemas, se incluye información de versionado de símbolos en la sección de módulos ELF.modinfo cargables . Esta información de versionado se compara con la del kernel en ejecución antes de cargar un módulo; si las versiones son incompatibles, el módulo no se cargará.
Otros sistemas operativos, como Solaris , FreeBSD , macOS y Windows, mantienen la API y la ABI del kernel relativamente estables, evitando así este problema. Por ejemplo, los módulos del kernel de FreeBSD compilados con la versión 6.0 funcionarán sin recompilación en cualquier otra versión de FreeBSD 6.x, como la 6.4. Sin embargo, no son compatibles con otras versiones principales y deben recompilarse para su uso con FreeBSD 7.x, ya que la compatibilidad de la API y la ABI se mantiene únicamente dentro de una rama.
Seguridad
Si bien los módulos de kernel cargables son un método conveniente para modificar el kernel en ejecución, los atacantes pueden abusar de esto en un sistema comprometido para evitar la detección de sus procesos o archivos , lo que les permite mantener el control sobre el sistema. Muchos rootkits utilizan los módulos de kernel cargables de esta manera. Cabe señalar que, en la mayoría de los sistemas operativos, los módulos no facilitan la elevación de privilegios , ya que se requieren privilegios elevados para cargar un módulo de kernel cargable; simplemente facilitan que el atacante oculte la intrusión. [ 11 ]
Linux
Linux permite deshabilitar la carga de módulos mediante la opción sysctl/proc/sys/kernel/modules_disabled . [ 12 ] [ 13 ] Un sistema initramfs puede cargar módulos específicos necesarios para una máquina al arrancar y luego deshabilitar la carga de módulos. Esto hace que la seguridad sea muy similar a la de un kernel monolítico. Si un atacante puede modificar el initramfs, puede modificar el binario del kernel.
macOS
En OS X Yosemite y versiones posteriores, una extensión del kernel debe estar firmada digitalmente con un certificado de desarrollador que posee un "derecho" específico. Este certificado de desarrollador solo lo proporciona Apple bajo petición y no se otorga automáticamente a los miembros de Apple Developer . Esta función, denominada "firma de kext", está habilitada de forma predeterminada e indica al kernel que detenga el arranque si hay extensiones del kernel sin firmar. [ 14 ] En OS X El Capitan y versiones posteriores, forma parte de la Protección de Integridad del Sistema .
En versiones anteriores de macOS, o si la firma de kext está deshabilitada, un módulo del kernel cargable en un paquete de extensión del kernel puede ser cargado por usuarios que no sean root si la propiedad OSBundleAllowUserLoad está establecida en True en la lista de propiedades del paquete. [ 15 ] Sin embargo, si alguno de los archivos en el paquete, incluido el archivo de código ejecutable, no pertenece a root y al grupo wheel, o es escribible por el grupo u "other", el intento de cargar el módulo cargable del kernel fallará. [ 16 ]
Solaris
Los módulos del kernel pueden incluir opcionalmente una sección ELF con firma criptográfica, la cual se verifica al cargarse según la configuración de la política de arranque verificado. El kernel puede exigir que los módulos estén firmados criptográficamente mediante un conjunto de certificados de confianza; en algunas plataformas SPARC, la lista de certificados de confianza se almacena fuera del sistema operativo, en el ILOM. La carga de módulos del kernel iniciada desde el espacio de usuario solo es posible desde la ruta de confianza cuando el sistema se ejecuta con la función de zona global inmutable habilitada.
Véase también
- Biblioteca de vínculos dinámicos : implementación de Microsoft del concepto de biblioteca compartida en Windows y OS/2. Páginas que muestran descripciones breves de destinos de redirección.
- Módulo cargable NetWare : software compatible con Novell legible por ordenador.
- Biblioteca compartida : biblioteca de software en memoria que varios ejecutables pueden usar en tiempo de ejecución.
Referencias
- ↑ "Extensiones de kernel obsoletas y alternativas de extensión del sistema" . Apple Inc. Consultado el 13 de marzo de 2021 .
- ↑ "Temas de programación de extensiones del kernel: Introducción" . Apple Inc. 1 de septiembre de 2010. Archivado del original el 4 de mayo de 2013. Consultado el 5 de mayo de 2013 .
- ↑ "Gestión y desarrollo de módulos de núcleo de carga dinámica" . Hewlett-Packard . 7 de junio de 2001.
- ↑ "Qué determina cuándo se carga un controlador" . Red de desarrolladores de Microsoft . Microsoft . 21 de noviembre de 2012. Archivado del original el 6 de marzo de 2013. Consultado el 5 de mayo de 2013 .
- ↑ "Guía de programación de módulos del kernel de Linux, sección 2.2 "Compilación de módulos del kernel"" . Consultado el 05-10-2020 .
- ↑ Linus Torvalds; et al. (21-06-2011). "Documentation/oops-tracing.txt" . kernel.org. Archivado del original el 02-10-2011 . Recuperado el 03-10-2011 .
- ↑ "Núcleos contaminados" . La guía del usuario y administrador del núcleo Linux .
- ↑ Jonathan Corbet (24-03-2006). "Contaminación desde el espacio del usuario" . LWN.net . Archivado del original el 16-11-2011 . Recuperado el 03-10-2011 .
- ↑ "Documentación de soporte de Novell: Núcleo contaminado" . 26 de julio de 2007. Consultado el 3 de octubre de 2011 .
- ↑ Jonathan Corbet (27 de abril de 2004). "Ser honesto con MODULE_LICENSE" . LWN.net. Archivado del original el 2 de noviembre de 2012. Recuperado el 30 de octubre de 2012 .
- ↑ Explotación de módulos de kernel cargables Archivado el 4 de febrero de 2012 en Wayback Machine
- ↑ "Sysctl/kernel.txt" . Consultado el 4 de enero de 2013 .
{{cite web}}: CS1 maint: servicio de archivado obsoleto ( enlace ) - ↑ Kees Cook (28-11-2012). "Deshabilitación de módulos limpios" . outflux.net . Consultado el 05-10-2020 .
- ↑ "Extensiones del kernel" . Biblioteca para desarrolladores de Mac . Apple. 16 de septiembre de 2015. Archivado del original el 17 de agosto de 2016. Consultado el 29 de septiembre de 2016 .
- ↑ "Propiedades de Info.plist para extensiones del kernel" . Apple Inc. Archivado del original el 26 de septiembre de 2012. Recuperado el 27 de septiembre de 2012 .
- ↑ – Manual del administrador del sistema Darwin y macOS
- FreeBSD
- núcleo de Linux
- núcleos de sistemas operativos
- Controladores de dispositivos