Bombă cu furcă

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită la 31 august 2021; verificările necesită 2 modificări .

O bombă fork  este un program rău intenționat sau scris eronat care creează la nesfârșit copii ale lui însuși (folosind apelul de sistem fork() ), care de obicei începe să creeze copii ale lui, etc.

Executarea unui astfel de program poate provoca o sarcină mare asupra sistemului de calcul sau chiar o refuz de serviciu din cauza lipsei resurselor sistemului (manere de proces, memorie, timp procesor), care este scopul.

Programul clasic cu bombă cu furcă (scris în C ) arată astfel:

#include <unistd.h> int main () { în timp ce ( 1 ) furca (); }

Cazuri similare de scurgeri de resurse ale sistemului sunt programele care generează zombi și procese orfane . Cu toate acestea, dacă majoritatea bombelor cu furcă sunt create intenționat, atunci aceste probleme sunt de obicei rezultatul neglijenței sau incompetenței programatorului.

Descriere

Bomba furcă generează un număr mare de copii ale ei însăși și, prin urmare, încearcă să umple spațiul liber din lista proceselor active ale sistemului de operare . După completarea listei de procese, devine imposibil să porniți un program util. Chiar dacă un alt proces se termină și spațiul din lista de procese devine liber, este puțin probabil ca un program util să înceapă, deoarece multe alte copii ale bombei furcă așteaptă deja oportunitatea de a începe următoarea copie.

Pe lângă popularea listei de procese, sunt posibile și strategii de populare a memoriei virtuale, a timpului CPU, a socket-urilor și a altor resurse de sistem. Rezultatul epuizării acestor resurse este încetinirea sau oprirea practic a sistemului de operare și/sau a programelor utile ( calculatorul se blochează ).

O bombă cu furcă poate fi obținută și ca urmare a unei erori de programare conștiincioasă. De exemplu, un program care ascultă pe un port de rețea poate, la primirea unui pachet de rețea sau la stabilirea unei conexiuni, „cădea” într-o buclă nesfârșită de a crea copii ale lui însuși pentru a procesa pachetul sau conexiunea. O simplă eroare de programare poate duce la o scurgere de memorie sau la consecințele unei bombe cu furcă.

Exemple de bombe cu furcă în diferite limbaje de programare

C : [1]

#include <stdlib.h> int main ( void ) { pentru (;;) { sistem ( „pornire” ); } }

sau:

#include <unistd.h> int main ( void ) { în timp ce ( furcă ()) {}; }

Lovitură : [2]

 : (){  : | : & } ; :

sau

furculiță () { furculiță | furculiță și } furculiţă

Java :

public class forkbomb { public static void main ( String [] args ) { Runtime . getRuntime (). exec ( String nou [] { "javaw" , "-cp " , System . getProperty ( "java.class.path" ), "forkbomb" }); } }

Perl :

furcă în timp ce furcă

Python :

import os în timp ce Adevărat : os . furca ()

În unele sisteme, un astfel de apel este interzis, copierea este posibilă numai dacă ID-ul procesului este salvat:

import os în timp ce Adevărat : a = os . furca ()

rubin :

furcă în timp ce furcă

A doua varianta:

buclă { furculiță }

PHP :

<?php while ( true ) { pcntl_fork (); }

Fișier batch Microsoft Windows :

: s start %0 goto : s

A doua varianta

începe %0 %0

Varianta pe VB.NET

DoSystem . _ diagnosticare . proces . Start ( Sistem . Reflecție . Asamblare . GetExecutingAssembly ( ). Locație ) Loop While True

Pseudocod :

alg ProgramX în timp ce true nc apel ProgramX cc con alg ProgramX

Dificultatea eliminării

În cazul unei bombe cu furcă de succes, devine dificil sau aproape imposibil să restabiliți funcționarea normală a computerului fără repornire , deoarece singura modalitate de a opri funcționarea bombei cu furcă este oprirea simultană a tuturor copiilor care rulează ale bombei cu furcă. În majoritatea implementărilor de sisteme de operare, apelarea unei comenzi pentru a ucide un proces necesită pornirea unui nou proces, ceea ce nu este posibil în condițiile unei bombe cu furcă care rulează cu succes.

Cu toate acestea, în practică, unele bombe cu furcă nu necesită măsuri atât de drastice și pot fi distruse fără a fi nevoie de o repornire. Luați în considerare, de exemplu, cazul bombei din exemplul de mai sus:

 : (){  : | : & } ; :

Particularitatea acestui cod este că nu se execută în buclă după generarea nereușită a copiilor sale, ci iese. Ca urmare, lista de procese este în mod constant pe punctul de a se umple: una dintre copiile bombei cu furcă este terminată, iar spațiul eliberat este imediat ocupat de un proces nou creat dintr-o altă copie a bombei cu furcă. Devine posibil să concurezi cu bomba cu furcă pentru spațiu în lista de procese. Apoi, mai devreme sau mai târziu, este posibil să rulați o comandă pentru a ucide toate copiile bombei cu furcă în același timp sau să rulați un program sigur care va „recupera” treptat un loc în lista de procese până la ultimul proces al furcii. bomba se termină. Un exemplu de astfel de program securizat în zsh :

in timp ce ( dormi 100 & ! ) do ; Terminat

Prevenirea

O modalitate de a preveni efectele negative ale unei bombe cu furcă este de a limita cu forță numărul de procese pe care un utilizator le poate rula în același timp. Cantitatea de memorie virtuală alocată și alte resurse de sistem poate fi, de asemenea, limitată. Când numărul maxim de procese disponibile este epuizat, încercarea procesului de a crea un nou proces va eșua. Numărul maxim de procese care pot fi pornite ar trebui să fie astfel încât să vă permită să rulați un număr rezonabil de programe, dar să nu conducă la o prăbușire a sistemului atunci când o bombă furcă este lansată de la toți utilizatorii sistemului în același timp.

Trebuie remarcat faptul că limitarea numărului de procese în sine nu împiedică lansarea unei bombe cu furcă, ci are drept scop doar minimizarea posibilelor daune dacă aceasta este declanșată.

O altă soluție la problemă este recunoașterea inteligentă a bombei cu furcă prin intermediul sistemului de operare în sine, dar această soluție nu și-a găsit aplicație largă.

Există, de asemenea, o astfel de dificultate încât, dacă o bombă cu furcă ia tot timpul disponibil al procesorului, atunci rezultatele muncii sale pot fi catastrofale nu numai pe un singur procesor, ci și pe un sistem multiprocesor, chiar și cu o limită a numărului de procese. . De exemplu, dacă numărul de procesoare este de 16, iar numărul maxim de procese care rulează este de 100, atunci pentru fiecare procesor vor exista o medie de 6-7 instanțe de rulare ale bombei cu furcă, devorând timpul procesorului. Pentru a rezolva această problemă, se aplică o limită de afinitate a procesorului.

Vezi și

Note

  1. unul dintre cele mai elegante exemple de bombă cu furcă, de Markys'om
  2. unul dintre cele mai elegante exemple de bombă cu furcă, de Jaromil