W jaki sposób vim kradnie pliki należące do roota?

39

Zobacz, co następuje:

sh-3.2$ mkdir testcase
sh-3.2$ cd testcase
sh-3.2$ sudo touch temp
sh-3.2$ ls -al
total 0
drwxr-xr-x   3 glen  staff  102 19 Dec 12:38 .
drwxr-xr-x  12 glen  staff  408 19 Dec 12:38 ..
-rw-r--r--   1 root  staff    0 19 Dec 12:38 temp

sh-3.2$ echo nope > temp
sh: temp: Permission denied

sh-3.2$ vim temp
# inside vim
itheivery
# press [ESC]
:wq!
# vim exits

sh-3.2$ ls -al
total 8
drwxr-xr-x   3 glen  staff  102 19 Dec 12:38 .
drwxr-xr-x  12 glen  staff  408 19 Dec 12:38 ..
-rw-r--r--   1 glen  staff    7 19 Dec 12:38 temp

Jakoś vim wziął ten plik będący własnością roota i zmienił go w plik należący do użytkownika!

Wydaje się, że działa to tylko wtedy, gdy użytkownik jest właścicielem katalogu - ale nadal wydaje się, że nie powinno to być możliwe. Czy ktoś może wyjaśnić, jak to się robi?

Glenjamin
źródło

Odpowiedzi:

51

Ty glenjesteś właścicielem katalogu (zobacz .plik we wpisie). Katalog jest tylko listą plików i masz uprawnienia do zmiany tej listy (np. Dodawania plików, usuwania plików, zmiany własności, aby znów była twoja itp.). Możesz nie być w stanie bezpośrednio zmienić zawartości pliku, ale możesz przeczytać i odłączyć (usunąć) plik jako całość, a następnie dodać nowe pliki. 1 Obserwując tylko przed i po, może to wyglądać, jakby plik został zmieniony.

Vim używa plików wymiany i przenosi pliki pod wodą, więc to wyjaśnia, dlaczego wydaje się zapisywać w tym samym pliku, co w powłoce, ale to nie to samo. 2)

Zatem to, co robi Vim, sprowadza się do tego:

cat temp > .temp.swp          # copy file by contents into a new glen-owned file
echo nope >> .temp.swp        # or other command to alter the new file
rm temp && mv .temp.swp temp  # move temporary swap file back

1 Jest to ważna różnica w obsłudze uprawnień do plików między Windows a Uniksem. W systemie Windows zwykle nie można usunąć plików, dla których nie masz uprawnień do zapisu.

Aktualizacja 2 : jak zauważono w komentarzach, Vim tak naprawdę nie robi tego w celu zmiany własności, ponieważ numer i-węzła w temppliku nie zmienia się (porównywanie ls -liprzed i po). Za pomocą stracemożemy zobaczyć dokładnie, co vimrobi. Interesująca część jest tutaj:

open("temp", O_WRONLY|O_CREAT|O_TRUNC, 0664) = -1 EACCES (Permission denied)
unlink("temp")                               = 0
open("temp", O_WRONLY|O_CREAT|O_TRUNC, 0664) = 4
write(4, "more text bla\n", 14)              = 14
close(4)                                     = 0
chmod("temp", 0664)                          = 0

To pokazuje, że tylko rozłącza , ale nie zamyka deskryptora pliku temp. Raczej po prostu nadpisuje całą zawartość ( more text bla\nw moim przypadku). Myślę, że to wyjaśnia, dlaczego numer i-węzła się nie zmienia.

gertvdijk
źródło
3
FWIW możesz sprawdzić, czy tak się dzieje, uruchamiając ls -ilprzed i po ... jeśli tempnumer i-węzła ulegnie zmianie, wiesz, że jest to inny plik o tej samej nazwie.
Bezużyteczny,
3
Można dodać, że rm tak naprawdę nie usuwa pliku, ale po prostu usuwa link do pliku, a plik nie jest usuwany, dopóki liczba linków nie spadnie do 0. rm po prostu usuwa wpis do pliku w katalogu. Jeśli root ma inne łącze (łącze twarde) do pliku w innym katalogu, użytkownik nie może usunąć pliku.
gerrit,
1
@Jeśli nie próbowałem, numer się nie zmienił, choć zmienił się właściciel i znacznik czasu!
amyassin,
1
@amyassin Masz rację! Zaktualizowałem swoją odpowiedź, wyjaśniając fragment strace.
gertvdijk,
1
Oprócz twojej uwagi na temat uprawnień Windows vs. Unix, jeśli chcesz zachować zachowanie podobne do Windowsa w Uniksie, możesz utworzyć katalog należący do roota (lub innego użytkownika, który powinien mieć uniwersalne uprawnienia do usuwania / zmiany nazwy / etc) i ustawić lepkość bit w katalogu. Wówczas użytkownicy będą mogli usuwać tylko własne pliki.
Matthew Crumley,
16

przed:

-rw-r--r-- 1 root staff 0 19 Dec 12:38 temp

po:

-rw-r--r-- 1 glen staff 7 19 Dec 12:38 temp

Vim nie przełamuje bariery uprawnień. Wystarczy dokładnie przejrzeć informacje o pliku, aby dowiedzieć się, że vim faktycznie usunął oryginalny plik (ponieważ masz uprawnienia do usunięcia pliku, ale nie możesz zmienić jego zawartości), a następnie utworzył nowy plik ( zobacz, że właściciel nie jest już „rootem”).

Podczas edytowania oryginalnego pliku w vimie, ostrzega o zmianie pliku tylko do odczytu. Kiedy więc wpiszesz polecenie :wq!(wymusisz operację), vim może jedynie usunąć istniejący plik i utworzyć nowy plik o identycznej nazwie.

Mam nadzieję, że to pomaga.

ymfoi
źródło
1

Użyj -iopcji, lsaby zobaczyć numer i-węzła, który jest unikalnym identyfikatorem (w systemie plików) pliku lub innego obiektu.

Zobaczysz, że plik został zastąpiony innym obiektem: numer i-węzła prawdopodobnie się zmieni.

Widzenie tego samego numeru i-węzła nie jest dowodem na nic: numer i-węzła można poddać recyklingowi. Jeśli usuniemy ostatni link do pliku, a następnie utworzymy nowy plik, możemy otrzymać taki z tym samym numerem i-węzła. Nie może się to jednak zdarzyć, jeśli stary plik zostanie usunięty po utworzeniu nowego. Np mv file file.tmp; touch file; rm file.tmp. Podejrzewam, że vim robi coś analogicznego do tego echo new_content > tmpfile; mv tmpfile file. mvPraca przełoży do renamewywołania systemowego, więc przypisanie numerów iwęźle zależy od sposobu narzędzi systemu plików do zmiany nazwy, która odłącza cel.

Kaz
źródło