Ostrzeżenie: Uruchomienie tego polecenia w większości powłok spowoduje uszkodzenie systemu, który będzie wymagał wymuszonego zamknięcia w celu naprawy
Rozumiem funkcję rekurencyjną :(){ :|: & };:
i jej działanie. Ale nie wiem, gdzie jest wywołanie systemowe wideł. Nie jestem pewien, ale podejrzewam w fajce |
.
linux
shell
system-calls
mavillan
źródło
źródło
Odpowiedzi:
W wyniku wprowadzenia potoku
x | y
tworzona jest podpowłoka zawierająca potok jako część grupy procesów pierwszego planu. Tworzy to podpowłoki (viafork()
) w nieskończoność, tworząc w ten sposób bombę widełkową.Jednak rozwidlenie nie występuje, dopóki kod nie zostanie uruchomiony, co jest ostatecznym wywołaniem
:
w kodzie.Aby zdemontować działanie bomby widelcowej:
:()
- zdefiniuj nową funkcję o nazwie:
{ :|: & }
- definicja funkcji, która rekurencyjnie przesyła funkcję wywołującą do innej instancji funkcji wywołującej w tle:
- wywołać funkcję bomby widełkowejZwykle nie wymaga to zbyt dużej pamięci, ale wysysa PID i zużywa cykle procesora.
źródło
x | y
, dlaczego jest tam sub-shell stworzył? Dla mojego zrozumienia, gdy bash widzi apipe
, wykonujepipe()
wywołanie systemowe, które zwraca dwafds
. Teraz komenda_lewa jest edytowana,exec
a dane wyjściowe są podawane do komendy_prawo jako dane wejściowe. Teraz Command_right jest edytowanyexec
. Dlaczego zaBASHPID
każdym razem jest inaczej?x
iy
są 2 osobne komendy działające w 2 osobnych procesach, więc masz 2 osobne podpowłoki. Jeślix
działa w tym samym procesie co powłoka, oznacza to, żex
musi być wbudowany.Ostatni bit kodu
;:
uruchamia funkcję:(){ ... }
. W tym miejscu występuje widelec.Średnik kończy pierwsze polecenie, a my rozpoczynamy kolejne, tzn. Wywołujemy funkcję
:
. Definicja tej funkcji obejmuje wywołanie do siebie (:
), a wynik tego wywołania jest przesyłany do wersji w tle:
. To wspiera proces na czas nieokreślony.Za każdym razem, gdy wywołanie funkcji
:()
jesteś wywołanie funkcji Cfork()
. Ostatecznie spowoduje to wyczerpanie wszystkich identyfikatorów procesów (PID) w systemie.Przykład
Możesz zamienić się
|:&
czymś innym, aby dowiedzieć się, co się dzieje.Skonfiguruj obserwatora
Zrób to w jednym oknie terminala:
Ustaw bombę wideł „z opóźnieniem bezpiecznika”
W innym oknie uruchomimy nieco zmodyfikowaną wersję widełkowej bomby. Ta wersja spróbuje się dusić, abyśmy mogli przestudiować, co robi. Nasza wersja będzie spała przez 61 sekund przed wywołaniem funkcji
:()
.Będziemy również tworzyć tło pierwszego połączenia, po jego wywołaniu. Ctrl+ z, a następnie wpisz
bg
.Teraz, jeśli uruchomimy
jobs
polecenie w oknie początkowym, zobaczymy:Po kilku minutach:
Zamelduj się u obserwatora
Tymczasem w drugim oknie, w którym działamy
watch
:Hierarchia procesów
A
ps -auxf
pokazuje hierarchię procesów:Czas na sprzątanie
A
killall bash
zatrzyma rzeczy, zanim wymkną się spod kontroli. Czyszczenie w ten sposób może być trochę ciężkie, łagodniejszy i łagodniejszy sposób, który potencjalnie nie rozbije wszystkichbash
pocisków, to:Określ, w jakim pseudo terminalu ma trafić widelec bomba
Zabij pseudo terminal
Więc co się dzieje?
Cóż, każde wywołanie
bash
isleep
jest wywołaniem funkcji Cfork()
zbash
powłoki, z której uruchomiono polecenie.źródło
bash
może działać na osobnych terminalach. Lepiej byłoby użyćpkill -t pts/2
.