Recentemente eu estive desenterrando informações sobre processos no GNU/Linux e encontrei a infame bomba fork :
:(){ : | :& }; :
Teoricamente, ele deve se duplicar infinitamente até que o sistema fique sem recursos...
No entanto, eu tentei testar tanto em uma distro CLI Debian quanto em uma GUI Mint , e isso não parece afetar muito o sistema. Sim, existem muitos processos criados e, depois de um tempo, li mensagens do console como:
bash: fork: recurso temporariamente indisponível
bash: fork: retry: nenhum processo filho
Mas depois de algum tempo, todos os processos são mortos e tudo volta ao normal. Eu li que o ulimit definiu uma quantidade máxima de processo por usuário, mas não consigo aumentá-lo muito longe.
Quais são as proteções do sistema contra uma fork-bomb? Por que não se replica até que tudo congele ou pelo menos fique muito atrasado? Existe uma maneira de realmente travar um sistema com uma bomba de garfo?
Você provavelmente tem uma distribuição Linux que usa systemd.
Systemd cria um cgroup para cada usuário, e todos os processos de um usuário pertencem ao mesmo cgroup.
Cgroups é um mecanismo Linux para definir limites em recursos do sistema como número máximo de processos, ciclos de CPU, uso de RAM, etc. Esta é uma camada diferente, mais moderna, de limitação de recursos
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 threads) permitidos nesse cgroup.Por padrão, o número máximo de tarefas que o systemd permitirá para cada usuário é 33% do "máximo de todo o sistema" (
sysctl kernel.threads-max
); isso geralmente equivale a ~10.000 tarefas. Se você quiser alterar esse limite:No systemd v239 e posterior, o padrão do usuário é definido por meio de TasksMax= em:
Para ajustar o limite para um usuário específico (que será aplicado imediatamente e armazenado em /etc/systemd/system.control), execute:
Os mecanismos usuais 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 anterior, o padrão do usuário é definido por meio de UserTasksMax= em
/etc/systemd/logind.conf
. Alterar o valor geralmente requer uma reinicialização.Mais informações sobre isso:
Isso não travará mais os sistemas Linux modernos de qualquer maneira.
Ele cria hordas de processos, mas não queima toda a CPU, pois os processos ficam ociosos. Você fica sem slots na tabela de processos antes de ficar sem RAM agora.
Se você não estiver limitado ao cgroup, como aponta Hkoof, a seguinte alteração ainda derruba os sistemas:
Nos anos 90, acidentalmente soltei um desses em mim. Eu inadvertidamente defini o bit de execução em um arquivo de origem C que tinha um comando fork() nele. Quando cliquei duas vezes nele, 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 tenham 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 for encerrado (por causa de um erro na bifurcação porque a tabela de processos está cheia ou devido a um operador desesperado tentando restaurar a sanidade do sistema), um dos outros processos alegremente bifurcará um novo para preencher o vazio.
A "bomba fork" é basicamente um sistema de processos de auto-reparação involuntária em uma missão para manter sua tabela de processos cheia. A única maneira de pará-lo é de alguma forma matá-los todos de uma vez.