Jak działa bomba widełkowa?


22
  • OSTRZEŻENIE NIE PRÓBUJ URUCHOMIĆ TEGO NA MASZYNIE PRODUKCYJNEJ

Czytając stronę Wikipedii na ten temat , ogólnie śledzę, co się dzieje z następującym kodem:

:(){ :|:& };:

fragment opisu

Następująca bomba widelca została zaprezentowana jako sztuka w 2002 roku;56 jego dokładne pochodzenie nie jest znane, ale istniało na Usenecie przed 2002 rokiem. Bomba jest wykonywana przez wklejenie następujących 13 znaków w powłoce UNIX, takiej jak bash lub zsh . Działa poprzez zdefiniowanie funkcji o nazwie „:”, która wywołuje się dwukrotnie, raz na pierwszym planie i raz w tle.

Jednak ostatni fragment nie jest dla mnie całkowicie jasny. Widzę definicję funkcji:

:(){ ... }

Ale co jeszcze się dzieje? Czy inne powłoki, takie jak ksh, cshi tcshcierpią z powodu tego samego losu, że są w stanie zbudować coś podobnego?


2
Ten pojawia się dość często przy wymianie stosu, dobra odpowiedź jest tutaj: stackoverflow.com/questions/991142/…
Drav Sloan

@DravSloan - Próbowałem tutaj stworzyć część tej treści, moje pytanie jest trochę w ten sposób załadowane 8-).
slm

Możesz dodać obowiązkowe „Na miłość boską nie uruchamiaj tego na maszynie produkcyjnej, lub jeśli chcesz dalej używać maszyny, uruchom ją !!” wiadomość :)
Drav Sloan

1
@ MartinSchröder - rozumiesz, że to pytanie doprowadziło do pytania? 8-). Poprosiłem o to w piątek wieczorem, żeby coś się zaczęło, a potem kolejne pytanie nadeszło za godzinę lub dwie później.
slm

1
@ MartinSchröder - prawdopodobnie najlepiej zostawić je osobno, są nieco inne. Jest to prośba o pełny szczegółowy widok działania bomby widelcowej, ta druga poprosiła o szczegółowe informacje na temat mechanizmu kryjącego się za tym, jak układ rozwidla się w bomby widelcowej. Wiem, że to może wydawać się mylące, ponieważ są ze sobą powiązane, ale są różne (IMO - oczywiście). Odpowiedziałem nawet na inne pytanie i próbowałem pokazać mechanizm pod maską, który napędza rozwidlenie, i nie oznaczyłem go jako duplikat.
slm

Odpowiedzi:


23

Ta bomba rozwidlona zawsze przypomina mi coś, co powiedział nauczyciel programowania AI na jednej z pierwszych lekcji, w których uczestniczyłem: „Aby zrozumieć rekurencję, najpierw musisz zrozumieć rekurencję”.

U podstaw tej bomby jest funkcja rekurencyjna . Zasadniczo tworzysz funkcję, która wywołuje siebie, która wywołuje siebie, która wywołuje siebie .... aż do wyczerpania zasobów systemowych. W tym konkretnym przypadku rekurencja jest wzmacniana przez użycie potokowania funkcji do siebie ORAZ jej tła.

Widziałem tę odpowiedź na StackOverflow i myślę, że podany tam przykład najlepiej to ilustruje, tylko dlatego, że łatwiej jest zobaczyć, co robi na pierwszy rzut oka (skradziony z linku powyżej ...)

☃(){ ☃|☃& };☃

Zdefiniuj funkcję błędu ☃() { ... }, której ciało wywołuje się (funkcja błędu), przesyłając dane wyjściowe do siebie (funkcja błędu) ☃|☃, i określ wynik w tle &. Następnie, po funkcja jest zdefiniowana, rzeczywiście wywołać funkcję błędu, ; ☃.

Zauważam, że przynajmniej na mojej Arch VM, potrzeba podłożenia procesu do tła nie jest wymagana do uzyskania tego samego rezultatu końcowego, do zużycia całej dostępnej przestrzeni procesu i renderowania hosta. Właściwie teraz powiedziałem, że wydaje się, że czasami kończy proces ucieczki i po jego przeskanowaniu -bash: fork: Resource temporarily unavailablezakończy się na Terminated(i journalctlpokazuje zrzut rdzenia bash).

Aby odpowiedzieć na twoje pytanie dotyczące csh / tcsh, żadna z tych powłok nie obsługuje funkcji, możesz tylko alias. W przypadku tych powłok należy napisać skrypt powłoki, który wywołuje się rekurencyjnie.

Wygląda na to, że zsh cierpi z powodu tego samego losu (z tym samym kodem), nie zrzuca zrzutu pamięci i powoduje, że Arch daje Out of memory: Kill process 216 (zsh) score 0 or sacrifice child., ale nadal się rozwija. Po chwili stwierdza Killed process 162 (systemd-logind) ...(i nadal ma rozwidlenie zsh).

Arch nie wydaje się mieć pacmanwersji ksh, więc zamiast tego musiałem wypróbować ją na Debianie. ksh sprzeciwia się :jako nazwa funkcji, ale używając czegoś - powiedzmy, że b()wydaje się mieć pożądany wynik.


Jakie są te postacie? Wiem, że to robaki, ale jak je stworzyłeś?
slm

10
Chociaż przy małym rozmiarze czcionki wygląda jak błąd, przekonasz się, że w rzeczywistości jest to bałwan. Byłby to znak Unicode U + 2603, który można wyświetlić w html, wpisując & # x 2603 bez spacji.
sambler

2
Podobno pod Linuksem sporo aplikacji związanych z Gnome i Firefox obsługuje, Ctrl+Shift+u+<hex>gdzie hex to kod szesnastkowy znaku Unicode, który chcesz wyświetlić. Listę widocznych kodów Unicode można znaleźć na stronie: fileformat.info/info/unicode/utf8test.htm (większość nieparzystych znajduje się w sekcji „Różne”). System Windows powinien pobrać kasę superuser.com/questions/47420/... , a ja osobiście korzystam z narzędzia wymienionego w łączu unicodeinput.exelub wycinam i wklejam za pomocą przeglądarki. Zawsze możesz użyć sekwencji HTML zgodnie z sugestią samblera.
Drav Sloan

1
Wiki ma również listę znaków Unicode: en.wikipedia.org/wiki/List_of_Unicode_characters
Drav Sloan

Podobał mi się błąd bałwana, ten, którego tu używasz, nie jest wyświetlany w moim systemie, 🐛 wygląda jak pole z liczbami szesnastkowymi.
terdon
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.