Do Zero Ao Um - Instructors ncaio Posted October 31, 2017 at 08:06 PM Do Zero Ao Um - Instructors Share Posted October 31, 2017 at 08:06 PM # # # 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 More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.