Como o SO detecta violações de acesso à memória

12

Como um sistema operacional (de preferência o Linux) sabe que você acessou um local de memória ao qual não tem permissão?

Essa pergunta foi inspirada por esses malditos indicadores! O que eu vejo é: tudo nos computadores tem a ver com um compromisso entre velocidade, segurança, integridade e outras coisas.

Eu estou bem ciente dos mapas de memória no Linux, mas me parece um pouco ridículo que o kernel verifique se o local que você está tentando acessar reside em um intervalo válido TODA vez que você faz um acesso. Parece que perderia muito tempo, o que poderia ser gasto fazendo algo mais produtivo (mas possivelmente menos seguro sem verificação!). Ou talvez ele se lembre de todos os acessos recentes e os verifique em todos os marcadores do temporizador de hardware? (Mas isso parece inseguro e, mais uma vez, lento.)

Fiquei surpreso que esta pergunta parece não ter sido respondida em qualquer lugar. É algo que eu sempre me perguntei. Isso me faz pensar que há uma seção de hardware que fará isso em nome do sistema operacional, em um nível agradável e conveniente de abstração. Mas ainda assim, seria necessário carregar os próximos mapas de memória de processos em cada alternância de contexto, o que novamente parece lento.

Então, sim, de qualquer forma, vou continuar: como um sistema operacional detecta uma violação de memória?

obrigado

Doddy
fonte

Respostas:

11

(A resposta a seguir pressupõe uma plataforma "moderna" de desktop, servidor ou plataforma incorporada de ponta (como smartphones e também sistemas cada vez menores). Para sistemas x86, moderno significa 386 e acima. A resposta a seguir também pressupõe uma SO "moderno", como quase qualquer unix ou Windows desde 95.)

Isso não está acontecendo no sistema operacional, está acontecendo no processador, especificamente na MMU ( unidade de gerenciamento de memória ) . A MMU suporta endereçamento virtual, pelo qual os bits que compõem um ponteiro não indicam diretamente a localização física dos bits na memória.

Em uma MMU típica, quando um ponteiro é desreferenciado, a MMU divide os bits em dois grupos: os bits de ordem superior compõem o número da página e os bits de ordem inferior compõem o endereço dentro da página. A maioria das máquinas de desktop e servidor usa páginas de 4kB. A MMU consulta o número da página virtual em uma tabela chamada TLB (é o que você chamou de "mapas de memória de processo"). O TLB indica o número da página física que corresponde a esta página virtual. A MMU busca os dados da página física na memória.

Se o TLB não contiver uma entrada para esse número de página virtual específico, a MMU notificará o processador de que ocorreu um acesso inválido; isso geralmente é chamado de exceção.

Observe que eu não mencionei o sistema operacional até agora. Isso porque toda essa operação é independente do sistema operacional. O sistema operacional entra em ação porque configura as coisas de duas maneiras:

  • O sistema operacional é responsável por alternar tarefas. Quando isso ocorre, como você suspeitou, ele salva o TLB atual e o substitui pelo TLB salvo para a próxima tarefa agendada. Dessa forma, cada processo possui um TLB; portanto, o endereço 0x123456no processo X pode não apontar para o mesmo local real na RAM que o mesmo endereço no processo Y ou pode simplesmente ser inválido. Se um processo tenta desreferenciar um ponteiro fora do seu espaço de endereço, ele não alcança o espaço de outro processo, mas não chega a lugar nenhum .

  • O sistema operacional decide o que acontece quando uma exceção é gerada. Ele pode encerrar o processo de acesso à memória inválido (falha de segmentação, falha de proteção geral, ...). Essa também é a maneira pela qual a troca é implementada: o manipulador de exceção pode decidir buscar alguns dados do espaço de troca, atualizar o TLB adequadamente e executar o acesso novamente.

Observe que a MMU fornece segurança porque o processo não pode alterar seu próprio TLB. Somente o kernel do sistema operacional pode alterar TLBs. O funcionamento das permissões de alteração do TLB está além do escopo desta resposta.

Gilles 'SO- parar de ser mau'
fonte
6

1) Segfaults são detectados pela unidade de gerenciamento de memória. Quando você solicita memória, o sistema operacional solicita à Unidade de Gerenciamento de Memória que obtenha um pouco do hardware. Tem que haver algo que monitore todos os grandes blocos de memória que o sistema operacional oferece a você. O tipo de sistema operacional que transfere para a MMU. Como ele conhece toda a memória que você forneceu, também pode lhe dizer quando você tenta acessar um local de memória que não recebeu das alocações. O sistema operacional especificamente possui um evento para isso, a memória que você não possui. Eventualmente, o sistema operacional mata seu aplicativo, acionando um segfault ou o equivalente em outros sistemas operacionais.

Nem todos os sistemas operacionais têm essa proteção. O MacOS até 9 não tinha nada disso, apesar de o MMU suportar isso. O Win 3.1 também não. O Win95 possuía alguma proteção, pois fazia a transição entre não ter proteção e depois adicionar alguns.

2) O sistema operacional não conhece outros detalhes além disso. Se você tem um ponteiro disperso que acessa a memória que você nunca alocou, ele sabe. Se você tem um que entra em outra parte do seu aplicativo, ele não sabe, é claro. Isso permite que você corrompa isso. É aqui que você obtém pilhas corrompidas, com ponteiros perdidos do seu aplicativo substituindo outras partes do aplicativo.

Então, sim, você pode estragar seus próprios dados. Se você tem um ponteiro disperso que sobrescreve seu próprio aplicativo, espera que você acerte sua pilha, pois isso provavelmente causará outra violação ao tentar retornar a pilha, mas se você acertar seus próprios dados, nunca saberá.

Você pode tentar ser mais rigoroso do que 'sem proteção', existe uma ferramenta chamada Electric Fence ( http://perens.com/FreeSoftware/ElectricFence/ ) que fará com que seu MMU trabalhe um pouco mais e faça com que ele detecte mais falhas, panes.

Rich Homolka
fonte
Ok, você pode ser mais específico sobre como isso funciona? Como, como ele sabe que um processo específico não pode acessar um local específico? O que indica quais processos podem acessar onde? Como isso distingue? Obrigado
Doddy
1
@panic - procure Memory_management_unit na wikipedia e nos links dessa página. Observe que o estado do processo inclui o status da MMU. Você pode gastar semestres no design, recursos e integração da MMU.
precisa saber é o seguinte