Não existem mais “Sextas-feiras Azuis”
(brendangregg.com)- Em 19 de julho de 2024, a pane global do Windows foi um caso em que uma atualização de driver de kernel de um produto de segurança levou a uma leitura incorreta de memória, causando tela azul e loops de inicialização
- O eBPF roda dentro do kernel, mas foi projetado para rejeitar código perigoso com um verificador e sandbox, impedindo que um único programa derrube o sistema inteiro
- O Linux já inclui eBPF, e quando o eBPF for Windows da Microsoft estiver pronto para produção, o software de segurança do Windows também poderá migrar da mesma forma
- Grandes empresas de tecnologia como Google, Meta e Cisco, além de startups de segurança baseadas em eBPF, estão expandindo produtos de segurança e sistemas de detecção aproveitando velocidade, visibilidade profunda e garantias de segurança
- Empresas que compram software comercial com drivers de kernel ou módulos de kernel podem adotar o suporte a eBPF como requisito para fornecedores: no Linux agora, no Windows em breve
Os riscos do código de kernel expostos pela pane do Windows de 19 de julho
- A pane de 19 de julho de 2024 foi um caso sem precedentes que mostrou os riscos inerentes da programação de kernel
- Computadores Windows no mundo todo sofreram tela azul (blue screen of death) e loops de inicialização, causando interrupções em hospitais, companhias aéreas, bancos, supermercados e emissoras
- A causa foi uma atualização de configuração (config update) de um produto de segurança amplamente usado, que incluía um driver de kernel para sistemas Windows
- Após a atualização, o driver de kernel tentou ler memória incorreta, e esse tipo de erro pode derrubar o kernel
Quedas que o eBPF pode evitar
- eBPF não é mais apenas uma sigla, e sim um ambiente seguro de execução no kernel, semelhante ao runtime seguro de JavaScript embutido em navegadores web
- Usuários de Linux provavelmente já têm eBPF no sistema, já que ele foi incorporado ao kernel Linux há alguns anos
- Programas eBPF são restritos para não poder derrubar o sistema inteiro
- Um verificador (verifier) de software analisa a segurança
- O programa roda, na prática, dentro de um sandbox
- Se o verificador encontrar código inseguro, o programa é rejeitado e não é executado
- O verificador da implementação Linux é composto por mais de 20 mil linhas de código, com contribuições da indústria, como Meta, Isovalent e Google, e da academia, como Rutgers University e University of Washington
- Segurança reforçada, baixo uso de recursos e prevenção de falhas são vantagens centrais do eBPF
Aplicabilidade em Linux e Windows
- A empresa de segurança que causou essa pane já estava em processo de adoção de eBPF em sistemas Linux
- Quando o suporte a eBPF para Windows da Microsoft estiver pronto para produção, o software de segurança do Windows também poderá ser portado para eBPF
- Um agente de segurança do Windows migrado para eBPF passaria a não poder causar falhas no kernel do Windows
Adoção pelo setor de segurança e por grandes empresas de tecnologia
- As startups de segurança baseadas em eBPF Oligo e Uptycs destacaram, após a pane recente, as vantagens da migração para eBPF
- Grandes empresas de tecnologia também estão adotando eBPF para segurança
- A Cisco adquiriu a startup de eBPF Isovalent e anunciou o Cisco Hypershield, uma malha para aplicação de políticas de segurança e monitoramento
- Google e Meta detectam e bloqueiam comportamentos maliciosos em larga escala com base na velocidade, visibilidade profunda e garantias de segurança do eBPF
- Além de segurança, o eBPF também é usado em redes e observabilidade (observability)
Limites do eBPF e complementos operacionais
- A pior coisa que um programa eBPF pode fazer é consumir mais recursos do que o desejável, como ciclos de CPU ou memória
- Ele não impede código desperdiçador, mas bloqueia problemas graves que levariam a uma queda do sistema
- O eBPF também é uma tecnologia nova, então houve bugs no código de gerenciamento, incluindo um caso recente de kernel panic no Linux descoberto pela mesma empresa de segurança que apareceu nas notícias
- Quando esses bugs são corrigidos no eBPF, a correção pode beneficiar todos os fornecedores que usam eBPF, melhorando a segurança geral mais rapidamente
- O risco de implantação não se resolve apenas com eBPF, e ainda existem práticas operacionais que podem ser usadas em conjunto
- testes canário
- rollout gradual
- engenharia geral de resiliência
Mudanças que compradores podem exigir
- O ponto importante da abordagem com eBPF é que ela representa uma solução de software que será fornecida nativamente tanto no kernel Linux quanto no kernel Windows, e que já foi adotada para esse caso de uso
- Se uma empresa paga por software comercial que inclui drivers de kernel ou módulos de kernel, ela pode tornar o eBPF um requisito
- No Linux isso já é possível hoje, e no Windows será em breve
- Alguns fornecedores já adotaram eBPF de forma proativa, mas outros podem precisar da pressão dos clientes que pagam por seus produtos
1 comentários
Opiniões no Hacker News
Ao olhar a lista de “hooks” oferecidos pelo eBPF para Windows, ela parece distante da realidade. No momento, limita-se mais ou menos a pacotes de entrada e operações de socket, como se a Microsoft esperasse que o Berkeley Packet Filter fosse usado literalmente para filtragem de pacotes
Isso é diferente de filtragem de I/O, criação/uso de objetos e dos inúmeros pontos em que drivers como os da CrowdStrike se prendem ao kernel NT
Além disso, para monitorar outros lixos de terceiros rodando no espaço do kernel, o antimalware também precisa estar dentro do kernel. O ELAM (early-launch anti-malware) carrega primeiro o driver antimalware para que ele monitore o comportamento de outros drivers, e é muito duvidoso que algo assim seja possível com eBPF
A Microsoft ainda tem um caminho muito longo se quiser substituir drivers antimalware em espaço de kernel por eBPF
https://microsoft.github.io/ebpf-for-windows/ebpf__structs_8...
Como analogia, seria uma situação em que as pessoas fazem operações bancárias em sites com JavaScript no Google Chrome, enquanto no Microsoft Edge aparece: “não oferecemos suporte a JavaScript, então baixe e execute este .EXE”. A questão é menos “se” a Microsoft vai oferecer suporte a JavaScript ou eBPF, e mais “quando”
Não quero discordar de alguém como Brendan Gregg, mas gostaria que os fornecedores dessa área investigassem toda a cadeia de falhas de forma mais abrangente. Quando, três dias depois da falha, surge uma proposta dizendo que “x resolve o problema que ocorreu na data y”, fico cauteloso
Pode estar certo, mas, sem análise, pontos cegos podem permanecer, e pode haver muitas alternativas que, após revisão, devem ser devidamente descartadas
Em especial, é difícil concordar com a parte de que “o pior resultado negativo é apenas desperdício de CPU”. Isso pode valer para certas classes de bugs, mas há muitos modos de falha em que um conjunto de regras incorreto transforma gravemente o sistema em um tijolo e dificulta a recuperação
Isso não significa que um módulo de segurança baseado em eBPF não possa ser a escolha certa para muitos fornecedores; significa entender quais riscos ele evita e quais não evita, e que parte da cadeia de falhas ele aborda
https://opensource.microsoft.com/blog/2021/05/10/making-ebpf...
https://lwn.net/Articles/857215/
Se houver preocupações reais, também existem canais de discussão para enviar opiniões, organizados no GitHub
https://github.com/microsoft/ebpf-for-windows
Talvez as respostas já existam; se não, podem ser tratadas lá
Isso não está certo. Se a estrutura é tal que o sistema precisa de algum trecho de código para rodar, então, quando esse código quebra, o sistema nem deveria iniciar. Ignorar a falha é estranho
Por exemplo, se o código de driver de algum dispositivo médico garante uma trava de segurança para não queimar uma pessoa, eu preferiria que tudo parasse a que ele continuasse operando como se nada tivesse acontecido com o mecanismo de segurança desligado
No fim, mesmo descendo na pilha, continua sendo o mesmo problema
Não sei como o Linux realmente faz, mas dá para imaginar um mundo em que o comportamento diante de entradas inválidas seja configurável
Além disso, essa afirmação nem sempre é verdadeira. Concordo no caso geral, mas em certos contextos é preciso continuar funcionando. Um exemplo que vem imediatamente à mente é o computador de orientação de uma sonda automática de pouso em Marte. O atraso de ida e volta com a Terra é longo demais para empurrar a responsabilidade para outro lugar
Se encerrar, ela cai; mas, se fizer o melhor possível em um estado danificado, provavelmente só vai cair, então essa opção pode ser melhor
Se o sistema operacional inteiro virar um tijolo, vira um problema muito maior, porque um técnico de TI precisa consertar manualmente. Caso contrário, bastaria atualizar o driver defeituoso
Um carro também não deixa de dar partida só porque está sem fluido do limpador de para-brisa
A maioria das organizações afetadas na sexta-feira teria preferido um pequeno aumento no risco de ataque por malware ou uso não autorizado durante 24 horas ao colapso total de TI que de fato sofreram
Além disso, o bug não precisava necessariamente causar uma tela azul. O sistema poderia ter continuado rodando em um estado indefinido e com resultados ilimitados
Com eBPF, pelo menos seria possível detectar parte dos erros possíveis e tomar uma decisão de gestão de risco com base nisso
Para atualizar, o chamador precisa chamar outra função, de modo que a responsabilidade fica com o chamador, não com alguém capaz de mexer no kernel por um caminho lateral
Se não houver uma função correspondente ao hash indicado, ela não pode ser chamada; e, mesmo que haja, não pode ser chamada de outra forma que não a pretendida, obtendo a propriedade desejada de “funcionar perfeitamente ou não funcionar de jeito nenhum”
Além disso, a reação a um estado incorreto não precisa necessariamente ser “ignorar”. Também poderia desativar logins limitados de usuário ou desligar a tela
Se a preocupação é que malware possa explorar isso, questiono se é uma boa ideia acreditar que o próprio sistema possa lidar com esse cenário quando o malware já é capaz de reescrever os arquivos em disco do antivírus
Pode ser mais seguro reportar a uma camada superior de segurança e deixar que sistemas externos desativem ou restrinjam o acesso à rede. Indo além, essas medidas só precisariam de permissão de observação, não de permissão para intervir no sistema, o que também reduz a chance de o próprio sistema antivírus se tornar um caminho para malware ou a causa desse tipo de bug
eBPF é excelente e, usado para vários propósitos, pode melhorar muita coisa, mas dizer que “o computador não vai travar por causa de uma atualização de software ruim” me parece exagero
Mesmo supondo que o BPF em si não tenha bugs, o escopo dos hooks do kernel é bem amplo, esses hooks chamam código eBPF, e esse código pode, por sua vez, chamar o kernel
https://www.man7.org/linux/man-pages/man7/bpf-helpers.7.html
Em especial, bpf_probe_read_kernel() é muito usado, mas não é seguro. Há bastante esforço para evitar OOPS ou crashes, mas isso está longe de ser perfeito
No restante da lista também há muitas coisas que podem estragar facilmente o sistema, mesmo que não causem de fato um oops ou panic
E, se for uma ferramenta que detecta e bloqueia “comportamento malicioso” no espaço de usuário, ela também pode começar a classificar tudo como malicioso e tornar o computador inutilizável
Por outro lado, o eBPF não tem um modelo de segurança real do lado do espaço de usuário. A anexação efetiva de programas eBPF não acontece como uma operação de permissão razoável sobre o objeto do kernel ao qual eles se prendem, mas por meio da chamada de sistema bpf(), e não há nenhum mecanismo para confinar dentro de um contêiner o eBPF usado por esse contêiner. bpf_probe_read_kernel() pode, em essência, ler toda a memória do kernel
Portanto, o ponto em que o eBPF é melhor que código C comum de kernel é parecido com escrever código em uma linguagem segura com uma superfície limitada de APIs unsafe. Para esse tipo de trabalho, é uma grande melhoria, mas está longe de ser perfeito
Também se diz que o verificador é rigoroso e que a implementação no Linux tem mais de 20 mil linhas, mas o verificador é absurdamente complexo. Eu preferiria ver uma base em métodos formais em vez de 20 mil linhas de lógica escritas à mão
Fico com dúvidas diante da afirmação de que “programas eBPF passam por uma verificação de segurança feita por um verificador de software e, na prática, rodam em uma sandbox, portanto não podem derrubar o sistema inteiro”
Um dos objetivos do sistema operacional não é monitorar o software? Sei que este é um problema relacionado ao próprio sistema operacional, mas, se adicionarmos uma camada para monitorar o monitor, no fim essa camada também não precisaria ser monitorada de novo?
Em vez de acreditar ingenuamente que a nova complexidade será melhor no longo prazo, não poderíamos optar por reduzir a complexidade?
O jeito antigo era carregar um driver de kernel, colocar hooks em inúmeras chamadas de sistema e rezar para não quebrar nada. Se desse errado, podia causar um panic, embora o Linux seja bastante robusto
A abordagem com eBPF é mais próxima de solicitar as informações desejadas por meio de instruções específicas do eBPF
Há uma visão geral de como funciona aqui: https://ebpf.io/what-is-ebpf/
Parece uma tecnologia interessante, mas o problema realmente grave é a parte de que “também é possível usar métodos de mitigação de risco na implantação de software, como testes canário, rollout gradual e engenharia de resiliência”
Não é preciso uma tecnologia nova para implementar controle de qualidade básico, que é padrão do setor
Para marcar este incidente, talvez dê para começar a folgar às sextas-feiras. É possível que o dano tivesse sido menor se as pessoas trabalhassem com menos pressão e tivessem mais tempo para parar e pensar sobre como as coisas estão se desenrolando e que impacto podem ter nesse fluxo
A explicação de que o verificador da implementação em Linux tem mais de 20 mil linhas e recebeu contribuições da indústria e da academia, na verdade, não me tranquiliza. A superfície de ataque adicional também é um problema, mas quem pode garantir uma base de código tão grande?
Tenho a impressão de que o verificador de WebAssembly é bem mais simples
Se o filtro é carregado na inicialização e coloca hooks em tudo, um único bug pode travar o sistema a ponto de ele não poder ser operado nem corrigido. Por exemplo, se uma lista de permissões vazia for carregada, isso pode acabar transformando um boot loop em outra forma de negação de serviço
Se a Microsoft colocar os elementos essenciais necessários para a recuperação em uma lista de permissões hardcoded, bugs desse tipo de ferramenta poderiam ser corrigidos com mais facilidade, mas, até que a correção fosse distribuída, os sistemas poderiam ficar ligados, porém inutilizáveis, gerando downtime efetivo
O post do blog diz que “eBPF é imune a esse tipo de crash”
Pesquisei, mas não encontrei nada definitivo, e ainda parece que ele pode quebrar algo. Gostaria que um especialista em eBPF explicasse essa afirmação. O melhor material que encontrei foi este: https://stackoverflow.com/questions/70403212/why-is-ebpf-sai...