Articulo de referencia

ioctl

En informática , ioctl (abreviatura de control de entrada/salida ) es una llamada al sistema para operaciones de entrada/salida específicas del dispositivo y otras operaciones q...

En informática , ioctl(abreviatura de control de entrada/salida ) es una llamada al sistema para operaciones de entrada/salida específicas del dispositivo y otras operaciones que no pueden expresarse mediante la semántica de lectura/escritura/búsqueda de archivos regulares. Recibe un parámetro que especifica un código de solicitud; el efecto de una llamada depende completamente de dicho código. Los códigos de solicitud suelen ser específicos del dispositivo. Por ejemplo, un controlador de dispositivo CD-ROM que puede instruir a un dispositivo físico para expulsar un disco proporcionaría un ioctlcódigo de solicitud para hacerlo. En ocasiones, se utilizan códigos de solicitud independientes del dispositivo para otorgar acceso desde el espacio de usuario a funciones del núcleo que solo utiliza el software del sistema principal o que aún están en desarrollo.

La ioctlllamada al sistema apareció por primera vez en la versión 7 de Unix con ese nombre. Es compatible con la mayoría de los sistemas Unix y similares a Unix , incluidos Linux y macOS , aunque los códigos de solicitud disponibles difieren de un sistema a otro. Microsoft Windows proporciona una función similar, llamada " DeviceIoControl", en su API Win32 .

Fondo

Los sistemas operativos convencionales se dividen en dos capas: el espacio de usuario y el núcleo . El código de las aplicaciones, como un editor de texto, reside en el espacio de usuario, mientras que las funcionalidades subyacentes del sistema operativo, como la pila de red , residen en el núcleo. El código del núcleo gestiona los recursos sensibles e implementa las barreras de seguridad y fiabilidad entre las aplicaciones; por este motivo, el sistema operativo impide que las aplicaciones en modo usuario accedan directamente a los recursos del núcleo.

Las aplicaciones de espacio de usuario suelen realizar solicitudes al núcleo mediante llamadas al sistema , cuyo código reside en la capa del núcleo. Una llamada al sistema generalmente se presenta como un "vector de llamadas al sistema", donde la llamada deseada se indica con un número de índice. Por ejemplo, exit()podría ser la llamada al sistema número 1, y write()la número 4. El vector de llamadas al sistema se utiliza para encontrar la función del núcleo que corresponde a la solicitud. De esta manera, los sistemas operativos convencionales suelen proporcionar varios cientos de llamadas al sistema al espacio de usuario.

Si bien las llamadas al sistema son un diseño práctico para acceder a las funciones estándar del núcleo, a veces resultan inapropiadas para acceder a periféricos de hardware no estándar. Por necesidad, la mayoría de los periféricos de hardware (también conocidos como dispositivos) solo son accesibles directamente desde el núcleo. Sin embargo, el código de usuario puede necesitar comunicarse directamente con los dispositivos; por ejemplo, un administrador podría configurar el tipo de medio en una interfaz Ethernet . Los sistemas operativos modernos admiten diversos dispositivos, muchos de los cuales ofrecen una amplia gama de funciones. Es posible que el diseñador del núcleo no haya previsto algunas de estas funciones, lo que dificulta que el núcleo proporcione llamadas al sistema para el uso de dichos dispositivos.

Para solucionar este problema, el núcleo está diseñado para ser extensible y puede aceptar un módulo adicional llamado controlador de dispositivo , que se ejecuta en el espacio del núcleo y puede acceder directamente al dispositivo. Una ioctlinterfaz es una única llamada al sistema mediante la cual el espacio de usuario puede comunicarse con los controladores de dispositivo. Las solicitudes a un controlador de dispositivo se dirigen a esta ioctlllamada al sistema, normalmente mediante un identificador del dispositivo y un número de solicitud. De este modo, el núcleo básico permite que el espacio de usuario acceda a un controlador de dispositivo sin necesidad de conocer las funcionalidades que admite el dispositivo y sin requerir una cantidad excesiva de llamadas al sistema.

Usos

Configuración del dispositivo de hardware

Un uso común ioctles controlar dispositivos de hardware.

Por ejemplo, en los sistemas Win32 , ioctllas llamadas pueden comunicarse con dispositivos USB o pueden descubrir información sobre la geometría de las unidades de los dispositivos de almacenamiento conectados.

En OpenBSD y NetBSD , ioctles utilizado por el bio(4)controlador de pseudodispositivo y la bioctlutilidad para implementar la administración de volúmenes RAID en una interfaz unificada independiente del proveedor similar a ifconfig. [ 1 ] [ 2 ]

En NetBSD , ioctltambién es utilizado por el sysmonmarco. [ 3 ]

Terminales

Un uso del ioctlcódigo expuesto a las aplicaciones de usuario final es la entrada/salida de terminales.

Los sistemas operativos Unix tradicionalmente han hecho un uso intensivo de las interfaces de línea de comandos , originalmente con terminales de texto de hardware como los VT100 conectados a puertos serie , y posteriormente con emuladores de terminal y servidores de inicio de sesión remoto que utilizan pseudoterminales . Tanto los dispositivos de puerto serie como los pseudoterminales se controlan y configuran mediante ioctlllamadas. Por ejemplo, el tamaño de la pantalla se establece mediante la TIOCSWINSZllamada. La función ioctl TIOCSTI (control de E/S de terminal, simulación de entrada de terminal) puede enviar un carácter a un flujo de dispositivo. [ 4 ]

Extensiones del kernel

Cuando las aplicaciones necesitan extender el núcleo, por ejemplo, para acelerar el procesamiento de red, ioctllas llamadas proporcionan una forma práctica de conectar el código del espacio de usuario con las extensiones del núcleo. Estas extensiones pueden proporcionar una ubicación en el sistema de archivos que se puede abrir por nombre, a través de la cual ioctlse puede enviar un número arbitrario de llamadas, lo que permite programar la extensión sin añadir llamadas al sistema operativo.

Alternativa a sysctl

Según un desarrollador de OpenBSD , ioctly sysctlson las dos llamadas al sistema para extender el kernel, siendo sysctlposiblemente la más simple de las dos. [ 5 ]

En NetBSD , el sysmon_envsysmarco para la monitorización de hardware utiliza ioctla través de proplib; mientras que OpenBSD y DragonFly BSD utilizan en su lugar sysctlpara su hw.sensorsmarco correspondiente. La revisión original de envsysen NetBSD se implementó con ioctlantes de proplibque estuviera disponible, y tenía un mensaje que sugería que el marco era experimental y que debería ser reemplazado por una sysctl(8)interfaz, si se desarrollaba una, [ 6 ] [ 7 ] lo que potencialmente explica la elección de sysctlen OpenBSD con su posterior introducción de hw.sensorsen 2003. Sin embargo, cuando el envsysmarco se rediseñó en 2007 alrededor de proplib, la llamada al sistema permaneció como ioctl, y el mensaje fue eliminado. [ 8 ]

Implementaciones

Unix

La ioctlllamada al sistema apareció por primera vez en la versión 7 de Unix , como reemplazo de las llamadas al sistema stty[ 9 ] y gtty, con un argumento de código de solicitud adicional. Una ioctlllamada toma como parámetros :

  1. un descriptor de archivo abierto
  2. un número de código de solicitud
  3. un puntero sin tipo a datos (ya sea que vayan al controlador, regresen del controlador o ambas cosas).

El núcleo generalmente envía una ioctlllamada directamente al controlador del dispositivo, que puede interpretar el número de solicitud y los datos de la manera que sea necesaria. Los desarrolladores de cada controlador documentan los números de solicitud para ese controlador en particular y los proporcionan como constantes en un archivo de encabezado .

Los números de solicitud suelen combinar un código que identifica el dispositivo o la clase de dispositivos a los que se dirige la solicitud y un número que indica la solicitud en particular; el código que identifica el dispositivo o la clase de dispositivos suele ser un único carácter ASCII. Algunos sistemas Unix, incluidos 4.2BSD y versiones posteriores de BSD , sistemas operativos derivados de dichas versiones y Linux , tienen convenciones que también codifican dentro del número de solicitud el tamaño de los datos que se transferirán hacia/desde el controlador del dispositivo y la dirección de la transferencia de datos. Independientemente de si se siguen dichas convenciones, el núcleo y el controlador colaboran para entregar un código de error uniforme (denotado por la constante simbólica ENOTTY) a una aplicación que realiza una solicitud a un controlador que no la reconoce.

La regla mnemotécnica ENOTTY(tradicionalmente asociada con el mensaje de texto " No es una máquina de escribir ") proviene de los primeros sistemas que incorporaban una ioctlllamada, donde solo el dispositivo teletipo ( tty) generaba este error. Si bien la regla mnemotécnica simbólica está fijada por requisitos de compatibilidad, algunos sistemas modernos ofrecen un mensaje más general, como " Operación de control de dispositivo inapropiada " (o una localización del mismo).

TCSETSEsto ejemplifica una ioctlllamada en un puerto serie . Las llamadas normales de lectura y escritura en un puerto serie reciben y envían bytes de datos. Una llamada, independiente de estas operaciones de E/S normales, controla diversas opciones del controlador, como el manejo de caracteresioctl(fd,TCSETS,data) especiales o las señales de salida del puerto (como la señal DTR ).

Win32

Un Win32 DeviceIoControltoma como parámetros:

  1. un identificador de objeto abierto (el equivalente en Win32 a un descriptor de archivo)
  2. un número de código de solicitud (el "código de control")
  3. un búfer para parámetros de entrada
  4. longitud del búfer de entrada
  5. un búfer para los resultados de salida
  6. longitud del búfer de salida
  7. una OVERLAPPEDestructura, si se está utilizando E/S superpuesta .

El código de control de dispositivos Win32 tiene en cuenta el modo de operación que se está realizando.

Existen 4 modos de funcionamiento definidos, que afectan a la seguridad del controlador del dispositivo.

  1. METHOD_IN_DIRECT: Se verifica que la dirección del búfer sea legible por el llamador en modo de usuario.
  2. METHOD_OUT_DIRECT: La dirección del búfer se verifica para comprobar que el llamador en modo usuario tiene permisos de escritura.
  3. METHOD_NEITHER: Las direcciones virtuales en modo de usuario se pasan al controlador sin mapeo ni validación.
  4. METHOD_BUFFEREDLos búferes compartidos controlados por el administrador de E/S se utilizan para transferir datos desde y hacia el modo de usuario.

Alternativas

Otras interfaces de llamadas vectoriales

Los dispositivos y las extensiones del núcleo pueden vincularse al espacio de usuario mediante nuevas llamadas al sistema adicionales, aunque este enfoque rara vez se utiliza, ya que los desarrolladores de sistemas operativos intentan mantener la interfaz de llamadas al sistema centrada y eficiente.

En los sistemas operativos Unix, son populares otras dos interfaces de llamadas vectorizadas: la fcntlllamada al sistema ("control de archivos") configura los archivos abiertos y se utiliza en situaciones como la habilitación de E/S no bloqueante ; y la setsockoptllamada al sistema ("configurar opción de socket") configura los sockets de red abiertos , una función utilizada para configurar el ipfwcortafuegos de paquetes en los sistemas BSD Unix.

Mapeo de memoria

Unix
Las interfaces de los dispositivos y las capacidades de entrada/salida a veces se proporcionan mediante archivos mapeados en memoria . Las aplicaciones que interactúan con los dispositivos abren una ubicación en el sistema de archivos correspondiente al dispositivo, como lo harían para una ioctlllamada, pero luego utilizan llamadas al sistema de mapeo de memoria para vincular una parte de su espacio de direcciones con el del núcleo. Esta interfaz es una forma mucho más eficiente de proporcionar transferencia de datos masiva entre un dispositivo y una aplicación de espacio de usuario; ioctllas llamadas al sistema individuales o de lectura/escritura generan sobrecarga debido a las transiciones repetidas entre el espacio de usuario y el núcleo, mientras que el acceso a un rango de direcciones mapeadas en memoria no genera dicha sobrecarga.
Win32
Se pueden utilizar métodos de E/S con búfer o objetos de asignación de archivos con nombre; sin embargo, para controladores de dispositivos sencillos, los DeviceIoControl METHOD_accesos estándar son suficientes.

Netlink es un mecanismo similar a un socket para la comunicación entre procesos (IPC), diseñado para ser un sucesor más flexible de ioctl.

Trascendencia

Complejidad

ioctlLas llamadas minimizan la complejidad de la interfaz de llamadas al sistema del kernel. Sin embargo, al proporcionar un espacio para que los desarrolladores almacenen fragmentos de las interfaces de programación del kernel, ioctllas llamadas complican la API general entre el usuario y el kernel. Un kernel que proporciona varios cientos de llamadas al sistema puede proporcionar varios miles de llamadas ioctl.

Aunque la interfaz de ioctllas llamadas parece algo diferente a las llamadas al sistema convencionales, en la práctica hay poca diferencia entre una ioctlllamada y una llamada al sistema; una ioctlllamada es simplemente una llamada al sistema con un mecanismo de despacho diferente. Por lo tanto, muchos de los argumentos en contra de ampliar la interfaz de llamadas al sistema del kernel podrían aplicarse a ioctllas interfaces.

Para los desarrolladores de aplicaciones, las llamadas al sistema no se diferencian de las subrutinas de la aplicación; son simplemente llamadas a funciones que reciben argumentos y devuelven valores. Las bibliotecas principales (por ejemplo, libc) ocultan la complejidad que implica invocar llamadas al sistema. Lo mismo ocurre con ioctl, donde las interfaces de controlador suelen venir con una biblioteca de espacio de usuario. (Por ejemplo, Mesa para la infraestructura de renderizado directo de los controladores gráficos).

Libpcap y libdnet son dos ejemplos de bibliotecas Unix de terceros que actúan como envoltorio para ocultar la complejidad de ioctllas interfaces, para la captura de paquetes y la entrada/salida de paquetes, respectivamente.

Seguridad

En el diseño tradicional, los núcleos residían en el anillo 0 , separados de los controladores de dispositivos en el anillo 1, y en los micronúcleos , también entre sí. Esta práctica se ha abandonado en gran medida debido a la sobrecarga que supone la transición entre anillos para las interfaces controlador/núcleo, similar a la que imponen las llamadas al sistema en las interfaces núcleo/espacio de usuario. Esto ha dado lugar al requisito, difícil de aplicar en la práctica, de que todos los controladores, que ahora también residen en el anillo 0, deben mantener el mismo nivel de seguridad que el núcleo.

Si bien las interfaces de usuario a núcleo de los sistemas operativos convencionales suelen someterse a auditorías exhaustivas para detectar fallos de código y vulnerabilidades de seguridad antes de su lanzamiento, estas auditorías se centran generalmente en las interfaces de llamadas al sistema, que están bien documentadas. Por ejemplo, los auditores podrían asegurarse de que las llamadas de seguridad sensibles, como el cambio de ID de usuario, solo estén disponibles para usuarios administradores. Dado que el controlador de una ioctlllamada también reside directamente en el anillo 0, la entrada del espacio de usuario debe validarse con el mismo cuidado. Las vulnerabilidades en los controladores de dispositivos pueden ser explotadas por usuarios locales, por ejemplo, pasando búferes no válidos a ioctllas llamadas. En la práctica, esto no sucede. ioctlLas interfaces son más grandes, más diversas y están menos definidas, por lo que son más difíciles de auditar que las llamadas al sistema. Además, dado que ioctllas llamadas pueden ser proporcionadas por desarrolladores externos, a menudo después del lanzamiento del sistema operativo principal, ioctllas implementaciones de llamadas generalmente reciben menos escrutinio y, por lo tanto, albergan más vulnerabilidades. Finalmente, algunas ioctlllamadas, en particular para controladores de dispositivos de terceros, pueden carecer por completo de documentación.

Se han creado diversas soluciones para este problema, con el objetivo de lograr una seguridad equivalente a la anterior, manteniendo la velocidad obtenida. Los sistemas operativos Win32 y Unix pueden proteger el nombre de un dispositivo en el espacio de usuario del acceso de las aplicaciones con controles de acceso específicos aplicados al dispositivo. Pueden surgir problemas de seguridad cuando los desarrolladores de controladores de dispositivos no aplican los controles de acceso adecuados al objeto accesible en el espacio de usuario. Algunos sistemas operativos modernos protegen el núcleo del código malicioso en el espacio de usuario (como aplicaciones infectadas por exploits de desbordamiento de búfer ) mediante envoltorios de llamadas al sistema . Los envoltorios de llamadas al sistema implementan el control de acceso basado en roles especificando qué llamadas al sistema pueden ser invocadas por qué aplicaciones; los envoltorios pueden, por ejemplo, utilizarse para "revocar" el derecho de un programa de correo electrónico a generar otros programas. ioctlLas interfaces complican los envoltorios de llamadas al sistema porque hay un gran número de ellos, cada uno acepta diferentes argumentos, algunos de los cuales pueden ser necesarios para los programas normales. Además, estas soluciones anulan la reducción de sobrecarga obtenida.

Referencias

  1. Niklas Hallqvist (2002); Marco Peereboom (2006). "bio(4) — dispositivo pseudo-túnel ioctl de E/S de bloque" . Referencia cruzada de BSD . OpenBSD .{{cite web}}: CS1 maint: nombres numéricos: lista de autores ( enlace )
    • "bio — bloque E/S túnel ioctl pseudo-dispositivo". Servidor de páginas del manual de OpenBSD .
  2. Marco Peereboom (2005). "bioctl(8) — Interfaz de administración RAID" . Referencia cruzada de BSD . OpenBSD .
    • "bioctl — Interfaz de administración RAID". Servidor de páginas del manual de OpenBSD .
  3. "sysmon(4) — interfaz de administración de energía y monitoreo del sistema" . NetBSD . Una interfaz ioctl(2) disponible a través de /dev/sysmon.
  4. Christiansen, Tom ; Torkington, Nathan (1998). "12: Paquetes, bibliotecas y módulos". Perl Cookbook: Soluciones y ejemplos para programadores de Perl (2.ª ed.). Sebastopol, California: O'Reilly Media, Inc. (publicado en 2003). pág. 482. ISBN   9780596554965. Recuperado el 15/11/2016 . [...] TIOCSTI [...] significa 'control de E/S de terminal, simulación de entrada de terminal'. En los sistemas que implementan esta función, insertará un carácter en el flujo de su dispositivo para que la próxima vez que cualquier proceso lea de ese dispositivo, obtenga el carácter que usted puso allí.
  5. Federico Biancuzzi (28-10-2004). "OpenBSD 3.6 Live" . ONLamp . O'Reilly Media . Archivado del original el 29-10-2004 . Recuperado el 20-03-2019 . Hay dos llamadas al sistema que se pueden usar para agregar funcionalidad al kernel (sin agregar otra llamada al sistema): ioctl(2) y sysctl(3). Esta última fue elegida porque era muy simple de implementar la nueva característica.
  6. Tim Rightnour; Bill Squier (19 de diciembre de 2007). "envsys -- API de sistemas ambientales" . NetBSD 4.0. Esta API es experimental y puede quedar obsoleta en cualquier momento... Esta API completa debería ser reemplazada por una interfaz sysctl(8) o un mecanismo de eventos del kernel, si se desarrolla alguno.
  7. Constantine A. Murenin (17 de abril de 2007). "3.5. Sysmon(4) de NetBSD". Interfaz generalizada con monitores de hardware de sistemas de microprocesadores . Actas de la Conferencia Internacional IEEE de 2007 sobre Redes, Detección y Control, 15-17 de abril de 2007. Londres, Reino Unido: IEEE . págs. 901-906 . doi : 10.1109/ICNSC.2007.372901 . ISBN  978-1-4244-1076-7IEEE ICNSC 2007, págs. 901-906.
  8. Constantine A. Murenin (21 de mayo de 2010). "6.1. Cronograma del marco; 7.1. NetBSD envsys / sysmon". Sensores de hardware de OpenBSD: monitorización ambiental y control de ventiladores ( tesis de maestría en matemáticas ). Universidad de Waterloo : UWSpace. hdl : 10012/5234 . ID del documento: ab71498b6b1a60ff817b29d56997a418.
  9. McIlroy, MD (1987). Un lector de Research Unix: extractos anotados del Manual del programador, 1971–1986 (PDF) (Informe técnico). CSTR. Bell Labs. 139. Archivado del original (PDF) el 30 de julio de 2023.

Lecturas adicionales

Obtenido de " https://en.wikipedia.org/w/index.php?title=Ioctl&oldid=1338008025 "