Este artículo necesita citas adicionales para su verificación . ( agosto de 2020 ) |
Una puerta de llamada es un mecanismo en la arquitectura x86 de Intel para cambiar el nivel de privilegio de un proceso cuando ejecuta una llamada de función predefinida utilizando una instrucción CALL FAR.
Las puertas de llamada tienen como objetivo permitir que un código con menos privilegios llame a un código con un nivel de privilegios más alto. Este tipo de mecanismo es esencial en los sistemas operativos modernos que emplean protección de memoria , ya que permite que las aplicaciones de usuario utilicen funciones del núcleo y llamadas del sistema de una manera que pueda ser controlada por el sistema operativo .
Las puertas de llamada utilizan un valor selector especial para hacer referencia a un descriptor al que se accede a través de la tabla de descriptores globales o la tabla de descriptores locales , que contiene la información necesaria para la llamada a través de los límites de privilegios. Esto es similar al mecanismo utilizado para las interrupciones .
Suponiendo que el núcleo del sistema operativo ya ha configurado una puerta de llamada , el código simplemente realiza una llamada FAR con el selector de segmento necesario (se ignora el campo de desplazamiento). El procesador realizará una serie de comprobaciones para asegurarse de que la entrada sea válida y que el código estuviera funcionando con los privilegios suficientes para utilizar la puerta. Suponiendo que todas las comprobaciones sean satisfactorias, se carga un nuevo CS/ EIP desde el descriptor de segmento y se introduce información de continuación en la pila del nuevo nivel de privilegio (SS antiguo, ESP antiguo, CS antiguo, EIP antiguo, en ese orden). También se pueden copiar parámetros de la pila antigua a la nueva pila si es necesario. La cantidad de parámetros a copiar se encuentra en el descriptor de la puerta de llamada.
El núcleo puede regresar al programa de espacio de usuario mediante una instrucción RET FAR que extrae la información de continuación de la pila y regresa al nivel de privilegio externo.
typedef struct _CALL_GATE { USHORT OffsetLow ; USHORT Selector ; UCHAR Número de argumentos : 5 ; UCHAR Reservado : 3 ; UCHAR Tipo : 5 ; // 01100 en i386, 00100 en i286 UCHAR Dpl : 2 ; UCHAR Presente : 1 ; USHORT OffsetHigh ; } CALL_GATE , * PCALL_GATE ;
Multics fue el primer usuario de puertas de llamada. El Honeywell 6180 tenía puertas de llamada como parte de la arquitectura, pero Multics las simuló en el antiguo GE 645 .
OS/2 fue uno de los primeros usuarios de las puertas de llamada Intel para transferir entre el código de aplicación que se ejecuta en el anillo 3, el código privilegiado que se ejecuta en el anillo 2 y el código del núcleo en el anillo 0.
Windows 95 ejecuta los controladores y la conmutación de procesos en el anillo 0, mientras que las aplicaciones, incluidas las DLL de API como kernel32.dll y krnl386.exe, se ejecutan en el anillo 3. El controlador VWIN32.VXD proporciona primitivas clave del sistema operativo en el anillo 0. Permite llamar a funciones de controlador desde aplicaciones de 16 bits (MSDOS y Win16). Esta dirección se obtiene llamando a INT 2Fh, con 1684h en el registro AX. Para identificar para qué VxD se solicita un punto de entrada, el registro BX se establece en el ID de VxD de 16 bits. Al regresar de la instrucción INT, los registros ES.DI contienen un puntero lejano que se puede llamar para transferir el control al VxD que se ejecuta en el anillo 0. El descriptor al que apunta ES es en realidad una compuerta de llamada. [1] Sin embargo, las aplicaciones de 32 bits, cuando necesitan acceder al código del controlador de Windows 95, llaman a la función VxDCall no documentada en KERNEL32.DLL que esencialmente llama a INT 30h, que cambia el modo de anillo.
Los sistemas operativos x86 modernos están abandonando las puertas de llamada CALL FAR. Con la introducción de las instrucciones x86 para llamadas al sistema (SYSENTER/SYSEXIT de Intel y SYSCALL/SYSRET de AMD), se introdujo un nuevo mecanismo más rápido para las transferencias de control de los programas x86. Como la mayoría de las demás arquitecturas no admiten puertas de llamada, su uso era poco frecuente incluso antes de estas nuevas instrucciones, ya que se preferían las interrupciones de software o las trampas por razones de portabilidad, a pesar de que las puertas de llamada son significativamente más rápidas que las interrupciones.
Las puertas de llamada son más flexibles que las instrucciones SYSENTER/SYSEXIT y SYSCALL/SYSRET, ya que a diferencia de las dos últimas, las puertas de llamada permiten cambiar de un nivel de privilegio arbitrario a un nivel de privilegio arbitrario (aunque superior o igual). Las instrucciones rápidas SYS* solo permiten transferencias de control del anillo 3 al 0 y viceversa.
Para preservar la seguridad del sistema, la tabla de descriptores globales debe mantenerse en una memoria protegida, de lo contrario, cualquier programa podrá crear su propia puerta de llamada y usarla para aumentar su nivel de privilegios. Las puertas de llamada se han utilizado en ataques de seguridad de software , cuando se han encontrado formas de evitar esta protección. [2] Un ejemplo de esto es el gusano de correo electrónico Gurong.A , escrito para explotar el sistema operativo Microsoft Windows , que utiliza \Device\PhysicalMemory para instalar una puerta de llamada. [3]