Dlaczego plik z 400 uprawnieniami jest zapisywany przez użytkownika root, ale przez użytkownika tylko do odczytu?

10

Jeśli utworzę plik jako użytkownik nieuprzywilejowany i zmienię tryb uprawnień na 400, ten użytkownik zobaczy go jako tylko do odczytu, poprawnie:

$ touch somefile
$ chmod 400 somefile
$ [ -w somefile ] && echo rw || echo ro
ro

Wszystko dobrze.

Ale potem pojawia się root:

# [ -w somefile ] && echo rw || echo ro
rw

Co za cholera? Jasne, root może zapisywać do plików tylko do odczytu, ale nie powinien mieć z tego zwyczaju: najlepsza praktyka dyktuje, że powinienem być w stanie przetestować bit uprawnień do zapisu, a jeśli nie, to został ustawiony w ten sposób z jakiegoś powodu.

Chyba chcę zrozumieć, dlaczego tak się dzieje, i jak mogę uzyskać fałszywy kod powrotu podczas testowania pliku, w którym nie ma ustawionego bitu zapisu?

Bogaty
źródło
btw Używam zarówno RHEL6 ( 4.1.2(1)-release), jak i RHEL7 ( 4.2.46(2)-release).
Bogaty
16
„Najlepsza praktyka zwykle dyktuje, że powinienem być w stanie przetestować bit zezwolenia na zapis, a jeśli nie, to ustawiono go z jakiegoś powodu”. - W rzeczywistości najlepszą praktyką jest „nie uruchamiaj rzeczy jako root”. Jeśli działasz jako root, już zdecydowałeś się ominąć sprawdzanie uprawnień. Ręczne ponowne wdrożenie tych kontroli uprawnień w przestrzeni użytkownika to przepis na katastrofę .
Kevin
@Kevin Dobrze dla ciebie, jeśli możesz uruchomić rzeczy nieuprzywilejowane. Służy do manipulacji /etc/dhcp/dhcpd.conf, której właścicielem jest root. Korzystam z dostarczonego przez dostawcę dhcpd. Totalna katastrofa, co? Plik jest sprawdzany w RCS, automatyzuję korzystanie rcsdiff, cia coponieważ mamy operatorów, którzy muszą ... operować. Kontrola bitów uprawnień ( -wjak szczegółowo opisano test(1)) miała być pierwszą linią awarii, działającą na podstawie, która ci -upozostawia plik tylko do odczytu. Porzucam to, idę prosto rcsdiff -qi sprawdzam $?. Niesmaczny dhcpd? Byłby własnością dhcpd.
Bogaty
1
Jest to potencjalna katastrofa, ponieważ masz teraz dwie różne implementacje kontroli uprawnień: jedną w jądrze i jedną w przestrzeni użytkownika. Co gorsza, te implementacje nie mają nawet na celu generowania identycznych wyników, więc nie można po prostu przetestować ich wzajemnie. Masz teraz dwie ścieżki dostępu, które należy zablokować i zabezpieczyć niezależnie od siebie.
Kevin
@Kevin Pewnie, nie dają identycznych wyników i nie były przeznaczone (pomimo niedostatku szczegółów na stronach podręcznika), ale ja wyraźnie chcę sprawdzić bit zezwolenia na zapis ; i strony podręczników bashi testdoprowadziły mnie do przekonania, że ​​po to [ -wjest.
Bogaty

Odpowiedzi:

26

test -waka [ -wnie sprawdza trybu plików. Sprawdza, czy można to zapisać. Tak jest w przypadku rootowania.

$ help test | grep '\-w'
  -w FILE        True if the file is writable by you.

Metodą, którą bym przetestował, byłoby porównanie bitowe z danymi wyjściowymi stat(1)(„ %a Prawa dostępu ósemkowe”).

(( 0$(stat -c %a somefile) & 0200 )) && echo rw || echo ro

Uwaga: podpowłoka $(...)wymaga 0prefiksu, aby wynik statinterpretowany był jako ósemkowy przez (( ... )).

Patrick
źródło
Dzięki za zwięzłość. Dobre wykorzystanie (( ... & ... )). Jedna literówka poprawiona :-)
Rich
Sprawdź, czy 3 ... Nie jest ifwymagane, dane wyjściowe uprawnień ósemkowych %anie są %di (( ... ))wymaga prefiksu, 0aby interpretować dane wyjściowe statjako ósemkowe.
Rich
@Patrick my man statmówi „% d numer urządzenia dziesiętnie”, ale to, czego chcemy, to „prawa dostępu”, prawda? Twoja uwaga o potrzebie prefiksu 0 jest dobrze wykonana, ale myślę, że musimy po prostu go tam znaleźć :).
sourcejedi
2
stat -c 0%a...
sourcejedi
@sourcejedi ack, masz rację. Z jakiegoś powodu myślałem, że% d ma prawa dostępu w systemie dziesiętnym. Przywrócono edycję. dzięki :-)
Patrick
30

Myślę, że źle zrozumiałeś -w. Nie sprawdza, czy plik ma „Uprawnienia do zapisu”, sprawdza, czy plik może zostać zapisany przez wywołującego użytkownika.

Mówiąc dokładniej, wzywa access(2)lub podobnie.

np. jeśli skrypt ma, if [ -w /etc/shadow ]to jeśli uruchomisz straceskrypt, możesz zobaczyć linię podobną do

faccessat(AT_FDCWD, "/etc/shadow", W_OK)

Ponieważ rootmoże zapisać do pliku, zwraca 0.

np. jako zwykły użytkownik:

faccessat(AT_FDCWD, "/etc/shadow", W_OK) = -1 EACCES (Permission denied)

Jako root

faccessat(AT_FDCWD, "/etc/shadow", W_OK) = 0

To pomimo faktu, że /etc/shadowma pozwolenie 000na moją maszynę.

---------- 1 root root 4599 Jan 29 20:08 /etc/shadow

Teraz to, co chcesz robić, staje się interesujące i nie jest takie proste.

Jeśli chcesz sprawdzić proste uprawnienia, sprawdź dane lswyjściowe, wywołanie statlub podobne. Pamiętaj jednak, że listy ACL mogą przekraczać te uprawnienia. Tylko dlatego, że plik ma uprawnienia 400, nie powstrzymuje go przed zapisywaniem ...

Stephen Harris
źródło
Nie, „nieporozumienie” oznacza błędne odczytanie stron podręcznika, ponieważ -w: test(1)jest jawne: „PLIK istnieje i udzielono zezwolenia na zapis ”, a nie „ plik może zostać zapisany przez bieżącego użytkownika ”. Nic o nadpisywaniu uprawnień ani list ACL. bash(1)to cagey: „Prawda, jeśli plik istnieje i można go zapisać ”. ksh(1)robi subtelną wskazówkę w stosunku do shenanigans: „-w plik // Prawda, jeśli plik istnieje i można go zapisać w bieżącym procesie ”. zsh(1)odsyła do test(1), zshmisc(1)jest sformułowane jako ksh(1)i zshexpn(1)opisuje niektóre interesujące globowania oparte na uprawnieniach. csh(1)jest przezabawnie zwięzły: „Dostęp do zapisu”.
btw: Zaakceptowałem odpowiedź Patricka, 1. ponieważ nie odpowiedziałeś odpowiednio na pytanie wstępne: w jaki sposób mogę uzyskać fałszywy kod zwrotny podczas testowania pliku, który nie ma ustawionego bitu zapisu? oraz 2. z powodu ponurego wprowadzenia, zakładając, że źle zrozumiałem strony podręcznika.
Bogaty
3
@Rich Sposób, w jaki to czytam, myślę, że twoje komentarze również wydają się nieco ponure. Nie twierdzę, że wszystko, co napisałeś, było złe, tylko to, że lepiej by się potoczyło, gdyby zostało wyrażone w bardziej uprzejmy sposób.
David Z
3
„Myślę, że źle zrozumiałeś ...” nie jest wredny. Twoja odpowiedź jednak w 100% snarky.
grill
@Rich Ponadto, chociaż strony podręcznika mogą nie być krystalicznie czyste, Stephen stwierdził, że być może „źle zrozumiałeś, co -w ”, a nie to, co mówią strony , w przypadku których to pierwsze wydaje się być prawdą, stąd pytanie
Sebi
1

Użytkownik root może robić, co chce, „normalne” uprawnienia do plików nie stanowią ograniczenia. Nie wykona bezpośrednio zwykłego pliku bez żadnych uprawnień eXecute, tylko dla odrobiny ubezpieczenia przed ćwiczeniem nożnym.

vonbrand
źródło