Recentemente, eu tenho desenterrado informações sobre processos no GNU / Linux e conheci a infame bomba de forquilha:
:(){ : | :& }; :
Teoricamente, é suposto duplicar-se infinitamente até o sistema ficar sem recursos ...
No entanto, tentei testar tanto em uma distro CLI Debian quanto em uma GUI Mint , e isso não parece impactar muito o sistema. Sim, existem muitos processos criados e, depois de um tempo, leio mensagens no console, como:
bash: fork: recurso temporariamente indisponível
bash: fork: nova tentativa: nenhum processo filho
Mas depois de algum tempo, todos os processos acabam sendo mortos e tudo volta ao normal. Eu li que o ulimit define uma quantidade máxima de processo por usuário, mas não consigo elevar isso muito longe.
Quais são as proteções do sistema contra uma bomba bifurcada? Por que ele não se reproduz até que tudo congele ou pelo menos fique muito tempo? Existe uma maneira de realmente travar um sistema com uma bomba de garfo?
:(){ :& :; }; :
? Eles também acabam sendo mortos? Que tal:(){ while :& do :& done; }; :
?Respostas:
Você provavelmente tem uma distribuição Linux que usa systemd.
O Systemd cria um cgroup para cada usuário e todos os processos de um usuário pertencem ao mesmo cgroup.
O Cgroups é um mecanismo do Linux para definir limites de recursos do sistema, como número máximo de processos, ciclos de CPU, uso de RAM, etc. Essa é uma camada diferente e mais moderna de limitação de recursos do que
ulimit
(que usa ogetrlimit()
syscall).Se você executar
systemctl status user-<uid>.slice
(que representa o cgroup do usuário), poderá ver o número atual e máximo de tarefas (processos e encadeamentos) permitidas nesse cgroup.Por padrão, o número máximo de tarefas que o systemd permitirá para cada usuário é 33% do "máximo do sistema" (
sysctl kernel.threads-max
); isso geralmente equivale a ~ 10.000 tarefas. Se você deseja alterar este limite:No systemd v239 e posterior, o padrão do usuário é definido via TasksMax = in:
Para ajustar o limite para um usuário específico (que será aplicado imediatamente e armazenado em /etc/systemd/system.control), execute:
Os mecanismos habituais de substituir as configurações de uma unidade (como
systemctl edit
) também podem ser usados aqui, mas exigirão uma reinicialização. Por exemplo, se você quiser alterar o limite para cada usuário, poderá criar/etc/systemd/system/user-.slice.d/15-limits.conf
.No systemd v238 e versões anteriores, o padrão do usuário é definido via UserTasksMax = in
/etc/systemd/logind.conf
. Alterar o valor geralmente requer uma reinicialização.Mais informações sobre isso:
fonte
Isso não trava mais os modernos sistemas Linux de qualquer maneira.
Ele cria hordas de processos, mas na verdade não queima tanta CPU quanto os processos ficam ociosos. Você fica sem slots na tabela de processos antes de ficar sem RAM agora.
Se você não é um cgroup limitado, como Hkoof aponta, a seguinte alteração ainda reduz os sistemas:
fonte
fork
repetidamente) e o resto do tempo executando a chamada de função (usando incrementalmente mais memória para cada chamada na pilha de chamadas do shell, presumivelmente).:(){ :& :; }; :
vez da que está em questão. Na verdade, ainda não pensei completamente no fluxo de execução do arquetípico, como dado.Nos anos 90, acidentalmente soltei um desses em mim. Eu inadvertidamente defini o bit de execução em um arquivo de origem C que continha um comando fork (). Quando cliquei duas vezes, o csh tentou executá-lo em vez de abri-lo em um editor como eu queria.
Mesmo assim, não travou o sistema. O Unix é robusto o suficiente para que sua conta e / ou o sistema operacional tenha um limite de processo. O que acontece é que fica super lento, e qualquer coisa que precise iniciar um processo provavelmente falhará.
O que está acontecendo nos bastidores é que a tabela de processos se enche de processos que estão tentando criar novos processos. Se um deles terminar (devido a um erro na bifurcação porque a tabela de processos está cheia ou devido a um operador desesperado tentando restaurar a sanidade de seu sistema), um dos outros processos alegremente bifurcará um novo para preencher o vazio.
A "bomba dos garfos" é basicamente um sistema de processos auto-reparado não intencionalmente, em uma missão para manter sua tabela de processos cheia. A única maneira de impedir isso é matá-los todos de uma vez.
fonte
-1
não é uma bandeira.kill
leva apenas uma opção e para de analisar as opções. Isso mata o ID do processo-1
, que é um alias para todos os processos.