Vim może łamać uprawnienia do plików?

8

Używałem Vima jak zwykle, kiedy zauważyłem coś dziwnego. Oto co zrobiłem:

~$ touch testfile
~$ ls -l | grep testfile
-rw-r--r-- 1 username groupname 0 Jul 23 10:00 testfile
~$ vim testfile

Potem dokonałem zmiany, zapisałem i rzuciłem :wq. Całkiem normalne. Potem jednak:

~$ sudo chown root:root testfile
~$ sudo chmod 644 testfile
~$ sudo -k
~$ ls -l | grep testfile
-rw-r--r-- root root 0 Jul 23 10:02 testfile
~$ vim testfile

Tak więc root powinien mieć dostęp r / w, a wszyscy inni powinni tylko czytać. Edytuj plik, spróbuj zapisać - nie możesz. Niesamowite, działa zgodnie z przeznaczeniem. Jeśli jednak zapiszesz za pomocą :w!, vim w jakiś sposób zmieni własność pliku z powrotem na nazwę użytkownika: grupa użytkowników i plik zostanie zapisany. Nawet jeśli to zrobisz:

~$ sudo chmod 444 testfile
~$ sudo -k
~$ ls -l | grep testfile
-r--r--r-- 1 root root 0 Jul 23 10:06 testfile
~$ vim testfile

Nadal możesz nadpisywać :w!! Co się dzieje? W jaki sposób vim może złamać takie prawa własności i zgody na pliki? Spojrzałem na stronę pomocy w vimie, mówiąc :help :wi znalazłem:

:w[rite]! [++opt]    Like ":write", but forcefully write when 'readonly' is set or there is another reason why writing was refused.
                     Note: This may change the permission and ownership of the file and break (symbolic) links. Add the 'W' flage to 'cpoptions' to avoid this.

Nie byłem w stanie wcześniej napisać do pliku w vimie, kiedy nie powinienem, więc myślę, że sedno mojego pytania brzmi: w jaki sposób mogę sprawić, że plik nie będzie edytowalny przez vima i dlaczego nie jest oparty na pliku uprawnienia systemowe, jak się spodziewałem, i jakiego mechanizmu używa vim do edycji pliku, którego inni edytorzy (gedit, nano) nie mogą użyć?

EDYCJA: Komputer, na którym próbowałem tego, używa jądra Linux 3.15.5-2-ARCH. Numer wersji Vima to 7.4.373-1 i to ten zainstalowany przez pacman- nie skompilowałem go od zera za pomocą specjalnych opcji.

zrneely
źródło
Wydaje mi się, że nie jestem w stanie odtworzyć problemu, chyba że
podejmę
Właśnie spróbowałem ponownie, używając poleceń z pytania, i stało się tak samo. Zmienię pytanie, aby dodać szczegóły dotyczące mojego komputera, ponieważ wygląda na to, że może to zależeć od platformy.
zrneely
Moje pierwsze przeczucie polega na tym, że możesz zmienić własność plików w katalogu, do którego masz dostęp do zapisu. Ale wydaje się, że tak nie jest . CAP_CHOWNjest wymagane, aby zadzwonić chown(2). Nawiasem mówiąc, mogę reprodukować na Debianie z vimem 7.4.
Bob

Odpowiedzi:

10

Widzę, że twoją bieżącą ścieżką jest ~katalog domowy użytkownika. Powinieneś mieć uprawnienia do zapisu w tym katalogu.

Pomyśl o tym z innej strony - jeśli masz uprawnienia do odczytu i zapisu do katalogu, co powstrzymuje Cię przed kopiowaniem pliku, usuwaniem starego i zmienianiem nazwy nowego na inne uprawnienia?

To właśnie robi vim!


Jeśli uruchomisz vima pod kontrolą, na przykład:

open("testfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = -1 EACCES (Permission denied)
lstat("testfile", {st_mode=S_IFREG|0644, st_size=10, ...}) = 0
getuid()                                = 1000
unlink("testfile")                      = 0
open("testfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 3
write(3, "ffjidfjds\n", 10)             = 10
fsync(3)                                = 0
close(3)                                = 0
chmod("testfile", 0644)                 = 0

Na podstawie tego dziennika mogę odgadnąć następujący proces:

Niektóre wcześniejsze kontrole uprawnień (i chownpróby itp.) Są pomijane ze względu na zwięzłość.

  1. open Próba otwarcia pliku do zapisu (błąd: odmowa uprawnień)
  2. lstat Sprawdź właściciela pliku
  3. getuuid Sprawdź bieżący identyfikator użytkownika, aby sprawdzić, czy odpowiada on właścicielowi pliku
  4. unlink Usuń plik (jest to dozwolone, ponieważ uprawnienia do zapisu w katalogu)
  5. open Utwórz nowy plik o tej samej nazwie
  6. write Zawartość pliku (czytaj wcześniej, wpisałem trochę bełkotu)
  7. fsync Opróżnij plik na dysk (niezbyt ważne)
  8. close
  9. chmod Zmień uprawnienia nowego pliku, aby wyglądał jak stary - tak się składa, że ​​ma teraz nowego właściciela.
Kok
źródło
Ok dzięki. Cieszę się, że to rozgryzłem. Więc jeśli nie mam uprawnień do zapisu w katalogu, nie będę mógł używać :w!, co ma sens.
zrneely
Ponadto informacje o przebiegu są bardzo przydatne - teraz mam inne narzędzie do własnych badań w przyszłości.
zrneely
1
@zrneely Wskazówka dla strace: użyj -oopcji, aby zapisać dane wyjściowe w pliku; w przeciwnym razie koliduje z vimwyjściem. Jeśli chodzi o uprawnienia zapisu, nie widzę go z katalogów sprawdzanie uprawnień stat, ale nie próbować utworzyć plik (o nazwie 4913wydaje losowo) w bieżącym katalogu, a następnie usunąć.
Bob
Wydaje się, że tak 4913naprawdę to tylko pierwsze imię, które próbuje, a jego celem jest sprawdzenie, czy ma wystarczające uprawnienia, aby to zrobić. Zobacz: bugzilla.redhat.com/show_bug.cgi?id=427711#c6 i groups.google.com/forum/#!topic/vim_dev/sppdpElxY44
Bob