stringtranslate.com

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 que no se pueden expresar mediante la semántica de archivo normal. Toma un parámetro que especifica un código de solicitud; el efecto de una llamada depende completamente del código de solicitud. Los códigos de solicitud suelen ser específicos del dispositivo. Por ejemplo, un controlador de dispositivo de CD-ROM que puede indicar a un dispositivo físico que expulse un disco proporcionaría un ioctlcódigo de solicitud para hacerlo. Los códigos de solicitud independientes del dispositivo a veces se utilizan para dar acceso de espacio de usuario a funciones del núcleo que solo se utilizan por el software del sistema central 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 , incluidos Linux y macOS , aunque los códigos de solicitud disponibles difieren de un sistema a otro. Microsoft Windows proporciona una función similar, denominada " DeviceIoControl", en su API Win32 .

Fondo

Los sistemas operativos convencionales se pueden dividir en dos capas: el espacio de usuario y el núcleo . El código de aplicación, como un editor de texto, reside en el espacio de usuario, mientras que las funciones subyacentes del sistema operativo, como la pila de red , residen en el núcleo. El código del núcleo maneja recursos confidenciales e implementa las barreras de seguridad y confiabilidad entre aplicaciones; por esta razón, el sistema operativo impide que las aplicaciones en modo usuario accedan directamente a los recursos del núcleo.

Las aplicaciones del espacio de usuario suelen realizar solicitudes al núcleo mediante llamadas al sistema , cuyo código se encuentra en la capa del núcleo. Una llamada al sistema suele adoptar la forma de un "vector de llamada al sistema", en el que la llamada al sistema 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 llamada al sistema se utiliza entonces para encontrar la función del núcleo deseada para la solicitud. De esta forma, los sistemas operativos convencionales suelen proporcionar varios cientos de llamadas al sistema al espacio de usuario.

Aunque se trata de un diseño conveniente para acceder a las funciones estándar del núcleo, las llamadas al sistema a veces no son adecuadas 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 se pueden direccionar directamente dentro del núcleo. Pero es posible que el código de usuario deba comunicarse directamente con los dispositivos; por ejemplo, un administrador puede configurar el tipo de medio en una interfaz Ethernet . Los sistemas operativos modernos admiten diversos dispositivos, muchos de los cuales ofrecen una gran variedad de funciones. Es posible que el diseñador del núcleo no haya previsto algunas de estas funciones y, en consecuencia, es difícil que un núcleo proporcione llamadas al sistema para utilizar los dispositivos.

Para resolver 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 dirigirse 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 con respecto 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 puede permitir que el espacio de usuario acceda a un controlador de dispositivo sin saber nada acerca de las funciones admitidas por el dispositivo y sin necesidad de una colección de llamadas al sistema inmanejablemente grande.

Usos

Configuración del dispositivo de hardware

Un uso común ioctles controlar dispositivos de hardware.

Por ejemplo, en sistemas Win32ioctl , las llamadas pueden comunicarse con dispositivos USB o pueden descubrir información sobre la geometría de la unidad 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 volumen RAID en una interfaz unificada e independiente del proveedor similar a ifconfig. [1] [2]

En NetBSD , ioctltambién lo utiliza el sysmonframework. [3]

Terminales

Un uso del ioctlcódigo expuesto a las aplicaciones del usuario final es la E/S de terminal.

Los sistemas operativos Unix han hecho tradicionalmente 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 más tarde con emuladores de terminal y servidores de inicio de sesión remotos que utilizan pseudoterminales . Los dispositivos de puerto serie y 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 insertar un carácter en un flujo de dispositivo. [4]

Extensiones del kernel

Cuando las aplicaciones necesitan extender el núcleo, por ejemplo para acelerar el procesamiento de la red, ioctllas llamadas proporcionan una manera conveniente de conectar el código del espacio de usuario con las extensiones del núcleo. Las extensiones del núcleo 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 una cantidad arbitraria de llamadas, lo que permite programar la extensión sin agregar llamadas del sistema al sistema operativo.

Alternativa de sysctl

Según un desarrollador de OpenBSD , ioctly sysctlson las dos llamadas del sistema para extender el kernel, sysctlsiendo posiblemente 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 en cambio utilizan 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 es experimental y debería ser reemplazado por una sysctl(8)interfaz, en caso de que se desarrollara 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 fue rediseñado en 2007 alrededor de proplib, la llamada al sistema permaneció como ioctly 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 (que van al controlador, regresan del controlador o ambos).

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 forma que se requiera. Los autores 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 esas 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 (indicado por la constante simbólica ENOTTY) a una aplicación que realiza una solicitud a un controlador que no lo reconoce.

El mnemónico ENOTTY(tradicionalmente asociado 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 de teletipo ( tty) generaba este error. Aunque el mnemónico simbólico está fijado por requisitos de compatibilidad, algunos sistemas modernos muestran de manera más útil un mensaje más general como " Operación de control de dispositivo inapropiada " (o una localización del mismo).

TCSETSejemplifica una ioctlllamada en un puerto serial . Las llamadas normales de lectura y escritura en un puerto serial reciben y envían bytes de datos. Una ioctl(fd,TCSETS,data)llamada, separada de dicha E/S normal, controla varias opciones del controlador, como el manejo de caracteres especiales o las señales de salida en el puerto (como la señal DTR ).

Win32

Un Win32 DeviceIoControltoma como parámetros:

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

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

Hay 4 modos de operación definidos que afectan la seguridad del controlador del dispositivo:

  1. METHOD_IN_DIRECT:Se verifica que la dirección del búfer sea legible para el llamador del modo usuario.
  2. METHOD_OUT_DIRECT:El llamador del modo usuario verifica que la dirección del búfer pueda escribirse.
  3. METHOD_NEITHER:Las direcciones virtuales del modo de usuario se pasan al controlador sin asignación ni validación.
  4. METHOD_BUFFEREDLos buffers compartidos controlados por IO Manager se utilizan para mover datos hacia y desde el modo de usuario.

Alternativas

Otras interfaces de llamadas vectorizadas

Los dispositivos y las extensiones del kernel se pueden vincular al espacio de usuario mediante nuevas llamadas de sistema adicionales, aunque este enfoque rara vez se adopta porque los desarrolladores de sistemas operativos intentan mantener la interfaz de llamadas del sistema enfocada y eficiente.

En los sistemas operativos Unix, otras dos interfaces de llamadas vectoriales son populares: la fcntlllamada del sistema ("control de archivos") configura archivos abiertos y se utiliza en situaciones tales como habilitar E/S sin bloqueo ; y la setsockoptllamada del sistema ("establecer opción de socket") configura sockets de red abiertos , una función utilizada para configurar el ipfwfirewall de paquetes en sistemas Unix BSD .

Mapeo de memoria

Unix
Las interfaces de dispositivos y las capacidades de entrada/salida a veces se proporcionan mediante archivos mapeados en memoria . Las aplicaciones que interactúan con dispositivos abren una ubicación en el sistema de archivos correspondiente al dispositivo, como lo harían para una ioctlllamada, pero luego usan llamadas del sistema de mapeo de memoria para vincular una parte de su espacio de direcciones al del núcleo. Esta interfaz es una forma mucho más eficiente de proporcionar transferencia de datos en masa entre un dispositivo y una aplicación de espacio de usuario; ioctllas llamadas del sistema individuales o de lectura/escritura generan sobrecarga debido a las transiciones repetidas del espacio de usuario al núcleo, donde 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 u objetos de mapeo de archivos con nombre; sin embargo, para controladores de dispositivos simples, los DeviceIoControl METHOD_accesos estándar son suficientes.

Enlace de red

Netlink es un mecanismo tipo 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 del sistema del núcleo. Sin embargo, al proporcionar un lugar para que los desarrolladores "guarden" fragmentos de las interfaces de programación del núcleo, ioctllas llamadas complican la API general de usuario a núcleo. Un núcleo que proporciona varios cientos de llamadas del sistema puede proporcionar varios miles de llamadas ioctl.

Aunque la interfaz de ioctllas llamadas parece algo diferente de 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 la expansión de la interfaz de llamadas al sistema del núcleo se podrían aplicar a ioctllas interfaces.

Para los desarrolladores de aplicaciones, las llamadas al sistema no se diferencian en nada de las subrutinas de la aplicación; son simplemente llamadas a funciones que toman argumentos y devuelven valores. Las bibliotecas de tiempo de ejecución del sistema operativo ocultan la complejidad que implica invocar llamadas al sistema. Desafortunadamente, las bibliotecas de tiempo de ejecución no hacen que ioctllas llamadas sean tan transparentes. Las operaciones simples, como descubrir las direcciones IP de una máquina, a menudo requieren una maraña de ioctlllamadas, cada una de las cuales requiere números mágicos y estructuras de argumentos. [ cita requerida ]

Libpcap y libdnet son dos ejemplos de bibliotecas Unix de terceros diseñadas para enmascarar la complejidad de ioctllas interfaces, para la captura de paquetes y la E/S de paquetes, respectivamente.

Seguridad

Las interfaces de usuario a núcleo de los sistemas operativos principales suelen ser objeto de auditorías exhaustivas para detectar fallos de código y vulnerabilidades de seguridad antes de su lanzamiento. Estas auditorías suelen centrarse en las interfaces de llamadas del sistema bien documentadas; por ejemplo, los auditores pueden asegurarse de que las llamadas de seguridad sensibles, como el cambio de ID de usuario, solo estén disponibles para los usuarios administrativos.

ioctlLas interfaces son más complicadas, más diversas y, por lo tanto, más difíciles de auditar que las llamadas del sistema. Además, dado que ioctllas llamadas pueden ser proporcionadas por desarrolladores externos, a menudo después de que se haya lanzado el sistema operativo principal, ioctllas implementaciones de llamadas pueden recibir menos escrutinio y, por lo tanto, albergar más vulnerabilidades. Por último, muchas ioctlllamadas, en particular para controladores de dispositivos de terceros, no están documentadas.

Dado que el controlador de una ioctlllamada reside directamente en el modo kernel, la entrada del espacio de usuario debe validarse cuidadosamente. Los usuarios locales pueden aprovechar las vulnerabilidades en los controladores de dispositivos al pasar búferes no válidos a ioctllas llamadas.

Los sistemas operativos Win32 y Unix pueden proteger el nombre de un dispositivo de espacio de usuario del acceso por parte de aplicaciones con controles de acceso específicos aplicados al dispositivo. Pueden surgir problemas de seguridad cuando los desarrolladores de controladores de dispositivos no aplican controles de acceso adecuados al objeto accesible del espacio de usuario.

Algunos sistemas operativos modernos protegen el núcleo del código hostil del espacio de usuario (como aplicaciones que han sido infectadas por vulnerabilidades de desbordamiento de búfer ) mediante envoltorios de llamadas del sistema. Los envoltorios de llamadas del sistema implementan un control de acceso basado en roles al especificar qué llamadas del sistema pueden ser invocadas por qué aplicaciones; los envoltorios pueden, por ejemplo, usarse para "revocar" el derecho de un programa de correo a generar otros programas. ioctlLas interfaces complican los envoltorios de llamadas del sistema porque hay una gran cantidad de ellos, cada uno de los cuales toma diferentes argumentos, algunos de los cuales pueden ser requeridos por programas normales.

Lectura adicional

Referencias

  1. ^ Niklas Hallqvist (2002); Marco Peereboom (2006). "bio(4) — pseudodispositivo de túnel ioctl de E/S de bloque". Referencia cruzada BSD . OpenBSD .{{cite web}}: CS1 maint: nombres numéricos: lista de autores ( enlace )
    • "bio — pseudodispositivo de túnel ioctl de E/S de bloque". Página del manual de OpenBSD del servidor.
  2. ^ Marco Peereboom (2005). «bioctl(8) — Interfaz de gestión RAID». Referencia cruzada de BSD . OpenBSD .
    • "bioctl — Interfaz de gestión RAID". Página del manual del servidor 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: Solutions & Examples for Perl Programmers (2.ª edición). Sebastopol, California: O'Reilly Media, Inc. (publicado en 2003). pág. 482. ISBN 9780596554965. Recuperado el 15 de noviembre de 2016. [...] TIOCSTI [...] significa 'control de E/S de terminal, simular 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 desde ese dispositivo, obtenga el carácter que usted puso allí.
  5. ^ Federico Biancuzzi (2004-10-28). "OpenBSD 3.6 Live". ONLamp . O'Reilly Media . Archivado desde el original el 2004-10-29 . Consultado el 20 de marzo de 2019 . Hay dos llamadas al sistema que se pueden usar para agregar funcionalidad al núcleo (sin agregar otra llamada al sistema): ioctl(2) y sysctl(3). Se eligió esta última porque era muy simple implementar la nueva característica.
  6. ^ Tim Rightnour; Bill Squier (19 de diciembre de 2007). "envsys -- Environmental Systems API". 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 núcleo, en caso de que se desarrolle uno.
  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 . pp. 901-906. doi :10.1109/ICNSC.2007.372901. ISBN 978-1-4244-1076-7. IEEE ICNSC 2007, págs. 901—906.
  8. ^ Constantine A. Murenin (21 de mayo de 2010). "6.1. Cronología del marco de trabajo; 7.1. NetBSD envsys / sysmon". Sensores de hardware OpenBSD: monitoreo ambiental y control de ventiladores ( tesis de maestría ). Universidad de Waterloo : UWSpace. hdl : 10012/5234. ID del documento: ab71498b6b1a60ff817b29d56997a418.
  9. ^ McIlroy, MD (1987). Un lector de Unix para investigación: extractos anotados del Manual del programador, 1971–1986 (PDF) (Informe técnico). CSTR. Bell Labs. 139. Archivado desde el original (PDF) el 30 de julio de 2023.