Nowe posty

Autor Wątek: Uniemożliwienie wykonania fork‐bomby  (Przeczytany 1346 razy)

Offline overcq

  • Nowy na forum
  • *
  • Wiadomości: 34
    • Zobacz profil
    • ‛overcq’
Uniemożliwienie wykonania fork‐bomby
« dnia: 2023-04-10, 16:47:16 »
Niedawno testowałem napisany program, który wywołuje “fork”, i z jakiegoś powodu powstała fork-bomba. Chciałbym to zdiagnozować, ale po uruchomieniu programu systemu nie da się uratować.
Jeśli nawet ustawię wcześniej
ulimit -Su 100
, to po uruchomieniu programu nie można go zastopować, np. poleceniami
pkill -9 -x nazwa
(takie polecenie zawiesza się i nic nie robi skutecznego).
Natomiast “ulimit” raczej nie jest wystarczający, gdy uruchamia się skrypt, np. poleceniem “make”, ponieważ tam potrzeba wywołać więcej procesów; stąd mój limit 100, a nie na przykład 30.
Zastanawiam się, czy jest jakaś metoda powstrzymania fork‐bomby, gdy zostanie wykonana, bez konieczności restartu systemu. Takie rozwiązanie musiałoby chyba się opierać na czasie użycia procesora przez grupę procesów.

Offline 1709

  • Users
  • Guru
  • *****
  • Wiadomości: 2769
  • 1709
    • Zobacz profil
Odp: Uniemożliwienie wykonania fork‐bomby
« Odpowiedź #1 dnia: 2023-04-10, 22:19:17 »
1. Diagnozujesz np.
- Graficznie z " monitoru systemu "
Jeśli zużycie pamięci rośnie wykładniczo i po za normalne użytkowanie to znaczy że już się zaczyna.
- Debugując program, czyli np. przerywając program w danym momencie.
Można ręcznie np. w skrypcie. Można za pomocą GDB jesli napisany w C.
- Debugując program, czyli np. obserwowanie logów aplikacji
- Debugując program, czyli np. obserwując wyjście w terminalu
- Programy pisane w C mają jeszcze taki program jak Valgrind i Memcheck

2. Limitowanie jest trochę " specyficzne "
- Podział na " hard and soft limits "
- Że się tak wyrażę każdy system posiada wartość do której maksymalnie da się otworzyć liczbę procesów. ( ulimit -a )
Więc ograniczenie musi być wartością mniejszą.
- Jest oczywistym że jeśli wyczerpiesz zasoby użytkownika, to system przestanie odpowiadać, a dokładniej będzie odpowiadał, ale strasznie wolno.
Od tego masz konto root żeby ubić niechciany proces. Dlatego możesz terminal z kontem root otworzyć wcześniej.
( Konto root powinno już działać normalnie - jeśli zabezpieczyłeś zasoby )

Przykładowe poradniki
- https://linuxhandbook.com/ulimit-command/
- https://sysadminxpert.com/configure-ulimit-values-permanently-on-linux/
 
3. Nie wiem czy Ci się przyda, ale możesz tez poczytać o prlimit  https://man7.org/linux/man-pages/man1/prlimit.1.html
« Ostatnia zmiana: 2023-04-10, 23:09:16 wysłana przez 1709 »
PS: Brak polskiej czcionki, nie jest to brak lenistwa, a jej brak w systemie i brak czasu na reczne poprawki.

Offline overcq

  • Nowy na forum
  • *
  • Wiadomości: 34
    • Zobacz profil
    • ‛overcq’
Odp: Uniemożliwienie wykonania fork‐bomby
« Odpowiedź #2 dnia: 2023-04-12, 18:54:17 »
Właśnie problem w tym, że bez względu na limity (jeśli tylko były jakieś nie najniższe), system zaczynał reagować bardzo wolno i nie dało się nic zrobić, mimo że jeszcze działał. Jeśli udało mi się przełączyć do terminala i zalogować na konto root, to polecenie “pkill” nie było w stanie ‚ubić’ procesów.
Rozwiązałem to na razie przy użyciu polecenia “nice”. Znalazłem też informacje o “cgroups”, ale nie widzę w moim systemie (Gentoo) żadnych narzędzi do konfiguracji. Poza tym “cgroups” raczej odnoszą się do rozdzielania użytkowników, a nie grup procesów jednego użytkownika.

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3062
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
Odp: Uniemożliwienie wykonania fork‐bomby
« Odpowiedź #3 dnia: 2023-04-12, 21:19:25 »
To może z innej strony - jak odpalisz brutala z CPU affinity na 1-2 rdzenie, nie powinien istotnie zamulić reszty systemu (poza zasobami typu PIDy, uchwyty) - ale musisz mieć otwartą konsolę roota przed "wypadkiem", bo może być problem z odpaleniem jej później właśnie ze względu na zasoby "pozaprocesorowe". Zamulanie jest też często spowodowane wjechaniem w swapa przy wyczerpaniu pamięci. W Archu to część pakietu util-linux, nie mam pod ręką Gentoo.
# Uruchomi "program" tylko na rdzeniach 0 i 1
taskset -c 0-1 ./program

Jeżeli masz Gentoo z systemd, możesz tak:

# Ograniczy pamięć do 100MB fizycznej + 100MB SWAP, pozwoli zająć średnio w pełni
# max 1 CPU (to coś innego niż poprzednie affinity) i pozwoli powołać max 100 procesów
systemd-run --user -G -p MemoryMax=100M -p MemorySwapMax=100M -p "CPUQuota=100%" -p "TasksMax=100" ./program
Tutaj masz dostępne kagańce, jakie możesz pozakładać.

Możesz też zrobić "bezpiecznego" shella poniższym poleceniem, i odpalać w nim programy interaktywne.
systemd-run --user -G -S -p MemoryMax=100M -p MemorySwapMax=100M -p "CPUQuota=100%" -p "TasksMax=100" 

Zrobiłem shella (tylko z "TasksMax=10" zamiast 100) i klasyczna bashowa forkbomba : (){ : | : & } ; : zrobiła... właściwie nic. bash: fork: Zasoby chwilowo niedostępne, load zero, pamięć stała, nic. Spokojnie mogłem otworzyć drugiego shella i zakillować pierwszego.
« Ostatnia zmiana: 2023-04-12, 22:11:36 wysłana przez Paweł Kraszewski »
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy