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?

slm
źródło
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.

Drav Sloan
źródło
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