Interface Hardware-Software
Modo Protegido de Operação de
Processadores x86 – Proteção
Descritores
gdt_data:
dd 0 ; null descriptor dd 0
; gdt code: ; code descriptor dw FFFFh ; limit low dw 0 ; base low db 0 ; base middle db 10011010b ; access db 11001111b ; granularity db 0 ; base high ... Descritor 0 Descritor 1
Usando Seletores
jmp 08h:Stage3 ... Stage3: mov ax, 0x10 ... Colocando o seletor 08h no CSFluxo de Carregamento de Registradores de
Segmentos
Seletores só são carregados nos registradores de segmentos depois da verificação do nível de privilégio, tipo de acesso eProteção Via Nível de Privilégio
O suporte a níveis de privilégio permite restrições de:
Acesso a dados
Chamadas a procedimentos Instruções privilegiadas
Os novos registradores e estruturas de dados introduzidos
na arquitetura IA-32 facilitam a proteção a acessos
indevidos
– Registradores de segmentos
– Seletores
– Descritores de segmentos
CPL, RPL e DPL
CPL (Current Privilege Level)
- Nível de privilégio do código sendo executado
- Encontra-se no registrador CS e SS (na parte escondida)
RPL (Requestor Privilege Level)
- Nível de privilégio do código que origina o seletor - Encontra-se no seletor
- Pode ser alterado com instruções específicas
DPL (Descriptor Privilege Level)
- Nível de privilégio do segmento ou do gate - Encontra-se no descritor
Esquemas de Proteção com Níveis de Privilégio
Níveis de privilégios são verificados quando se carrega um
seletor para um descritor no registrador de segmento
- Utiliza-se o CPL, RPL e DPL
A forma de verificação é diferente dependendo do tipo de
seletor que se deseja carregar
- Código - Dados
Acesso a Segmentos de Dados
Seletores de segmentos de dados devem ser carregados
no registradores DS,ES,FS,GS ou SS
- Com instruções como: MOV, POP, LDS, LES, LFS, LGS, etc
Max(CPL,RPL) <= DPL
Ou seja, CPL e RPL devem ter um nível de privilégio
maior ou igual a DPL
Exemplo de Acesso Inválido a Segmento de
Dados
Acesso a Segmentos de Pilha
A regra de acesso é mais restrita
Acesso a Segmentos de Código
Transferência de controle pode resultar em mudança do
segmento de código executado
- Quando há desvios inter-segmentos
- Instruções que provocam transferência: CALL, JMP, SYSENTER, SYSEXIT, RET, etc
As regras de acesso a segmentos de código diferem das
de acesso a dados
As regras diferem se:
- Acesso for a segmentos de código non-conforming - Acesso for a segmentos de código conforming
Acesso a Segmentos de Código sem Gates
Informações verificadas neste tipo de acesso
- CPL do segmento que contém código que chamou a rotina - RPL do seletor para o segmento destino que contém rotina - DPL do descritor do segmento destino que contém rotina - Bit C do descritor do segmento destino que contém rotina
Acesso a Segmentos de Código Non-Conforming
Maioria dos segmentos de código são non-conforming
- Transferência de controle só pode ocorrer entre segmentos de mesmo nível de privilégio (exceto quando um gate é
usado)
Se (C == 0)
CPL == DPL &&
RPL <= CPL
Exemplo de Acesso Válido a Segmento
Non-Conforming
Exemplos de Acessos Inválidos a Segmento
Non-Conforming
CPL < DPL
Acesso a Segmentos de Código Conforming
Permite que se faça chamadas de um segmento com
menor nível de privilégio para uma rotina localizada em um
segmento com maior nível de privilégio
- CPL não se altera
Geralmente, utilizado em rotinas de bibliotecas utilitárias
if (C == 1)
CPL >= DPL
Valor numérico
Exemplo de Acesso Válido a Segmento
Conforming
Exemplo de Acesso Inválido a Segmento
Conforming
Gates
Gate é um tipo de descritor que permite transferência de
controle segura entre níveis diferentes de privilégio
- É um descritor de sistema
Diferentemente de descritores de segmento, um descritor
de gate contém um ponteiro para um descritor de
segmento
- Geralmente permite acesso a apenas uma parte de um segmento
Tipos de Gates
Call Gates
- Usados para controlar acesso a rotinas de outros segmentos - Localizados na GDT ou LDT
Interrupt Gates e Trap Gates
- Usados para controlar acesso a rotinas de interrupção - Localizados na IDT
Task Gates
- Usados para controlar acesso entre diferentes tarefas - Localizados na GDT
Call Gates
Permite controlar que partes de um segmento de código
possam ser acessadas por outro segmento de código
Forma mais segura de transferência de controle
Funções principais:
- Especifica o segmento de código a ser acessado
- Especifica o ponto de entrada para uma rotina no segmento de código especificado
- Determina o nível de privilégio requerido do caller que tenta acessar a rotina
- Se ocorrer uma troca de pilha, especifica o número de parâmetros que devem ser copiados entre as pilhas
- Define o tamanho dos valores a serem adicionados na pilha de destino
Descritor de um Call Gate
Target Code-Segment Selector
- Especifica o descritor do segmento de código a ser acessado - Este seletor é carregado no CS na transferência de controle
Target Code-Segment Offset
- Especifica o ponto de entrada para uma rotina no segmento de código especificado
Transferência de Controle com Call Gates
Um “far” pointer para o gate é fornecido como o operando
destino em uma instrução CALL ou JMP
- Seletor deste pointer identifica o call gate
- Instruction offset é necessário, porém é descartado pelo processador
Uso Típico de Call Gates: Sistema Operacional
SO tem serviços (rotinas) que podem ser utilizados tanto
por programas de aplicação quanto pelo próprio SO
- Call Gates podem ser definidos para rotinas que permitam o acesso a todos os níveis de privilégio (Ex: rotinas de E/S)
- Call Gates mais privilegiados podem ser definidos para rotinas que só podem ser chamadas pelo SO (Ex:rotinas que
inicializam drivers)
Aplicação
Acesso a Segmentos de Código com Gates
Informações verificadas neste tipo de acesso
- CPL do segmento que contém código que chamou a rotina - RPL do seletor para o call gate
- DPL do call gate (DPLg)
- DPL do descritor do segmento destino que contém rotina (DPLs)
Regras de Acesso Para Segmentos Destinos
Conforming
Nível de privilégio do segmento atual deve ser maior ou
igual ao do descritor do call gate
CPL <= DPLg &&
RPL <= DPLg &&
DPLs <= CPL
Regras de Acesso Para Segmentos Destinos
Non-Conforming
Regras diferem um pouco se utilizado JMP ou CALL para
um call gate, quando o segmento destino é non-conforming
- Somente CALL pode mudar para um segmento non-conforming de maior privilégio
CPL <= DPLg &&
RPL <= DPLg
Regra Geral:
Se CALL:
DPLs <= CPL
Se JMP:
DPLs == CPL
Exemplo de Acesso Inválido a Segmento via
Call Gate
DPLs > CPL
CPL > DPLg
RPL > DPLg
Exemplo de Acesso Válido a Segmento via Call
Gate
Se o CALL é feito para um segmento non-conforming de
maior privilégio, ocorre uma troca de pilha
Troca de Pilha
A mudança de pilha ocorre por dois motivos
- Evitar que a rotina de maior privilégio não consiga executar da forma correta por espaço insuficiente na pilha
- Evitar que rotinas de menor privilégio interfiram em rotinas de maior privilégio através de pilhas compartilhadas
O SO é responsável por criar pilhas e descritores de pilha
de todos os níveis de privilégio que são usados (por uma
tarefa) e por armazenar os apontadores para ela na TSS
(Task State Segment)
- TSS é apontado por um tipo de descritor de sistema mantido na GDT
- Mesmo se o SO não for multi-tarefa, mas se ele roda no
Troca de Pilha entre Rotinas de Níveis de
Privilégios Diferentes
Pilha de nível de
privilégio maior
Deve empilhar registradores necessários para o retorno da rotinaUso de Call Gates Hoje em Dia
Call gates cairam em desuso há algum tempo
- Principalmente depois do Pentium
Hoje em dia os sistemas operacionais permitem acesso a
rotinas de nível de privilégio maiores, através de interfaces
oficiais, com chamadas de sistema
- São acessíveis através de interrupções de sistema
- Ou através de instruções como SYSENTER(32 bits) ou SYSCALL(64 bits)