Xz: o único caractere que desativou o Landlock no Linux
(git.tukaani.org)- A mudança em CMakeLists.txt no xz.git, ao trocar a detecção do sandbox Landlock de uma verificação da presença do cabeçalho para um teste de compilação real, introduziu um caso em que um caractere
.isolado apareceu dentro do código de teste - A nova verificação foi adicionada para filtrar sistemas que têm
linux/landlock.h, mas podem não ter as definições de syscall necessárias - O teste de compilação inclui
<linux/landlock.h>,<sys/syscall.h>e<sys/prctl.h>, e referenciaprctl,SYS_landlock_create_ruleset,SYS_landlock_restrict_selfeLANDLOCK_CREATE_RULESET_VERSION - O critério anterior,
HAVE_LINUX_LANDLOCK_H, foi alterado para HAVE_LINUX_LANDLOCK, e as configurações deSANDBOX_COMPILE_DEFINITIONeSANDBOX_FOUNDtambém passam a seguir esse resultado - O commit corrige o teste de recurso do Linux Landlock nas builds com Autotools e CMake, e o diff fornecido mostra a mudança no lado do CMake
Mudança no método de detecção do Landlock no CMake
- O arquivo afetado é o CMakeLists.txt do xz.git, e o ponto alterado é o bloco
# Sandboxing: Landlock - A lógica anterior do CMake, quando
ENABLE_SANDBOXeraONoulandlockeSANDBOX_FOUNDnão estava definido, verificava apenas a existência do cabeçalho comcheck_include_file(linux/landlock.h HAVE_LINUX_LANDLOCK_H) - Depois da mudança,
check_c_source_compilespassou a compilar de fato um pequeno código C para verificar a disponibilidade do Landlock- Alguns sistemas podem ter
linux/landlock.he ainda assim não possuir as definições de syscall necessárias para o Linux Landlock - O código de teste inclui
<linux/landlock.h>,<sys/syscall.h>e<sys/prctl.h> - Dentro de
my_sandbox(), ele referenciaprctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0),SYS_landlock_create_ruleset,SYS_landlock_restrict_selfeLANDLOCK_CREATE_RULESET_VERSION
- Alguns sistemas podem ter
Caractere isolado e mudança de nome de variável
- Após o bloco de includes do código de teste de compilação inserido, há uma linha com um
.isolado - A variável de resultado foi alterada de
HAVE_LINUX_LANDLOCK_Hpara HAVE_LINUX_LANDLOCK - A condição também mudou de
if(HAVE_LINUX_LANDLOCK_H)paraif(HAVE_LINUX_LANDLOCK) - O valor de
SANDBOX_COMPILE_DEFINITIONusa"HAVE_LINUX_LANDLOCK"em vez de"HAVE_LINUX_LANDLOCK_H" - A configuração posterior de
SANDBOX_FOUND ONfoi mantida
1 comentários
Opiniões no Hacker News
Resposta: https://git.tukaani.org/?p=xz.git;a=commitdiff;h=f9cf4c05edd...
Se você não conhece bem o sistema de controle de acesso Landlock do Linux, há uma explicação aqui: https://docs.kernel.org/userspace-api/landlock.html
Página oficial (provavelmente...) de resposta ao incidente do xz: https://tukaani.org/xz-backdoor/
Mas por causa de um pequeno ponto final difícil de notar, colado perto da margem esquerda do diff, o código C ficava sempre inválido, e por isso o Landlock ficava sempre desativado?
Impressionante de tão canalha, e canalha de tão impressionante. Eu também não vi na primeira leitura
Se fosse para esconder, há maneiras melhores de trocar por caracteres Unicode parecidos. Alguns parecem idênticos até no nível de pixels, dependendo da fonte
Posso ter perdido o fio da meada, mas a intenção deliberada foi comprovada aqui?
Eu estava passando os olhos com cuidado e vi um ponto final em um lugar onde claramente não deveria estar, então pensei: “não é tão difícil quanto parecia”
Toquei de leve na tela e o ponto se mexeu
Maldita poeira no monitor
É inacreditável que a segurança do sistema dependa de uma cadeia de correção tão frouxa. Havia inúmeros pontos em que isso poderia ter sido barrado
+ # A compile check is done here because some systems have+ # linux/landlock.h, but do not have the syscalls defined+ # in order to actually use Linux Landlock.O header desses sistemas deveria ser corrigido para excluí-los explicitamente. Qual é o sentido de um header se ele não declara sua própria funcionalidade?
E também não entendo por que, depois que um blob binário é criado (mesmo que compilado a partir de código aberto), não há nenhum teste para verificar se a segurança está intacta
Você provavelmente não colocaria no ar a função de pagamento de um site sem testes de ponta a ponta para a funcionalidade principal. Parece haver um desalinhamento de prioridades em que adicionar recursos fica acima da confiabilidade
Espero que a correção não seja simplesmente remover o
.. Acabei de ver outro post no HN mostrando a remoção do.Corrigir o header ou adicionar testes não teria impedido isso. Para começo de conversa, não havia sinal de que o header estivesse quebrado, e testes adicionais também poderiam ter sido comprometidos de outra forma ou ignorados no tarball de release
[1] https://git.tukaani.org/?p=xz.git;a=commit;h=328c52da8a2bbb8...
Como o usuário poderia tentar compilar com o GCC 9.4.0, e a funcionalidade que dependia daquele header não era essencial para a aplicação, quando o build detectava que o header estava quebrado, simplesmente desativava aquele recurso e emitia um aviso
Voltando ao xz, se segurança não for a prioridade máxima, ignorar a falha de um recurso opcional e seguir em frente também parece razoável. Claro que, em retrospecto, é fácil apontar o dedo, mas sem esse contexto não é uma decisão totalmente absurda
Nossa, o último commit dele está piorando o relato de segurança: https://git.tukaani.org/?p=xz.git;a=commitdiff;h=af071ef7702...
Landlock deveria ser usado onde/como?
Acho que, na prática, seria difícil usar em bibliotecas genéricas, como as de compressão/descompressão. A biblioteca não tem como saber o que o programa deve fazer nem o que deve restringir
Em um programa, isso pode ser mais claro
O ataque ao sshd usou a liblzma como biblioteca. Então desativar o Landlock parece irrelevante, não? Será que é sinal de que há mais código malicioso ainda não descoberto, ou de que planejavam inseri-lo depois?
Ao remover o Landlock, o daemon não se trava, então fica mais fácil executar o payload quando a exploração chega a essa etapa
Não vejo as duas coisas como não relacionadas. Acho que eles já tinham o payload em mente e perceberam que isso seria um obstáculo
Este caso é muito confuso. Algumas partes são sofisticadas a ponto de serem difíceis de acreditar, enquanto outras parecem bastante descuidadas
A ideia é que a biblioteca inicie uma tarefa complexa em uma thread separada, e que o código do usuário aguarde essa thread dentro da API chamada. A thread aplica Landlock a si mesma e então começa o trabalho. Se algo der errado, o código fica isolado
Claro que, neste caso, a sandbox é controlada pelo invasor, então isso não funciona. O invasor pode simplesmente desativá-la ou torná-la mais fraca do que o original. Ainda assim, dá para fazer de outras formas
O que exatamente eles estavam tentando fazer aqui? Inserir mais backdoors depois, backdoors com negação mais plausível? Na minha visão, nem o oss-fuzz nem essa alteração teriam realmente encontrado o backdoor descoberto
Mas por que colocar todos os ovos de backdoor em uma cesta só, isto é, em uma única biblioteca?
Além disso, não se trata de colocar um backdoor na própria biblioteca, mas de mirar as ferramentas que a usam. É no estilo “Reflections on trusting trust”
Até falhar, soa como um plano perfeito
Fico curioso sobre por que seria útil impedir que o Landlock fosse ativado no xz. Será que pretendiam injetar conteúdo malicioso em arquivos xz numa etapa posterior? Se fosse isso, por que não simplesmente colocar comportamento malicioso no próprio xz?
Talvez seja possível inserir às escondidas um buffer overflow ou uso após liberação em um projeto C mantido por você sem ser pego. Distribuir um cavalo de Troia de verdade é muito mais difícil, e isso ficou claro no backdoor xz-para-sshd
Isso é surpreendentemente chamativo. A técnica de desativar o recurso é inteligente e o commit é bem plausível. Mas por que escolher um erro de sintaxe óbvio em vez de simplesmente errar a grafia? Por exemplo, será que teríamos percebido se o erro fosse
PR_SET_NO_NEW_PRIV?Isso também teria mais plausibilidade de negação
Separadamente, essa equipe de malware criou um ótimo dataset para treinar IA a identificar problemas de segurança. Como todo commit tem um problema de segurança, e a comunidade open source vai examiná-los um a um até encontrá-los
Agradeço aos mantenedores que estão fazendo a limpeza. Certamente não é uma tarefa divertida
Por isso eu realmente não gosto de sistemas de build no estilo configure que ativam e desativam recursos automaticamente. Se quero algo, prefiro ativá-lo explicitamente. Se houver um bom motivo para deixar um recurso como padrão, então deveria ser possível desativá-lo explicitamente em vez disso
Bastaria ter um conjunto de recursos padrão e permitir
--enable-a --disable-bconforme necessárioEngolir silenciosamente bugs no processo de verificação é outro problema