W jaki sposób „rm -rf /” jest w stanie usunąć wszystkie pliki w systemie?

81

Nie próbowałem tego polecenia na Ubuntu (z oczywistych powodów), więc nie jestem pewien, czy Ubuntu pozwoli na jego wykonanie. Ale słynie z usuwania wszystkiego. Z ciekawości, co się stanie, gdy jądro i /binzostaną usunięte? Jak rmutrzymuje się stos czasu wykonywania? Jak rmzarządza komunikacją z systemem plików i całkowitym usunięciem? Jak komunikuje się ze sprzętem?

Muye
źródło
18
rm -rf /nie usuwa niczego bez --no-preserve-root.
muru
47
Moim pierwszym doświadczeniem z Linuksem było stworzenie Ubuntu vm, aby móc go „rm -rf /”. Polecam spróbować tego. Jest dość szybki w konfiguracji, zapewnia bezpieczeństwo twojego hosta i jest bardzo zabawny, gdy patrzysz, jak różne części systemu operacyjnego rozpadają się na twoich oczach. Bardzo satysfakcjonujące.
DJMcMayhem
21
Przypomina mi mój ulubiony zaniżony raport o błędzie: bugzilla.redhat.com/show_bug.cgi?id=1202858 „Oczekiwane wyniki: Squid jest restartowany. Rzeczywiste wyniki: Wszystkie pliki są usuwane z komputera.”
9
Powinieneś przeczytać Unix Recovery Legend . Dopóki jesteś zalogowany do powłoki, system nie jest całkowicie martwy!
200_sukces
2
@gerrit zrobiłem . :)
muru

Odpowiedzi:

79

Nie ma znaczenia, że /bin/rmzostanie usunięty. Jest uruchamiany tylko raz i do tego momentu wszystko jest ładowane do pamięci, podobnie jak wszystko inne wymagane do dalszego wysyłania usunięć do systemu plików i dysku.


Pasek boczny / aktualizacja: Według odpowiedzi Davida Hoelzera (i wspomnianej w komentarzach) i-węzeł, na /bin/rmktóry wskazywał hardlink, pozostałby do samego rmkońca (ponieważ Linux jest w stanie otwartym), ale fakt ten jest nieistotny; stan dysku w ogóle nie ma znaczenia.

Plik binarny jest ładowany do pamięci przed uruchomieniem. Nawet jeśli możesz ręcznie zniszczyć rmdane na dysku, nie wpłynie to na proces usuwania ani go nie zatrzyma (przy założeniu, że dysk nie stanie się niedostępny).

Nie masz pojęcia, co to jest i-węzeł lub hardlink? To jest odpowiedź na to pytanie.


W każdym razie właśnie dlatego możesz usunąć pakiet dla bieżącego jądra bez implodowania komputera. Dopóki zainstalujesz inną wersję, będzie można ją uruchomić.

Ponownie działa to, ponieważ rmjest wywoływane tylko raz. Następujące nie powiedzie się po /bin/rmśmierci, ponieważ wywołuje to raz dla każdej nazwy pliku:

find / -exec rm {} \;

To powiedziawszy, find / -exec rm -rf {} +i find / -print0 | xargs -0 rm -rfoba prawdopodobnie również zawiodą, ponieważ oba mają ograniczenia argumentów, co oznacza, że ​​usuną tylko kilka plików przed ponownym wywołaniem. W pewnym momencie podróży /bin/rmmoże wygasnąć ( i zostać zwolniony) przed usunięciem pozostałych plików. Nie jest to jednak gwarantowane. Gdyby /bin/wprowadzono ostatni katalog, te metody mogłyby działać.

Oli
źródło
7
Jak wyjaśnia @DavidHoelzer, niepowiązane pliki nie muszą już znajdować się w pamięci, aby dalej działać. Jądro wie, że istnieje otwarty uchwyt pliku, więc utrzymuje dane pliku, aby spełnić wszelkie żądania (w tym wejścia stron), aż do zamknięcia ostatniego uchwytu.
Andrew Medico,
4
@Desty, nie, to by się nie udało, o ile /bin/rmnie jest wystarczająco blisko, aby być w ostatniej partii; -exec ... {} +(ucieczka przed odwrotnym ukośnikiem jest niepotrzebna) nadal powoduje wielokrotne wykonywanie; nie jeden na plik, ale jeden na partię na podstawie liczby argumentów, które mogą zmieścić się w ARG_MAX.
Charles Duffy
6
@Oli, nie chodzi o stronicowanie; liczniki odwołań są połączone z i-węzłem, a nie z pozycją katalogu, a uchwyt otwartego pliku jest liczony jako odniesienie (tak samo jak twardy link), co zapobiega dealokacji i-węzła. Rozmiar pliku w ogóle nie ma znaczenia, a dzieje się tak nawet wtedy, gdy nie ma przestrzeni wymiany (a więc stronicowania).
Charles Duffy
2
@CharlesDuffy Bez względu na to, czy masz przestrzeń wymiany, czy nie, stronicowanie będzie używane dla wszystkich plików mapowanych w pamięci. Dotyczy to wszystkich plików wykonywalnych i bibliotek. W rzeczywistości brak przestrzeni wymiany może oznaczać więcej stronicowania dla plików mapowanych w pamięci.
kasperd
2
@CharlesDuffy Tak, rozmiar jest rzeczywiście nieistotny. Odwzorowanie pamięci pliku nie powoduje załadowania żadnej zawartości pliku do momentu uzyskania dostępu. Pamięć użyta do załadowania części pliku, do której uzyskano dostęp, może zostać w razie potrzeby ponownie zwolniona, po czym zostanie ponownie załadowana z pliku, jeśli będzie dostępna ponownie. Tak więc plik musi pozostać w systemie plików tak długo, jak jest mapowany, i zachowuje się tak samo w przypadku pliku jednostronicowego, jak w przypadku pliku wystarczająco dużego, aby objąć całą przestrzeń adresową. (Szczegóły są nieco bardziej skomplikowane w przypadku mapowań kopiowania przy zapisie, które są potrzebne do dynamicznego łączenia).
kasperd
57

Nie próbowałem tego polecenia na Ubuntu (z oczywistych powodów), więc nie jestem pewien, czy Ubuntu pozwoli na jego wykonanie.

Zrobiłem. rm -rf / --no-preserve-rootdziałał w sesji root otwartej bezpośrednio na maszynie, podczas gdy ja również byłem połączony sshz innego komputera, używając również konta root.

Dzieje się tak, że zaczynasz otrzymywać wiele wiadomości, takich jak:

rm: nie można usunąć „/ ...”: Operacja niedozwolona

lub:

rm: nie można usunąć „/ ...”: Urządzenie lub zasób zajęty

wprowadź opis zdjęcia tutaj

Co zaskakujące, sshpołączenie pozostało otwarte do końca operacji. Dopiero gdy zamknąłem połączenie i próbowałem ponownie je otworzyć, pojawił się błąd:

Odczyt z gniazda nie powiódł się: resetowanie połączenia przez partnera

Na komputerze pozostają cztery katalogi:

  • /dev. Tutaj przechowywane są pliki urządzeń.
  • /proc—System plików w pamięci utworzony przez jądro.
  • /run, ustandaryzowana lokalizacja systemu plików dla demonów.
  • /sys. Pozwala to uzyskać informacje o systemie i jego komponentach.

Oznacza to, że niewiele zostało i nie ma wiele do zrobienia. Nie możesz ls(chociaż podczas używania Tabnazwy katalogów i plików są nadal wyświetlane). Możesz cdw różnych katalogach, a także w różnych echorzeczach, ale takie polecenia catnie są już dostępne.

Nie ma sudoteż żadnego .

shutdown -h nowi rebootzniknął, więc twoją jedyną opcją wydaje się ręczne wyłączenie urządzenia. Logout ( exit) nie działa, nawet jeśli wyświetla ładny tekst „logout”.

Gdy spróbujesz zrestartować komputer, pojawi się niezły błąd GRUB 15, a potem nic się nie dzieje, w tym momencie możesz zacząć myśleć, że mogłeś rmzrobić coś złego w twoim systemie.

wprowadź opis zdjęcia tutaj

Ty też możesz to zrobić

Nie, czekaj, nie rób tego na swoim komputerze!

Zamiast tego możesz uruchomić maszynę wirtualną . Maszyny wirtualne mają tę zaletę, że ułatwiają eksperymentowanie. Ponieważ używasz Ubuntu, vmbuilder może Cię zainteresować . Jest to narzędzie, które pozwala wdrożyć maszyny wirtualne w ciągu kilku minut (oficjalna dokumentacja twierdzi, że można to zrobić „za około minutę”, ale faktyczny czas, nawet na szybkim sprzęcie, wynosi około dwóch-trzech minut .

Po zakończeniu wdrożenia masz środowisko, w którym możesz grać. Jeśli ostatecznie go zniszczysz, nie ma to znaczenia: ponownie uruchom maszynę, a dwie minuty później możesz kontynuować.

Jeśli korzystasz z oprogramowania takiego jak VMWare, możesz być również zainteresowany migawkami (zwróć uwagę, że darmowy VMWare Player nie ma tej funkcji; musisz kupić VMware Workstation). Pamiętaj, że Hyper-V jest bezpłatny i obsługuje migawki (ale musisz uruchomić system Windows).

Zaletą migawek jest to, że możesz zrobić jedną w ciągu kilku milisekund. Przywracanie do migawki trwa dłużej, ale często zajmuje kilka sekund. To sprawia, że ​​eksperymentowanie jest jeszcze łatwiejsze i szybsze.

To eksperymentowanie nie ogranicza się do samego systemu operacyjnego. Możesz robić różne rzeczy związane z oprogramowaniem. Masz podejrzaną aplikację? Przetestuj na maszynie wirtualnej - jeśli jest to wirus, nie wyrządzi żadnej szkody. Chcesz przetestować operację na bazie danych, ponieważ może to mieć wpływ na środowisko? Przetestuj na maszynie wirtualnej.

Co jeśli zrobiłbyś to na prawdziwej, nie testowej maszynie?

Zdarzają się złe rzeczy. Pamiętaj, że rmchroni cię przed sobą: rm -rf /nie działa: musisz użyć --no-preserve-root. Ale co jeśli rzeczywiście udało ci się przez pomyłkę usunąć wszystko?

rmusuwa tylko pliki , ale dane są nadal na Twoim dysku twardym. Dzięki temu można je później odzyskać (dlatego nie należy po prostu wyrzucać dysków twardych z danymi wrażliwymi, gdy już nie działają).

Oznacza to, że wystarczy mieć zapasowy komputer z obudową dysku twardego, aby odzyskać prawie wszystkie pliki. Ważne jest, aby unikać zapisywania czegokolwiek na dysku twardym w celu odzyskania: zapisane dane zastąpią niepowiązane pliki.

Jak zauważono w artykule w komentarzu 200_success , jeśli będziesz działać mądrze, możesz odzyskać maszynę nawet bez zapasowego komputera. Jeśli zależy Ci tylko na danych, nie zawracałbym sobie głowy - odzyskanie ich za pomocą zapasowego komputera jest znacznie łatwiejsze.

Arseni Mourzenko
źródło
VirtualBox obsługuje migawki dysku.
Nathan Osman,
1
Zauważ, że wirusy są często zaprojektowane do wykrywania maszyn wirtualnych, więc nie zalecałbym tego procesu wykrywania wirusów. Małe pytanie: pozostałe cztery katalogi nie są „prawdziwymi” katalogami, prawda? Nie są na dysku twardym? Co pozostaje na dysku twardym po uruchomieniu tego polecenia?
raptortech97
2
@ raptortech97 rmtak naprawdę nie usuwa danych z dysku twardego, po prostu „rozłącza” (rozłącza) rzeczywiste dane na dysku z drzewa systemu plików, oznaczając je jako wolne (aby mogły zostać ostatecznie nadpisane przez normalne użycie komputera). Więc jeśli, powiedzmy, rm -rf ~nie wszystko stracone, o ile działasz szybko (np. Z extundelete). Możesz myśleć o tym jako o jeszcze bardziej niewiarygodnej wersji folderu „usuniętego” w skrzynce pocztowej, możesz odzyskać rzeczy, jeśli nie zaczekasz zbyt długo, ale w końcu zostaną usunięte.
Thomas
@ raptortech97 Z drugiej strony, jeśli z jakiegoś powodu nie używałeś , rmale shredto już prawie koniec gry, chociaż prawdopodobnie będziesz miał czas, aby uświadomić sobie swój błąd i przerwać, ponieważ niszczenie trwa dłużej.
Thomas
5
Przechowywane katalogi są najprawdopodobniej punktami montowania w takiej czy innej formie. Polecenia, które nadal działają, to wbudowane polecenia bash, a nie oddzielne pliki binarne. Więc dopóki lsnie ma go, for i in /*; do echo $i; donepowinno działać. Aby zastąpić, catmożesz użyć polecenia takiego jak while read i; do echo $i; done < /proc/self/maps.
MvG,
25

Powodem jest to, że warstwa nazewnictwa plików (to, co widzisz ls) jest naprawdę dla Twojej wygody. Sterownik systemu plików i jądro dbają tylko o to, czym jest i-węzeł. Gdy do pliku odwołuje się nazwa, jest on natychmiast tłumaczony na i-węzeł, który zawiera wszystkie metadane, w tym uprawnienia, bloki danych na dysku, identyfikator właściciela, identyfikator grupy i liczbę łączy.

Liczba linków jest tutaj naprawdę ważna. Gdy usuwasz plik w systemie UNIX, faktyczne wywołanie systemowe to unlink. To, co dzieje się pod maską, polega na tym, że liczba linków (liczba nazw plików w warstwie nazewnictwa plików) wskazująca na ten i-węzeł jest zmniejszana. System plików wie, że plik jest usuwany, gdy liczba linków osiągnie zero.

Usunięcie pliku rmspowoduje również edycję pliku katalogu (tak, to tylko plik zawierający nazwę pliku i i-węzeł oprócz kilku innych bitów, które nie są ważne dla tej odpowiedzi). Jednak to rozłączenie faktycznie uwalnia zasoby dysku.

To prowadzi do innych interesujących efektów. Po pierwsze, możliwe jest otwarcie pliku, którego liczba linków wynosi zero. Dzieje się tak, gdy rm -rf /usuwa wpis dla /bin/rm. Plik jest otwarty (jest do niego uchwyt pliku), ale i-węzeł jest oznaczony jako usunięty (liczba linków = 0). Zasoby dyskowe nie zostaną zwolnione i ponownie użyte, dopóki uchwyt pliku nie zostanie zamknięty.

Innym interesującym efektem jest to, co dzieje się, gdy masz i-węzeł z liczbą linków większą niż zero, ale nic w warstwie nazewnictwa plików, która na to wskazuje. To w pewnym sensie bardzo dobrze ukryty plik :). Aby uzyskać do niego dostęp, musisz użyć czegoś niskiego poziomu, aby odwołać się do niego za pomocą numeru i-węzła, a nie według nazwy (ponieważ nie istnieje) lub edytować wpis katalogu, aby wskazywał na i-węzeł za pomocą edytora szesnastkowego.

Trzecim interesującym efektem jest zmniejszenie liczby linków do zera, ale i tak skierowanie wpisu katalogu na i-węzeł. Zostawię to tobie do eksperymentowania, jeśli chcesz. Oczywiście oba te dwa ostatnie prowadzą do niespójności systemu plików.

David Hoelzer
źródło
Patrząc z innej strony, liczba linków nie jest równa zero, ponieważ otwarcie pliku dodaje link w / proc.
OrangeDog,
@OrangeDog, to zachowanie nadal istnieje, nawet jeśli procfs jest odmontowany.
Charles Duffy
1
@OrangeDog Charles Duffy ma rację. Uchwyty plików w / proc nie modyfikują i-węzłów, dostosowując liczbę łączy.
David Hoelzer
/ proc i / sys są odzwierciedleniem bieżącego stanu systemu (jądra). Tylko wybrane akcje dla plików i katalogów tam faktycznie zmieniają stan systemu.
CVn
18

Poprzednie odpowiedzi są dobre, ale chcę wyjaśnić jeden szczegół:

rmto nie tylko polecenie. Jest to program, który można znaleźć w PATH.

Dlatego to, co dzieje się podczas wykonywania, jest następujące:

  • dzwonisz (jako root) rm -rf /
  • wystąpienie programu rmjest ładowane do pamięci z argumentami -rfi/
  • na podstawie tych argumentów program rmrozpoczyna działanie (przeglądając wszystko w zamontowanym / partycji i rekurencyjnie usuwając do niego odwołania [przepraszam za techniczność;)])
  • po zakończeniu instancja rmprogramu jest rozładowywana
  • w tym momencie jedyne rzeczy w pamięci to programy, które zostały tam wcześniej załadowane (np. bash, jeśli masz otwarty terminal w Ubuntu, środowisku Desktop, jądrze, sterownikach itp.)
  • jeśli spróbujesz wywołać dowolne inne polecenie (które w przypadku Linuksa czyni go samodzielnym programem), zakończy się ono niepowodzeniem, ponieważ nie ma takiego programu w lokalizacjach PATH (a lokalizacje PATH już nie istnieją). Jednak wszystko po załadowaniu będzie nadal działać

Aby zrozumieć, jak to działa, spróbuj zainstalować LAMP na Ubuntu (w Virtualbox), trochę skryptów i pamięci podręcznej kodu PHP, a następnie wywołaj to złe polecenie. Zaskakujące (jeśli masz szczęście, a pamięć podręczna opcode nie zauważy usunięcia pliku php), nadal możesz uzyskiwać dostęp do skryptów php z zewnątrz za pośrednictwem serwera Apache!

PS: to złe polecenie działało nawet jako root nie usuwa everything, nie może usuwać niektórych uprzywilejowanych procesów jądra /proci nie może usuwać niektórych rzeczy z /devurządzeń, które pojawiają się w twoim systemie jako pliki. W rzeczywistości root nie jest tak wszechmocny, jak nam się wydaje, z drugiej strony jądro.

PPS: Również jako druga myśl nadal będziesz mieć pliki, które były lockedw innym procesie w chwili próby usunięcia.

Alexey Kamenskiy
źródło
W systemie Linux z pewnością można usunąć węzły urządzeń, uruchamiając je jako root. Ale tak, nie można niczego usunąć, /procponieważ jest to system plików tylko do odczytu. Podobnie dla /sys. Uważam, że nie można również usunąć punktów montowania.
Brian
@AlexKey Sugeruję edycję, aby wyjaśnić, co rozumiesz przez „wbudowane polecenie inne niż jądro” (lub aby całkowicie uniknąć tego wyrażenia). Wygląda na to, że mówisz, że istnieją polecenia, które możesz uruchomić przez powłokę, które są zaimplementowane bezpośrednio w jądrze, więc zawsze działają bez względu na wszystko. (To znaczy, jak zapewne wiesz, ale wielu czytelników może tego nie robić , a nie przypadek: gdy uruchomisz polecenie podobne cd, wywołuje to wbudowaną powłokę o tej nazwie - to polecenie jest wbudowane w powłokę, a nie w jądro). oznacza „polecenia” Alt + SysRq?
Eliah Kagan
@Brian czy to zależy od dystrybucji? Pracowałem w różnych dystrybucjach i jak śmiesznie to brzmi, popełniłem ten błąd wiele razy. Jak sobie przypomniałem po sprawdzeniu szczątków / wciąż było coś w / dev, ale może to być coś takiego jak cdrom lub dyskietka ...
Alexey Kamenskiy
@EliahKagan Gdy próbowałem pozostać niezależny od dystrybucji, użyłem tego terminu. Oznacza to, że nie we wszystkich systemach polecenie cli oznacza program zewnętrzny. Ale dzięki, że to zwróciłem, wyjaśnię tę kwestię.
Alexey Kamenskiy,
@AlexKey Wierzę, że nie będziesz w stanie usunąć, /dev/ptsponieważ jest to punkt montowania. (I także system plików tylko do odczytu.)
Brian
1

Po wyczyszczeniu wszystkiego z dysków twardych jądro nadal działa, ale utknęło, ponieważ nie ma już żadnych urządzeń i programów, poleceń itp.

System operacyjny nie będzie już działać.

I to prawda, co mówi Oli, polecenie zostaje załadowane / wykonane do pamięci i nic go nie zatrzyma, chyba że zabijesz ten proces (oczywiście, jeśli polecenie zabicia jest nadal obecne ^^).

s1mmel
źródło
4
Dlaczego jądro utknęło? Odpowiedź MainMa sugeruje inaczej i potwierdza to, czego bym się spodziewał.
MvG,
4
Programy działają z pamięci, a nie z dysku twardego. Jądro nie będzie wiedziało, że coś jest nie tak, dopóki nie uruchomi się ponownie.
phyrfox,
Cóż, może muszę zmienić użyte słowa, jądro jest mniej lub bardziej „zablokowane” bez urządzeń, programów itp., A jeśli nie znajdujesz się przed konsolą główną, nie możesz robić złych rzeczy, nawet na tym konsoli nie można robić złych rzeczy. Zgadzam się, ale zmienię sformułowania w odpowiedzi, ponieważ są one mylące.
s1mmel
0

Należy pamiętać, że jeśli system ma selinux i selinux jest w trybie wymuszania, a zasady selinux są skonfigurowane poprawnie; wtedy nic się nie wydarzy.

Selinux jest obowiązkową kontrolą dostępu, co oznacza między innymi, że użytkownik root naprawdę nie ma dużo więcej mocy do zniszczenia systemu niż jakikolwiek inny użytkownik w systemie.

Selinux jest wymuszony w jądrze; musiałbyś skompromitować jądro, aby się obejść.

W dobrze zaprojektowanym systemie z dobrymi zasadami Selinuksa root nie byłby w stanie wiele zrobić w systemie.

Późniejsze wersje Androida wprowadzają Selinux z tego właśnie powodu.

Mark Allyn
źródło