Probabilmente hai una distribuzione Linux che usa systemd.
Systemd crea un cgroup per ogni utente e tutti i processi di un utente appartengono allo stesso cgroup.
Cgroups è un meccanismo Linux per impostare limiti sulle risorse di sistema come il numero massimo di processi, cicli della CPU, utilizzo della RAM, ecc. Questo è un livello di limitazione delle risorse diverso e più moderno rispetto a ulimit
(che usa il getrlimit()
chiamata di sistema).
Se esegui systemctl status user-<uid>.slice
(che rappresenta il cgroup dell'utente), puoi vedere il numero corrente e massimo di task (processi e thread) consentito all'interno di quel cgroup.
$ systemctl status user-$UID.slice ● user-22001.slice - User Slice of UID 22001 Loaded: loaded Drop-In: /usr/lib/systemd/system/user-.slice.d └─10-defaults.conf Active: active since Mon 2018-09-10 17:36:35 EEST; 1 weeks 3 days ago Tasks: 17 (limit: 10267) Memory: 616.7M
Per impostazione predefinita, il numero massimo di attività consentite da systemd per ciascun utente è il 33% del "massimo a livello di sistema" (sysctl kernel.threads-max
); questo di solito equivale a ~ 10.000 attività. Se desideri modificare questo limite:
-
In systemd v239 e versioni successive, l'utente predefinito è impostato tramite TasksMax= in:
/usr/lib/systemd/system/user-.slice.d/10-defaults.conf
Per regolare il limite per un utente specifico (che verrà applicato immediatamente e memorizzato in /etc/systemd/system.control), eseguire:
systemctl [--runtime] set-property user-<uid>.slice TasksMax=<value>
I soliti meccanismi di sovrascrittura delle impostazioni di un'unità (come
systemctl edit
) possono essere utilizzati anche qui, ma richiederanno un riavvio. Ad esempio, se desideri modificare il limite per ogni utente, potresti creare/etc/systemd/system/user-.slice.d/15-limits.conf
. -
In systemd v238 e versioni precedenti, l'utente predefinito è impostato tramite UserTasksMax= in
/etc/systemd/logind.conf
. La modifica del valore generalmente richiede un riavvio.
Maggiori informazioni su questo:
- man 5 systemd.resource-control
- man 5 systemd.slice
- man 5 logind.conf
- http://0pointer.de/blog/projects/systemd.html (cerca cgroup in questa pagina)
- man 7 cgroups e https://www.kernel.org/doc/Documentation/cgroup-v1/pids.txt
- https://en.wikipedia.org/wiki/Cgroups
In ogni caso, questo non causerà più il crash dei moderni sistemi Linux.
Crea orde di processi ma in realtà non brucia tutta la CPU poiché i processi diventano inattivi. Finisci gli slot nella tabella dei processi prima di esaurire la RAM ora.
Se non sei limitato da cgroup come sottolinea Hkoof, la seguente modifica fa comunque crollare i sistemi:
:(){ : | :& : | :& }; :
Negli anni '90 ho accidentalmente scatenato uno di questi su me stesso. Avevo inavvertitamente impostato il bit di esecuzione su un file sorgente C che conteneva un comando fork(). Quando ho fatto doppio clic su di esso, csh ha provato a eseguirlo invece di aprirlo in un editor come volevo.
Anche allora, non ha bloccato il sistema. Unix è abbastanza robusto che il tuo account e/o il sistema operativo avranno un limite di processo. Quello che succede invece è che diventa super lento e tutto ciò che deve avviare un processo rischia di fallire.
Quello che sta accadendo dietro le quinte è che la tabella dei processi si riempie di processi che cercano di creare nuovi processi. Se uno di essi termina (sia a causa di un errore sul fork perché la tabella dei processi è piena, sia a causa di un operatore disperato che cerca di ripristinare la sanità mentale del proprio sistema), uno degli altri processi eseguirà allegramente il fork di uno nuovo da riempire il vuoto.
La "fork bomb" è fondamentalmente un sistema di processi che si autoripara involontariamente in una missione per mantenere piena la tabella dei processi. L'unico modo per fermarlo è in qualche modo ucciderli tutti in una volta.