web-dev-qa-db-fra.com

Pourquoi ne puis-je pas planter mon système avec une bombe à fourche?

Récemment, j'ai déterré des informations sur les processus dans GNU/Linux et j'ai rencontré l'infâme bombe fork:

:(){ : | :& }; :

Théoriquement, il est supposé se dupliquer à l'infini jusqu'à épuisement des ressources du système ...

Cependant, j'ai essayé de tester à la fois sur une CLI Debian CLI et une GUI Mint distro, et cela ne semble pas avoir beaucoup d'impact sur le système. Oui, il y a des tonnes de processus qui sont créés, et après un certain temps, j'ai lu dans la console des messages comme:

bash: fork: Ressource temporairement indisponible

bash: fork: retry: aucun processus enfant

Mais après un certain temps, tous les processus sont simplement tués et tout redevient normal. J'ai lu que le limit définissait une quantité maximale de processus par utilisateur, mais je n'arrive pas à le faire monter très loin.

Quelles sont les protections du système contre une fourche-bombe? Pourquoi ne se réplique-t-il pas tant que tout ne gèle pas ou du moins tard? Existe-t-il un moyen de vraiment planter un système avec une bombe à fourche?

55
Plancton

Vous avez probablement une distribution Linux qui utilise systemd.

Systemd crée un groupe de contrôle pour chaque utilisateur et tous les processus d'un utilisateur appartiennent au même groupe de contrôle.

Cgroups est un mécanisme Linux pour fixer des limites sur les ressources système comme le nombre maximum de processus, les cycles CPU, RAM utilisation, etc. Ceci est une couche de limitation des ressources différente et plus moderne que ulimit (qui utilise la fonction getrlimit() syscall).

Si vous exécutez systemctl status user-<uid>.slice (qui représente le groupe de contrôle de l'utilisateur), vous pouvez voir le nombre actuel et maximum de tâches (processus et threads) autorisées dans ce groupe de contrôle.

$ systemctl status user- $ UID.slice
 ● user-22001.slice - Tranche utilisateur de l'UID 22001 
 Chargé: chargé 
 Drop-In: /usr/lib/systemd/system/user-.slice.d 
 └─10-defaults.conf 
 Actif: actif depuis lun. 2018-09-10 17:36:35 EEST; Il y a 1 semaines 3 jours 
 Tâches: 17 (limite: 10267)
 Mémoire: 616,7 M 

Par défaut, le nombre maximal de tâches que systemd autorisera pour chaque utilisateur est de 33% du "maximum à l'échelle du système" (sysctl kernel.threads-max); cela équivaut généralement à environ 10 000 tâches. Si vous souhaitez modifier cette limite:

  • Dans systemd v239 et versions ultérieures, la valeur par défaut de l'utilisateur est définie via TasksMax = dans:

    /usr/lib/systemd/system/user-.slice.d/10-defaults.conf
    

    Pour ajuster la limite pour un utilisateur spécifique (qui sera appliquée immédiatement ainsi que stockée dans /etc/systemd/system.control), exécutez:

    systemctl [--runtime] set-property user-<uid>.slice TasksMax=<value>
    

    Les mécanismes habituels de substitution des paramètres d'une unité (tels que systemctl edit) peut également être utilisé ici, mais il faudra un redémarrage. Par exemple, si vous souhaitez modifier la limite pour chaque utilisateur, vous pouvez créer /etc/systemd/system/user-.slice.d/15-limits.conf.

  • Dans systemd v238 et versions antérieures, la valeur par défaut de l'utilisateur est définie via UserTasksMax = dans /etc/systemd/logind.conf. La modification de la valeur nécessite généralement un redémarrage.

Plus d'informations à ce sujet:

85
Hkoof

De toute façon, cela ne fera plus planter les systèmes Linux modernes.

Il crée des hordes de processus mais ne brûle pas vraiment autant de CPU que les processus deviennent inactifs. Vous manquez d'emplacements dans la table de processus avant de manquer de RAM now.

Si vous n'êtes pas limité au groupe de contrôle, comme le souligne Hkoof, la modification suivante réduit toujours les systèmes:

:(){ : | :& : | :& }; :
13
Joshua

Dans les années 90, j'ai déclenché accidentellement l'un d'eux sur moi. J'avais mis par inadvertance le bit d'exécution sur un fichier source C qui avait une commande fork (). Lorsque j'ai double-cliqué dessus, csh a essayé de l'exécuter plutôt que de l'ouvrir dans un éditeur comme je le voulais.

Même alors, cela n'a pas fait planter le système. Unix est suffisamment robuste pour que votre compte et/ou le système d'exploitation aient une limite de processus. Ce qui se passe à la place, c'est que cela devient super lent, et tout ce qui doit démarrer un processus est susceptible d'échouer.

Ce qui se passe dans les coulisses, c'est que la table des processus se remplit de processus qui tentent de créer de nouveaux processus. Si l'un d'entre eux se termine (soit en raison d'une erreur sur le fork parce que la table de processus est pleine, soit en raison d'un opérateur désespéré essayant de restaurer la santé mentale de leur système), l'un des autres processus va joyeusement en fork un nouveau à remplir le vide.

La "bombe à fourche" est fondamentalement un système de processus auto-réparateur involontaire qui a pour mission de garder votre table de processus pleine. La seule façon de l'arrêter est de les tuer d'une manière ou d'une autre.

9
T.E.D.