Proteção de memória - Memory protection

A proteção de memória é uma forma de controlar os direitos de acesso à memória em um computador e faz parte da maioria das arquiteturas de conjunto de instruções e sistemas operacionais modernos . O principal objetivo da proteção de memória é impedir que um processo acesse a memória que não foi alocada a ele. Isso evita que um bug ou malware em um processo afete outros processos ou o próprio sistema operacional. A proteção pode abranger todos os acessos a uma área especificada da memória, acessos de gravação ou tentativas de executar o conteúdo da área. Uma tentativa de acessar a memória não autorizada resulta em uma falha de hardware , por exemplo, uma falha de segmentação , exceção de violação de armazenamento , geralmente causando o encerramento anormal do processo ofensivo. A proteção de memória para segurança de computador inclui técnicas adicionais, como randomização de layout de espaço de endereço e proteção de espaço executável .

Métodos

Segmentação

A segmentação se refere à divisão da memória de um computador em segmentos. Uma referência a um local de memória inclui um valor que identifica um segmento e um deslocamento dentro desse segmento.

A arquitetura x86 possui vários recursos de segmentação, que são úteis para usar memória protegida nesta arquitetura. Na arquitetura x86, a Global Descriptor Table e a Local Descriptor Tables podem ser usadas para fazer referência a segmentos na memória do computador. Ponteiros para segmentos de memória em processadores x86 também podem ser armazenados nos registradores de segmento do processador. Inicialmente, os processadores x86 tinham 4 registradores de segmento, CS (segmento de código), SS (segmento de pilha), DS (segmento de dados) e ES (segmento extra); mais tarde, outros dois registros de segmento foram adicionados - FS e GS.

Memória virtual paginada

Na paginação, o espaço ou segmento de endereço de memória é dividido em blocos de tamanhos iguais chamados páginas . Usando hardware de memória virtual , cada página pode residir em qualquer local em um limite adequado da memória física do computador ou ser marcada como protegida. A memória virtual torna possível ter um espaço de endereço de memória virtual linear e usá-lo para acessar blocos fragmentados no espaço de endereço de memória física .

A maioria das arquiteturas de computador que suportam paginação também usam páginas como base para proteção de memória.

Uma tabela de página mapeia a memória virtual para a memória física. Pode haver uma tabela de página única, uma tabela de página para cada processo, uma tabela de página para cada segmento ou uma hierarquia de tabelas de página, dependendo da arquitetura e do sistema operacional. As tabelas de páginas geralmente são invisíveis para o processo. As tabelas de página facilitam a alocação de memória adicional, pois cada nova página pode ser alocada de qualquer lugar na memória física.

Alguns sistemas operacionais configuram um espaço de endereço diferente para cada processo, o que fornece limites de proteção de memória rígida. É impossível para um aplicativo sem privilégios acessar uma página que não foi explicitamente alocada a ele, porque cada endereço de memória aponta para uma página alocada para aquele aplicativo ou gera uma interrupção chamada falha de página . As páginas não alocadas e as páginas alocadas a qualquer outro aplicativo não têm nenhum endereço do ponto de vista do aplicativo.

Uma falha de página pode não indicar necessariamente um erro. As falhas de página não são usadas apenas para proteção de memória. O sistema operacional pode gerenciar a tabela de páginas de forma que uma referência a uma página que foi anteriormente trocada para o disco cause uma falha de página. O sistema operacional intercepta a falha de página, carrega a página de memória necessária e o aplicativo continua como se nenhuma falha tivesse ocorrido. Esse esquema, conhecido como memória virtual , permite que os dados da memória não em uso atualmente sejam movidos para o armazenamento em disco e de volta de uma forma que seja transparente para os aplicativos, para aumentar a capacidade geral da memória.

Em alguns sistemas, o mecanismo de falha de página também é utilizada para a protecção do espaço executável , tais como W ^ X .

Chaves de proteção

Um mecanismo de chave de proteção de memória (MPK) divide a memória física em blocos de um tamanho específico (por exemplo, 4 KiB), cada um dos quais tem um valor numérico associado denominado chave de proteção. Cada processo também possui um valor de chave de proteção associado a ele. Em um acesso à memória, o hardware verifica se a chave de proteção do processo atual corresponde ao valor associado ao bloco de memória que está sendo acessado; caso contrário, ocorre uma exceção. Este mecanismo foi introduzido na arquitetura System / 360 . Ele está disponível nos mainframes System z atuais e é amplamente utilizado pelos sistemas operacionais System z e seus subsistemas.

As chaves de proteção do System / 360 descritas acima estão associadas a endereços físicos. Isso é diferente do mecanismo de chave de proteção usado por arquiteturas como o Hewlett-Packard / Intel IA-64 e o Hewlett-Packard PA-RISC , que estão associados a endereços virtuais e permitem várias chaves por processo.

Nas arquiteturas Itanium e PA-RISC, as traduções ( entradas TLB ) têm chaves (Itanium) ou ids de acesso (PA-RISC) associadas a elas. Um processo em execução possui vários registros de chave de proteção (16 para Itanium, 4 para PA-RISC). Uma tradução selecionada pelo endereço virtual tem sua chave comparada a cada um dos registros de chave de proteção. Se algum deles corresponder (além de outras verificações possíveis), o acesso é permitido. Se nenhuma correspondência, uma falha ou exceção é gerada. O manipulador de falhas de software pode, se desejado, verificar a chave ausente em uma lista maior de chaves mantida pelo software; assim, os registros de chave de proteção dentro do processador podem ser tratados como um cache gerenciado por software de uma lista maior de chaves associadas a um processo.

PA-RISC tem 15–18 bits de chave; O Itanium exige pelo menos 18. As chaves são geralmente associadas a domínios de proteção , como bibliotecas, módulos, etc.

No x86, a arquitetura das chaves de proteção permite marcar endereços virtuais para páginas do usuário com qualquer uma das 16 chaves de proteção. Todas as páginas marcadas com a mesma chave de proteção constituem um domínio de proteção. Um novo registro contém as permissões associadas a cada domínio de proteção. As operações de carga e armazenamento são verificadas em relação às permissões da tabela de páginas e às permissões da chave de proteção associadas ao domínio de proteção do endereço virtual, e somente permitidas se ambas as permissões permitirem o acesso. As permissões da chave de proteção podem ser definidas no espaço do usuário, permitindo que os aplicativos restrinjam diretamente o acesso aos dados do aplicativo sem intervenção do sistema operacional. Como as chaves de proteção estão associadas a um endereço virtual, os domínios de proteção são por espaço de endereço, portanto, os processos em execução em diferentes espaços de endereço podem usar cada um dos 16 domínios.

Anéis de proteção

No Multics e nos sistemas derivados dele, cada segmento possui um anel de proteção para leitura, escrita e execução; uma tentativa de um processo com um número de toque maior do que o número de toque do segmento causa uma falha. Existe um mecanismo para chamar com segurança procedimentos que são executados em um anel inferior e retornam ao anel superior. Existem mecanismos para uma rotina em execução com um número de toque baixo para acessar um parâmetro com o maior de seu próprio toque e do toque do chamador.

Segmentação simulada

Simulação é o uso de um programa de monitoramento para interpretar as instruções do código de máquina de algumas arquiteturas de computador. Tal simulador de conjunto de instruções pode fornecer proteção de memória usando um esquema do tipo segmentação e validando o endereço de destino e o comprimento de cada instrução em tempo real antes de realmente executá-los. O simulador deve calcular o endereço de destino e comprimento e comparar isso com uma lista de intervalos de endereços válidos que ele mantém em relação ao ambiente do encadeamento , como quaisquer blocos de memória dinâmica adquiridos desde o início do encadeamento, mais quaisquer slots de memória estática compartilhada válidos. O significado de "válido" pode mudar ao longo da vida do segmento, dependendo do contexto. Às vezes, pode ser permitido alterar um bloco estático de armazenamento, e às vezes não, dependendo do modo de execução atual, que pode ou não depender de uma chave de armazenamento ou estado de supervisor.

Geralmente, não é aconselhável usar esse método de proteção de memória onde existem recursos adequados em uma CPU, pois isso consome um valioso poder de processamento do computador. No entanto, é geralmente usado para fins de depuração e teste para fornecer um nível extra fino de granularidade para violações de armazenamento genéricas e pode indicar precisamente qual instrução está tentando sobrescrever a seção específica de armazenamento que pode ter a mesma chave de armazenamento como armazenamento desprotegido.

Endereçamento baseado em capacidade

O endereçamento baseado em capacidade é um método de proteção de memória que não é usado em computadores comerciais modernos. Neste método, os ponteiros são substituídos por objetos protegidos (chamados capacidades ) que só podem ser criados usando instruções privilegiadas que só podem ser executadas pelo kernel, ou algum outro processo autorizado a fazê-lo. Isso efetivamente permite que o kernel controle quais processos podem acessar quais objetos na memória, sem a necessidade de usar espaços de endereço separados ou alternâncias de contexto . Apenas alguns produtos comerciais usavam segurança baseada em capacidade: Plessey System 250 , IBM System / 38 , arquitetura Intel iAPX 432 e KeyKOS . Abordagens de capacidade são amplamente utilizadas em sistemas de pesquisa como EROS e navegador Combex DARPA. Eles são usados ​​conceitualmente como base para algumas máquinas virtuais , principalmente Smalltalk e Java . Atualmente, o projeto CHERI da Universidade de Cambridge, financiado pela DARPA, está trabalhando para criar uma máquina de capacidade moderna que também oferece suporte a software legado.

Contaminação dinâmica

A contaminação dinâmica é uma técnica para proteger programas de acessos ilegais à memória. Quando a memória é alocada, em tempo de execução, essa técnica mancha a memória e o ponteiro correspondente usando a mesma marca de mancha. As marcas de contaminação são propagadas adequadamente enquanto o programa é executado e são verificadas toda vez que um endereço de memória m é acessado por meio de um ponteiro p ; se as marcas de contaminação associadas a m e p forem diferentes, a execução é interrompida e o acesso ilegal é relatado.

Os processadores SPARC M7 (e superiores) implementam contaminação dinâmica no hardware. A Oracle comercializa esse recurso como Silicon Secured Memory (SSM) (anteriormente denominado Application Data Integrity (ADI)).

O design da CPU lowRISC inclui contaminação dinâmica sob o nome Tagged Memory.

Medidas

O nível de proteção de uma implementação particular pode ser medido pela proximidade com o princípio de privilégio mínimo .

Proteção de memória em diferentes sistemas operacionais

Diferentes sistemas operacionais usam diferentes formas de proteção ou separação de memória. Embora a proteção de memória fosse comum na maioria dos mainframes e em muitos sistemas de minicomputador da década de 1960, a verdadeira separação de memória não era usada em sistemas operacionais de computadores domésticos até o OS / 2 (e no RISC OS ) ser lançado em 1987. Em sistemas anteriores, essa falta de proteção foi até usado como uma forma de comunicação entre processos , enviando um ponteiro entre processos. É possível que os processos acessem a memória do sistema na família de sistemas operacionais Windows 9x .

Alguns sistemas operacionais que implementam proteção de memória incluem:

Em sistemas do tipo Unix, a mprotect chamada do sistema é usada para controlar a proteção da memória.

Veja também

Referências

Notas

links externos