Una falla de protección general ( GPF ) en las arquitecturas de conjunto de instrucciones (ISA) x86 es una falla (un tipo de interrupción ) iniciada por mecanismos de protección definidos por la ISA en respuesta a una violación de acceso causada por algún código en ejecución, ya sea en el núcleo o en un programa de usuario. El mecanismo se describe por primera vez en los manuales y hojas de datos de Intel para la CPU Intel 80286 , que se introdujo en 1983; también se describe en la sección 9.8.13 del manual de referencia del programador Intel 80386 de 1986. Una falla de protección general se implementa como una interrupción ( vector número 13 (0Dh)). Algunos sistemas operativos también pueden clasificar algunas excepciones no relacionadas con violaciones de acceso, como excepciones de código de operación ilegal , como fallas de protección general, aunque no tengan nada que ver con la protección de memoria. Si una CPU detecta una violación de protección, detiene la ejecución del código y envía una interrupción GPF. En la mayoría de los casos, el sistema operativo elimina el proceso que falla de la cola de ejecución, notifica al usuario y continúa ejecutando otros procesos. Sin embargo, si el sistema operativo no detecta la falla de protección general, es decir, si ocurre otra violación de protección antes de que el sistema operativo regrese de la interrupción GPF anterior, la CPU señala una falla doble , deteniendo el sistema operativo. Si ocurre otra falla ( falla triple ), la CPU no puede recuperarse; desde el 80286, la CPU entra en un estado de parada especial llamado "Apagado", del cual solo se puede salir mediante un reinicio de hardware . El IBM PC AT , el primer sistema compatible con PC que contenía un 80286, tiene hardware que detecta el estado de Apagado y reinicia automáticamente la CPU cuando ocurre. Todos los descendientes del PC AT hacen lo mismo, por lo que en un PC, una falla triple provoca un reinicio inmediato del sistema.
Comportamiento específico
Microsoft Windows
En Microsoft Windows , el fallo de protección general se presenta con distintos idiomas, dependiendo de la versión del producto:
Windows 11 ya no muestra mensajes de error para fallos de protección generales; si se produce un fallo, el programa simplemente se cierra.
En Windows 95, 98 y Me, existe un mensaje de error alternativo, utilizado principalmente con programas de Windows 3.x: "Se ha producido un error en su programa. Para continuar trabajando, haga clic en Ignorar y guarde su trabajo en un archivo nuevo. Para salir de este programa, haga clic en Cerrar. Perderá la información que haya introducido desde el último guardado". Al hacer clic en "Cerrar", aparece uno de los mensajes de error anteriores, según la versión de Windows. A veces, al hacer clic en "Ignorar" también aparece este mensaje.
Unix
En Linux y otros sistemas Unice , los errores se notifican por separado (por ejemplo, error de segmentación para errores de memoria).
Errores de memoria
En los errores de memoria, el programa que falla accede a memoria a la que no debería acceder. Algunos ejemplos son:
- Intentando escribir en una parte de la memoria que solo es de lectura.
- Intentar ejecutar bytes en la memoria que no están designados como instrucciones.
- Intentando leer como datos bytes en la memoria que están designados como instrucciones
- Otros conflictos diversos entre la designación de una parte de la memoria y su uso
Sin embargo, muchos sistemas operativos modernos implementan sus esquemas de control de acceso a memoria mediante paginación en lugar de segmentación, por lo que a menudo las referencias a memoria no válidas en sistemas operativos como Windows se notifican mediante fallos de página en lugar de fallos de protección generales. Los sistemas operativos suelen proporcionar una capa de abstracción (como el manejo de excepciones o señales) que oculta a un programa el mecanismo interno del procesador utilizado para generar un error de acceso a memoria, con el fin de proporcionar una interfaz estándar para gestionar muchos tipos diferentes de condiciones de error generadas por el procesador.
En la arquitectura x86, los fallos de protección generales son específicos de la protección basada en segmentación en lo que respecta a los accesos a memoria. Sin embargo, estos fallos también se utilizan para informar de otras infracciones de protección (además de las de acceso a memoria) cuando se utiliza la paginación, como el uso de instrucciones inaccesibles desde el nivel de privilegio actual (CPL).
Si bien teóricamente es posible que un sistema operativo utilice tanto la paginación como la segmentación, en la mayoría de los casos, los sistemas operativos comunes suelen basarse en la paginación para la mayor parte de sus necesidades de control de acceso a la memoria.
Errores de privilegios
En un ordenador existen ciertas funciones reservadas exclusivamente al sistema operativo . Si un programa ajeno al sistema operativo intenta utilizar alguna de estas funciones, podría provocar un fallo de seguridad general.
Además, existen ubicaciones de almacenamiento reservadas tanto para el sistema operativo como para el procesador. Debido a esta reserva, son de solo lectura, y cualquier intento de escribir datos en ellas por parte de un programa sin privilegios produce un error.
Causas técnicas de las fallas
El procesador genera fallos de protección general cuando encuentra una instrucción protegida que excede el nivel de permisos de la tarea que se está ejecutando, ya sea porque un programa en modo de usuario está intentando ejecutar una instrucción protegida o porque el sistema operativo ha emitido una solicitud que pondría al procesador en un estado indefinido.
Los sistemas operativos modernos detectan y gestionan los fallos de protección generales. Por lo general, si el fallo se origina en un programa en modo usuario, este se cierra. Sin embargo, si el fallo se origina en un controlador del sistema principal o en el propio sistema operativo, este suele guardar información de diagnóstico en un archivo o en la pantalla y deja de funcionar. El sistema reinicia el equipo o muestra una pantalla de error , como una pantalla azul de la muerte o un error de kernel .
Se han superado los límites del segmento.
Se pueden superar los límites de segmento:
- con segmentos de código (CS), segmentos de datos (DS) o registros ES, FS o GS (segmentos adicionales); o
- acceso a tablas de descriptores como la Tabla de Descriptores Globales (GDT), la Tabla de Descriptores de Interrupción (IDT) y la Tabla de Descriptores Locales (LDT).
Se han violado los permisos del segmento.
Los permisos de segmento pueden ser violados por:
- Saltar a segmentos no ejecutables
- escribir en segmentos de código o en segmentos de solo lectura
- lectura de segmentos de solo ejecución
Segmentos cargados ilegalmente
Esto puede ocurrir cuando:
- Un segmento de pila (SS) se carga con un selector de segmento para un segmento de solo lectura, ejecutable, nulo o con privilegios de descriptor que no coinciden con los privilegios actuales en CS.
- un segmento de código (CS) cargado con un selector de segmento para un segmento de datos, de sistema o nulo.
- SS, DS, ES, FS o GS son segmentos cargados con un selector de segmento para un segmento del sistema.
- SS, DS, ES, FS o GS son segmentos cargados con un selector de segmento para un segmento de código de solo ejecución.
- acceso a la memoria mediante los registros DS, ES, FS o GS, cuando contienen un selector nulo
Traspuesta
Pueden producirse fallos en la estructura del segmento de estado de la tarea (TSS) cuando:
- cambiar a una tarea que requiere atención durante una llamada o una instrucción de salto
- cambiar a una tarea disponible durante una instrucción de retorno de interrupción (IRET)
- utilizando un selector de segmento en un interruptor que apunta a un descriptor TSS en el LDT
Misceláneas
Otras causas de fallos en la protección general son:
- Intentar acceder a un controlador de interrupción/excepción desde el modo virtual 8086 cuando el nivel de privilegio del descriptor de segmento de código (DPL) del controlador es mayor que cero.
- Intentando escribir un uno en los bits reservados de CR4.
- intentar ejecutar instrucciones privilegiadas cuando el nivel de privilegio actual (CPL) no es cero
- intentar ejecutar una sola instrucción con una longitud mayor a 15 bytes (posiblemente anteponiendo a la instrucción prefijos superfluos) [ 2 ]
- escribir en un bit reservado en una instrucción MSR
- acceso a una puerta que contiene un selector de segmento nulo
- ejecutar una interrupción de software cuando el CPL es mayor que el DPL establecido para la puerta de interrupción
- El selector de segmento en una puerta de llamada, interrupción o trampa no apunta a un segmento de código.
- violando las reglas de privilegio
- habilitar la paginación mientras se desactiva la protección
- consultando la tabla de descriptores de interrupción después de una interrupción o excepción que no sea una interrupción, trampa o puerta de tarea.
- SSE heredado : El operando de memoria no está alineado a 16 bytes.
Referencias
Lecturas adicionales
- Manual del desarrollador de software de la arquitectura Intel – Volumen 3: Programación del sistema
- Tecnología de sistemas operativos
- Errores informáticos