Articulo de referencia

Puerta de llamada (Intel)

Una puerta de llamada es un mecanismo de la arquitectura x86 de Intel para cambiar el nivel de privilegio de un proceso cuando ejecuta una llamada a una función predefinida medi...

Una puerta de llamada es un mecanismo de la arquitectura x86 de Intel para cambiar el nivel de privilegio de un proceso cuando ejecuta una llamada a una función predefinida mediante una instrucción CALL FAR.

Descripción general

Las puertas de llamada están diseñadas para permitir que el código con menos privilegios llame a código con un nivel de privilegios superior. 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 al sistema de una manera que puede ser controlada por el sistema operativo .

Las puertas de llamada utilizan un valor de 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 privilegio. Esto es similar al mecanismo utilizado para las interrupciones .

Uso

Suponiendo que el núcleo del sistema operativo ya haya configurado una puerta de llamada , el código simplemente realiza una llamada a FAR con el selector de segmento necesario (el campo de desplazamiento se ignora). El procesador realizará varias comprobaciones para asegurarse de que la entrada sea válida y de que el código estuviera operando con los privilegios suficientes para usar la puerta. Si todas las comprobaciones se superan, se carga un nuevo CS/ EIP desde el descriptor de segmento y la información de continuación se inserta 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 si es necesario. El número de parámetros a copiar se encuentra en el descriptor de la puerta de llamada.

El núcleo puede regresar al programa del 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.

Formato del descriptor de puerta de llamada

typedef struct _CALL_GATE { USHORT OffsetLow ; USHORT Selector ; UCHAR NumberOfArguments : 5 ; UCHAR Reserved : 3 ; UCHAR Type : 5 ; // 01100 en i386, 00100 en i286 UCHAR Dpl : 2 ; UCHAR Present : 1 ; USHORT OffsetHigh ; } CALL_GATE , * PCALL_GATE ;

Uso anterior

Multics fue el primer usuario de puertas de llamada. El Honeywell 6180 tenía puertas de llamada como parte de su arquitectura, pero Multics las simuló en el GE 645, un modelo anterior .

OS/2 fue uno de los primeros sistemas en utilizar las puertas de llamada de Intel para transferir información 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 controladores y 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 puerta 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 no documentada VxDCall en KERNEL32.DLL que esencialmente llama a INT 30h, que cambia el modo de timbre.

Uso moderno

Los sistemas operativos x86 modernos están dejando atrás 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 la transferencia de control en programas x86. Dado que 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 o trampas de software para mayor 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 estas dos últimas, permiten cambiar de un nivel de privilegio arbitrario a otro (si bien superior o igual). Las instrucciones rápidas SYS* solo permiten transferencias de control del anillo 3 al 0 y viceversa.

Problemas de seguridad

Para preservar la seguridad del sistema, la Tabla de Descriptores Globales debe mantenerse en memoria protegida; de lo contrario, cualquier programa podrá crear su propia puerta de llamada y usarla para elevar su nivel de privilegio. Las puertas de llamada se han utilizado en exploits de seguridad de software cuando se han encontrado maneras de eludir 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 ]

Véase también

Referencias

  1. Matt Pietrek , Secretos de programación del sistema Windows 95
  2. El blog del proyecto Xen sobre la escalada de privilegios SYSRET de Intel
  3. Gusano: W32/Gurong.A Descripción F-Secure Labs