stringtranslate.com

Módulo de kernel cargable

En informática , un módulo de núcleo cargable ( LKM ) es un archivo de objeto que contiene código para ampliar el núcleo en ejecución , o el llamado 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 del sistema . Cuando la funcionalidad proporcionada por un LKM ya no es necesaria, se puede descargar para liberar memoria y otros recursos.

La mayoría de los sistemas actuales similares a Unix y Microsoft Windows admiten módulos de kernel cargables con diferentes nombres, como módulo cargable de kernel ( kld ) en FreeBSD , extensión de kernel ( kext ) en macOS (aunque se está abandonando la compatibilidad con módulos de terceros [1] ), [2] módulo de extensión de kernel en AIX , módulo de kernel cargable dinámicamente en HP-UX , [3] controlador de modo kernel en Windows NT [4] y módulo de kernel descargable ( DKM ) en VxWorks . También se conocen como módulos cargables de kernel (o KLM ), y simplemente como módulos de kernel ( KMOD ).

Ventajas

Sin módulos de núcleo cargables, un sistema operativo tendría que incluir toda la funcionalidad anticipada posible compilada directamente en el núcleo base. Gran parte de esa funcionalidad residiría en la memoria sin ser utilizada, lo que desperdiciaría memoria [ cita requerida ] y requeriría que los usuarios reconstruyeran y reiniciaran el núcleo base cada vez que necesitaran una nueva funcionalidad.

Desventajas

Una pequeña crítica a la preferencia por un núcleo modular en lugar de un núcleo estático es la llamada 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 está 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 haga que el núcleo se fragmente, introduciendo así una pequeña penalización de rendimiento al utilizar más entradas TLB , lo que provoca más errores de TLB. [ cita requerida ]

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 han tenido la extensión .ko("objeto kernel") desde la versión 2.6 (las versiones anteriores usaban la .oextensión). [5] El lsmodcomando enumera 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 , presionando '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 núcleo [ cita requerida ] . Los mantenedores de Linux toleran la distribución de módulos propietarios , [ cita requerida ] pero permiten que los símbolos se marquen como disponibles únicamente para los módulos de la Licencia Pública General GNU (GPL).

Cargar un módulo propietario o no compatible con GPL activará una bandera de 'contaminación' [6] [7] en el kernel en ejecución—lo que significa que cualquier problema o error experimentado tendrá menos probabilidades de ser investigado por los mantenedores. [8] [9] Los LKM efectivamente se convierten en parte del kernel en ejecución, por lo que pueden corromper las estructuras de datos del kernel y producir errores que pueden no poder ser investigados si el módulo es de hecho propietario.

Controversia sobre Linux

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 ve 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 núcleo en ese momento intentaba determinar si el módulo tenía licencia GPL y se detenía cuando alcanzaba un carácter nulo ( \0), por lo que fue engañado y pensó que el módulo estaba declarando que su licencia era simplemente "GPL". [10]

LibreBSD

Los módulos del núcleo de FreeBSD se almacenan en /boot/kernel/para módulos distribuidos con el sistema operativo o, generalmente, /boot/modules/para módulos instalados desde puertos de FreeBSD o paquetes de FreeBSD o para módulos propietarios o de solo binarios. Los módulos del núcleo de FreeBSD generalmente tienen la extensión .ko. Una vez que la máquina ha arrancado, se pueden cargar con el kldloadcomando , descargar con kldunloady listar con kldstat. Los módulos también se pueden cargar desde el cargador antes de que se inicie el núcleo, ya sea automáticamente (a través de /boot/loader.conf) o a mano.

macOS

Algunos módulos del kernel cargables en macOS se pueden cargar automáticamente. Los módulos del kernel cargables también se pueden cargar mediante el kextloadcomando. Se pueden enumerar mediante 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 otros directorios.

NetWare

Un módulo de núcleo NetWare se denomina módulo cargable NetWare (NLM). Los NLM se insertan en el núcleo NetWare mediante el comando LOAD y se eliminan mediante el comando UNLOAD; el modulescomando enumera los módulos de núcleo cargados actualmente. Los NLM pueden residir en cualquier ruta de búsqueda válida asignada en el servidor NetWare y tienen .NLMcomo extensión de nombre 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 núcleo configurable, que por defecto es /platform/platform-name/kernel /kernel /usr/kernel. La mayoría de los módulos del núcleo se encuentran en subdirectorios bajo /kernel; aquellos que no se consideran necesarios para arrancar el sistema hasta el punto en que init pueda iniciarse se encuentran a menudo (pero no siempre) en /usr/kernel. Al ejecutar una compilación de núcleo DEBUG, el sistema intenta activamente descargar módulos.

Compatibilidad binaria

Linux no proporciona una API o ABI estable para los módulos del kernel. Esto significa que existen diferencias en la estructura y función internas entre las distintas versiones del kernel, lo que puede causar problemas de compatibilidad. En un intento por combatir esos problemas, los datos de versiones de símbolos se colocan dentro de la .modinfosección de módulos ELF cargables . Esta información de versiones se puede comparar 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 del kernel funcionarán sin recompilación en cualquier otra versión de FreeBSD 6.x, por ejemplo, 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 API y ABI se mantiene solo 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 ellos 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 hacen uso de los LKM de esta manera. Tenga en cuenta que, en la mayoría de los sistemas operativos, los módulos no ayudan a la elevación de privilegios de ninguna manera, ya que se requieren privilegios elevados para cargar un LKM; simplemente hacen que sea más fácil para el atacante ocultar 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 en el arranque y luego deshabilitar la carga de módulos. Esto hace que la seguridad sea muy similar a la de un núcleo monolítico. Si un atacante puede cambiar el initramfs, puede cambiar el binario del núcleo.

macOS

En OS X Yosemite y versiones posteriores, una extensión del núcleo debe estar firmada con un certificado de desarrollador que tenga un "derecho" particular. Apple solo proporciona un certificado de desarrollador de este tipo a pedido y no se entrega automáticamente a los miembros desarrolladores de Apple . Esta función, llamada "firma de kext", está habilitada de manera predeterminada y le indica al núcleo que deje de iniciarse si hay extensiones de núcleo sin firmar. [14] En OS X El Capitan y versiones posteriores, es 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 de kernel cargable en un paquete de extensión de 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 son propiedad de root y el grupo wheel, o son escribibles por el grupo u "other", el intento de cargar el módulo cargable del kernel fallará. [16]

Solaris

Los módulos del kernel pueden tener opcionalmente una sección ELF de firma criptográfica que se verifica durante la carga 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 por un conjunto de certificados de confianza; la lista de certificados de confianza se guarda fuera del SO en ILOM en algunas plataformas basadas en SPARC. La carga de módulos del kernel iniciada por 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

Referencias

  1. ^ "Extensiones de kernel obsoletas y alternativas de extensión del sistema". Apple Inc. Consultado el 13 de marzo de 2021 .
  2. ^ "Temas de programación de extensiones de kernel: Introducción". Apple Inc. 1 de septiembre de 2010. Archivado desde el original el 4 de mayo de 2013 . Consultado el 5 de mayo de 2013 .
  3. ^ "Administración y desarrollo de módulos de kernel cargables dinámicamente". Hewlett-Packard . 7 de junio de 2001.
  4. ^ "Qué determina cuándo se carga un controlador". Microsoft Developer Network . Microsoft . 21 de noviembre de 2012. Archivado desde el original el 6 de marzo de 2013 . Consultado el 5 de mayo de 2013 .
  5. ^ "Guía de programación de módulos del núcleo de Linux, sección 2.2 "Compilación de módulos del núcleo"" . Consultado el 5 de octubre de 2020 .
  6. ^ Linus Torvalds; et al. (2011-06-21). "Documentation/oops-tracing.txt". kernel.org. Archivado desde el original el 2011-10-02 . Consultado el 2011-10-03 .
  7. ^ "Núcleos contaminados". Guía del usuario y administrador del núcleo Linux .
  8. ^ Jonathan Corbet (24 de marzo de 2006). "Contaminación desde el espacio de usuario". LWN.net . Archivado desde el original el 16 de noviembre de 2011. Consultado el 3 de octubre de 2011 .
  9. ^ "Documentación de soporte de Novell: kernel contaminado". 26 de julio de 2007. Consultado el 3 de octubre de 2011 .
  10. ^ Jonathan Corbet (27 de abril de 2004). "Ser honesto con MODULE_LICENSE". LWN.net. Archivado desde el original el 2 de noviembre de 2012. Consultado el 30 de octubre de 2012 .
  11. ^ Explotación de módulos del kernel cargables Archivado el 4 de febrero de 2012 en Wayback Machine
  12. ^ "Sysctl/kernel.txt". Archivado desde el original el 15 de abril de 2013 . Consultado el 4 de enero de 2013 .
  13. ^ Kees Cook (28 de noviembre de 2012). «Desactivación del módulo Clean». outflux.net . Consultado el 5 de octubre de 2020 .
  14. ^ "Extensiones del kernel". Biblioteca para desarrolladores de Mac . Apple. 16 de septiembre de 2015. Archivado desde el original el 17 de agosto de 2016. Consultado el 29 de septiembre de 2016 .
  15. ^ "Propiedades de Info.plist para extensiones de kernel". Apple Inc. Archivado desde el original el 26 de septiembre de 2012 . Consultado el 27 de septiembre de 2012 .
  16. ^ kextload(8)  –  Manual del administrador del sistema de Darwin y macOS