Jump to content

FALANDO SOBRE OOM


ncaio

Recommended Posts

  • Do Zero Ao Um - Instructors
#
#
#	Ncaio - caiogore $! gma1l (..) com
#	FALANDO SOBRE OOM
#       REVISÃO 01 31/10/2017 - TXT AND FILES-> http://8bit.academy/doc/OOM/
#
#

John Von Neumann serrou o pulso e declarou: "Um computador é composto de três partes fundamentais: o processador, os dispositivos de entrada/saída 
e a memoria.". Ele mudou de forma radical o conceito de computadores em meados de 1930. Estamos falando de calculadoras. Infelizmente, a ideia de 
armazenar um programa em memória junto com a parte de dados, demorou a entrar em prática por falta de tecnologia para se construir dispositivos de 
memória. Enquanto isso, os processadores não pararam de evoluir. Isso talvez explique o motivo dos processadores estarem, de longe, mais evoluídos 
em comparação aos dispositivos de memória. Sistemas operacionais lidam elegantemente com essa diferença de velocidade entre dispositivos de memória 
primária e processadores. E este delay tem nome, se chama wait states. Bem, mas este assunto rende muito pano para manga. Dentro deste contexto, o 
assunto segurança não fica de fora. Este documento fala sobre um dos tópicos da filosofia de segurança Linux que é, inclusive, adotada pelo(a) 
Android:

Ensures that user A does not exhaust user B's memory. https://source.android.com/security/overview/kernel-security

Em resumo, sistemas operacionais multiusuários como o Linux, por exemplo, o que fazer para evitar que um usuário não monopolize todo o 'espaço'
disponível de memória, que não comprometa o sistema operacional e/ou os outros demais utilizadores ? Sabemos que erros ocorridos no processo de 
desenvolvimento de uma aplicação podem resultar em um alto consumo de memória em sua execução, assim como intencionalmente ( ou não ), um usuário 
pode desencadear este consumo. Quando um processo ameaça o funcionamento de um computador que utiliza Linux como sistema operacional por causa de 
sua fome incontrolável de memória, um mecanismo chamado Out of Memory (OOM) Killer entra em ação. O OOM é um cão de guarda que observa a consumação 
de memória de um processo e o ataca quando ele passa dos limites. Isso significa que o Linux sempre diz sim quando um programa pede mais memória 
(malloc())! Com isso, ele consegue, ou tenta, executar mais programas. Estamos agora falando de over-commit de memória. Vamos aqui abrir um espaço para 
falarmos sobre memória virtual. Memória virtual é uma abstração da memória física que possibilita mecanismos de segurança, extensão e compartilhamento, 
por exemplo, de forma mais eficiente de quê o acesso direto. O over-commit no Linux vem ativo por padrão! Por isso, um pedido de espaço na memória 'nunca'
é respondido como NULL. Isso é motivo de muita discussão na comunidade em geral e o que nos interessa no momento, é:

* Por padrão, o valor da flag over-commit é zero no Kernel do Linux ( https://www.kernel.org/doc/Documentation/vm/overcommit-accounting );
* Se um aplicativo pede memória, o Linux responde positivamente;
* E quando este pedido de memória perde o controle, o OOM killer entra em ação e assassina o processo.

Claro que é um resumo genérico e existem algumas entrelinhas. No entanto, este é o conhecimento base para continuarmos a falar sobre o mecanismo OOM.

LAB

Para acompanhar estes procedimentos de forma prática, é recomendado o uso de uma máquina virtual com o sistema operacional Linux instalado. 
NÃO execute estes procedimentos fora da máquina virtual! 

Certifique que a flag de over-commit é zero.

cat /proc/sys/vm/overcommit_memory
0
O valor esperado é zero. Como alterar este valor  ?

echo "0" > /proc/sys/vm/overcommit_memory
Os vídeos aqui anexados, apresentam 4 telas de terminais que representam o mesmo host, onde:

* Terminal superior esquerdo: É executada a criação de estrutura com o mkdir;
* Terminal inferior esquerdo: Pontuação do OOM;
* Terminal superior direito: A saída do comando free -m;
* Terminal inferior direito: Tabela de processamento.

Telas: http://8bit.academy/doc/OOM/img-6.png

LAB 01 - NA VIDA REAL

Vamos pegar um exemplo do dia a dia de um administrador para a construção de situações que envolvem memória. 

Chico do Pentest recebeu a seguinte missão: Criar uma estrutura de diretórios com características:  

Exemplo da estrutura de diretórios: http://8bit.academy/doc/OOM/lista-dir.txt

São duas camadas de dez(10) diretórios (0 - 9) que, dentro deles, tem outra camada de dez diretórios. Chico tem um bom conhecimento em shell e 
utiliza para este procedimento, expansão de variáveis. Como ele criou estes dois níveis ? 

mkdir -p {0..9}/{0..9}/
De forma simples, Chico resolveu o problema proposto no laboratório 1

LAB 02 - FATIANDO O PROBLEMA

Não demorou muito para a equipe de desenvolvimento descobrir que a estrutura de pastas solicitadas não atenderia aos requisitos do sistema. O chamado 
retornou para a fila de atendimento de Chico, solicitando a adição de mais quatro níveis. Contabilizando agora, seis níveis. Chico aceita  o desafio e 
logo pensa em aproveitar a linha de comando anterior, adicionando a quantidade de níveis solicitada. E assim fez.

mkdir -p {0..9}/{0..9}/{0..9}/{0..9}/{0..9}/{0..9}/
bash: /usr/bin/mkdir: Argument list too long
Vídeo: http://8bit.academy/doc/OOM/6-levels.webm

Temos aqui dois problemas:

* Dez elevado a sexta potência, igual a 1 milhão de strings para serem carregadas na memória (10^6=1000000);
* 1 milhão de strings é um valor muito alto de argumentos para um único comando mkdir.

O Linux faz over-commit de memória, isso significa que o problema número um seria descartado do processo de resolução de problemas de Chico, se não 
houvesse memória suficiente e que isso fosse degradar o funcionamento do sistema operacional, ele já sabia que o cão e guarda OOM Killer entraria em 
ação. Esta é uma situação que muitos administradores já passaram ou passarão no decorrer de suas carreiras. E a recomendação para este caso é fatiar o 
seu problema. Chico agora tem duas situações:

Utilizar FOR e realizar a criação unitária em 10^6 ciclos. O  exemplo a seguir mostra como o problema 1 não impacta no sistema operacional utilizado. 
Ele foi capaz de carregar 1 milhão de strings na memória  e passar uma por uma ao comando mkdir.

for i in {0..9}/{0..9}/{0..9}/{0..9}/{0..9}/{0..9}/; do mkdir -p $i; done
Utilizar o comando xargs. Este comando irá passar para o mkdir, por exemplo, apenas a quantidade de argumentos que ele suporta naquele momento. 
Em comparação a utilização do FOR, é de longe a solução mais recomendada.

Chico também aprendeu:

* Limitação de recursos é uma prática importante;
* Aprendeu sobre o comando ulimit;
* Aprendeu sobre ARG_MAX ( https://www.in-ulm.de/~mascheck/various/argmax/ ).

PAUSA PARA O OOM

A ideia de cão de guardar foi entendida por Chico. No entanto, ele precisou descobrir mais sobre o comportamento do OOM. Principalmente sobre a 
heurística que determina se um processo passou ou não dos limites. Em sua pesquisa, Chico chegou a seguinte conclusão sobre como a pontuação OOM é 
calculada.

* O primeiro modelo publicado em 2009 não se mostrou efetivo. Já que saia matando qualquer processo e quando necessário, continuava a matar processo 
sem descrição de importância;
* O modelo de 2010 é o que utilizamos hoje;
* Existe uma proposta de melhoria para o modelo atual, publicado em 2013;
* Cada processo tem sua pontuação;
* A abstração fica em proc/<pid>/oom_score;
* A pontuação é baseada na porcentagem de uso de memória RAM + SWAP ;
* O valor 1000 significa 100% de uso da memória;
* 0 significa 0% de uso da memória;
* Para processo root, subtrair 3% da pontuação;
* Existe como desativar um processo da ação matadora do OOM;
* Existe como marcar um processo como alvo preferencial para o OOM;
* Este arquivo é /proc/<pid>/oom_score_adj

Links de referência:
https://lwn.net/Articles/317814/
https://lwn.net/Articles/391222/
https://lwn.net/Articles/548180/

LAB 03 - O CURIOSO

Chico resolveu seu problema anterior utilizando o FOR e aprendeu que poderia resolver de outra forma, com o xargs, por exemplo. Descontente e curioso, 
ele tem a ideia de mandar mais argumentos para o mkdir. Neste caso, ele enviou a criação de oito níveis.

mkdir -p  {0..9}/{0..9}/{0..9}/{0..9}/{0..9}/{0..9}/{0..9}/
Vídeo: http://8bit.academy/doc/OOM/08-levels.webm

O vídeo de exemplo mostra que o gatilho Argument list too long não foi disparado. E com isso, o mkdir começou a pedir memória para armazenar as 
10 ^ 8 = 100000000 strings. Que equivalem mais ou menos, contando com NULL e SLASHES -> 15 bytes, 15 * 100000000 = 1500000000 bytes ou 1.3 GigaByte. 
No canto superior direito ( free -m ) é possível observar o decremento da memória RAM E SWAP, enquanto no canto inferior esquerdo, a pontuação OOM só 
aumenta, até chegar ao ponto que o interpretador de comandos, no canto superior direito, ser assassinado pelo OOM.  

OBS: Chico utilizou uma sequência de comandos para esvaziar o CACHE da memória virtual.

echo "3" > /proc/sys/vm/drop_caches
Chico não para de se perguntar: Por qual motivo 10^6 argumentos geram um Argument list too long e 10^8, não ?

LAB 04 - O REVOLTADO

Chico desabilita o over-commit e chega a conclusão que é perigoso. Ele tem o receio que o seus programas sejam mortos antes de concluírem seus ciclos de 
execução. Sem over-commit, o processo é morto, por padrão, quando utiliza 50% da memória física.

Vídeo: http://8bit.academy/doc/OOM/disable-overcommit.webm

LAB 05 - O MORTO VIVO

Para finalizar, Chico teve a brilhante ideia de executar o comando mkdir para a criação de uma estrutura de 8 níveis e desabilitar o OOM do processo 
executor. 

Vídeo: http://8bit.academy/doc/OOM/score-prio.webm

E para sua surpresa, a pontuação não foi incrementada, o processo consumiu toda a memória RAM + SWAP e mesmo assim foi morto. Até então, tudo ocorreu 
bem, a não ser pelo fato de do suposto PID assassinado continuar na tabela de processamento com o status Z (zombie process).

Depois dos laboratórios, Chico do Pentest aprendeu que tudo precisa de limites e que sempre deve levar o assunto de segurança de recursos a sério.
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...