Blokowanie plików wykonywalnych: Windows tak, Linux nie. Czemu?

83

Zauważyłem, że gdy plik jest wykonywany w systemie Windows (.exe lub .dll), jest on zablokowany i nie można go usunąć, przenieść ani zmodyfikować.

Z drugiej strony Linux nie blokuje plików wykonywalnych i można je usuwać, przenosić lub modyfikować.

Dlaczego system Windows blokuje się, a Linux nie? Czy blokowanie ma zalety?

David Lenihan
źródło
7
Istnieje narzędzie o nazwie WhoLockMe, które dodaje pozycję menu do menu kontekstowego w eksploratorze, która może wyświetlać procesy blokujące dany plik. Niezwykle przydatne, gdy pojawiają się dziwne błędy blokowania plików. Edycja: Wiem, że to nie jest odpowiedzią na pytanie, ale pomyślałem, że jest wystarczająco przydatne w kontekście, aby uzasadnić oddzielną odpowiedź (w przeciwieństwie do zwykłego komentarza).
JesperE

Odpowiedzi:

106

Linux ma mechanizm zliczania odwołań, więc możesz usunąć plik podczas jego wykonywania i będzie on istniał tak długo, jak długo jakiś proces (który wcześniej go otworzył) ma dla niego otwarty uchwyt. Wpis katalogu dla pliku jest usuwany po jego usunięciu, więc nie można go już otworzyć, ale procesy, które już używają tego pliku, mogą go nadal używać. Po zakończeniu wszystkich procesów korzystających z tego pliku plik jest automatycznie usuwany.

System Windows nie ma takiej możliwości, więc jest zmuszony do zablokowania pliku do czasu zakończenia wszystkich wykonywanych z niego procesów.

Uważam, że zachowanie Linuksa jest lepsze. Prawdopodobnie istnieje kilka głębokich powodów architektonicznych, ale głównym (i prostym) powodem, dla którego uważam go za najbardziej przekonujący, jest to, że w systemie Windows czasami nie można usunąć pliku, nie masz pojęcia dlaczego, a wszystko, co wiesz, to to, że jakiś proces utrzymuje go w posługiwać się. W Linuksie to się nigdy nie zdarza.

Oren Shemesh
źródło
2
Zwróć uwagę, że możesz użyć narzędzia takiego jak Process Explorer w systemie Windows, aby zobaczyć, jaki proces używa pliku / folderu.
J c
15
Praktycznym powodem przemawiającym za zachowaniem Linuksa jest to, że możesz aktualizować system operacyjny i inne oprogramowanie w systemie podczas jego działania i nigdy / rzadko uruchamiać ponownie (możesz nawet przełączyć działające jądro bez ponownego uruchamiania, jest to po prostu wystarczająco trudne, że nazywa się to tylko w aplikacjach o krytycznym znaczeniu dla czasu pracy).
joelhardi
7
„Windows nie ma tej możliwości”… czy na pewno? Jądro NT jest oparte na ponownym liczeniu obiektów z uchwytami i referencjami.
Adam Mitz,
11
W rzeczywistości system Windows ma 3 bity, które możesz ustawić, które definiują, co inny proces może zrobić z plikiem, gdy jest otwarty. Plik można usunąć, gdy jest otwarty, jeśli FILE_SHARE_DELETEbit jest ustawiony. Nie sądzę, aby program ładujący PE (który ładuje pliki EXE i DLL) ustawia ten bit. Uchwyty są zliczane i przy usuwaniu plik znika, gdy ostatni uchwyt zostanie upuszczony, ale różnica między nim a Uniksem polega na tym, że NT zablokuje utworzenie nowego pliku o tej samej nazwie, gdy to się stanie.
asveikau
2
To, co mówi Comonad, jest całkowicie błędne, NTFS oczywiście używa Hardlinks i zawsze tak było, dowiązania symboliczne zostały dodane w Windows Vista. Jest również całkowicie błędne, że system Windows nie używa ref copunting, robi to, po prostu czyta interfejsy API, takie jak CreateFile, gdzie eit jest jasno powiedziane, w jakich okolicznościach pliki można usunąć i tak dalej. I to jest właściwe miejsce na prawdziwą odpowiedź na to pytanie: CreateFile ma argument claled dwShareMode, który kontroluje obowiązkowe blokowanie otwartych plików i pozwala aplikacjom decydować. Wartością domyślną jest blokada na wyłączność ...
Thorsten Schöning
30

O ile mi wiadomo, Linux czy wykonywalne blokady, gdy są one uruchomione - jednak blokuje iwęzeł . Oznacza to, że możesz usunąć „plik”, ale i-węzeł nadal znajduje się w systemie plików, nietknięty, a wszystko, co naprawdę usunąłeś, to łącze.

Programy uniksowe cały czas używają tego sposobu myślenia o systemie plików, tworzą plik tymczasowy, otwierają go, usuwają nazwę. Twój plik nadal istnieje, ale jego nazwa jest dostępna dla innych i nikt inny nie może go zobaczyć.

Neil Williams
źródło
"cały czas"? Jakieś przykłady?
Mez
4
Zapytaj Google o „bezpieczny plik tymczasowy w systemie unix”, a znajdziesz wystarczająco dużo opisów tej techniki, aby pokazać, że jest ona dobrze znana i powszechnie używana. Chociaż nie mam żadnych konkretnych przykładów do podania, ośmielę się powiedzieć, że każda aplikacja świadoma bezpieczeństwa, która używa plików tymczasowych, robi to.
Dave Sherohman
26

Linux blokuje pliki. Jeśli spróbujesz nadpisać plik, który jest wykonywany, otrzymasz „ETXTBUSY” (plik tekstowy zajęty). Możesz jednak usunąć plik, a jądro usunie plik po usunięciu ostatniego odniesienia do niego. (Jeśli komputer nie został prawidłowo zamknięty, te pliki są przyczyną komunikatu „Usunięty i-węzeł miał zerowy czas d” podczas sprawdzania systemu plików, nie zostały one całkowicie usunięte, ponieważ działający proces miał do nich odniesienie, a teraz są).

Ma to kilka głównych zalet, możesz zaktualizować uruchomiony proces, usuwając plik wykonywalny, zastępując go, a następnie ponownie uruchamiając proces. Nawet init może zostać zaktualizowany w ten sposób, podmienić plik wykonywalny i wysłać mu sygnał, a sam zrestartuje exec () bez konieczności ponownego uruchamiania. (Zwykle jest to wykonywane automatycznie przez system zarządzania pakietami w ramach jego aktualizacji)

W systemie Windows zastąpienie używanego pliku wydaje się być dużym problemem, zazwyczaj wymagającym ponownego uruchomienia, aby upewnić się, że nie są uruchomione żadne procesy.

Mogą wystąpić pewne problemy, na przykład jeśli masz bardzo duży plik dziennika i usuniesz go, ale zapomnisz powiedzieć procesowi, który logował się do tego pliku, aby ponownie otworzył plik, będzie przechowywać odniesienie i będziesz się zastanawiać dlaczego na dysku nagle nie było dużo więcej wolnego miejsca.

Możesz również użyć tej sztuczki pod Linuksem dla plików tymczasowych. otwórz plik, usuń go, a następnie kontynuuj korzystanie z pliku. Po zakończeniu procesu (bez względu na przyczynę - nawet awaria zasilania), plik zostanie usunięty.

Programy takie jak lsof i fuser (lub po prostu szperające w / proc // fd) mogą pokazać, które procesy mają otwarte pliki, które nie mają już nazwy.


źródło
6

Myślę, że linux / unix nie używa tej samej mechaniki blokowania, ponieważ są zbudowane od podstaw jako system dla wielu użytkowników - co wymagałoby możliwości używania tego samego pliku przez wielu użytkowników, być może nawet do różnych celów.

Czy blokowanie ma zalety? Cóż, prawdopodobnie mogłoby to zmniejszyć liczbę wskaźników, którymi system operacyjny musiałby zarządzać, ale teraz kwota oszczędności jest znikoma. Największą zaletą blokowania, o której mogę pomyśleć, jest to: oszczędzasz pewną niejednoznaczność widoczną dla użytkownika. Jeśli użytkownik a uruchamia plik binarny, a użytkownik b go usuwa, wówczas rzeczywisty plik musi pozostać, dopóki proces użytkownika A nie zostanie zakończony. Jeśli jednak użytkownik B lub jakikolwiek inny użytkownik będzie szukał go w systemie plików, nie będzie w stanie go znaleźć - ale będzie on nadal zajmował miejsce. Nie jest to dla mnie wielkim problemem.

Myślę, że w dużej mierze jest to kwestia kompatybilności wstecznej z systemami plików Windows.

Eric Tuttleman
źródło
„Windows” w tym kontekście to wiersz Windows NT. Zostało to zaprojektowane jako następca dla wielu użytkowników systemu Windows 3.11 dla jednego użytkownika. Porównaj z Unixem, który jest następcą Multics dla jednego użytkownika.
MSalters
6

Myślę, że jesteś zbyt zdecydowany co do Windows. Zwykle nie przydziela miejsca wymiany dla części kodu pliku wykonywalnego. Zamiast tego blokuje pliki wykonywalne & DLL. Jeśli ponownie będą potrzebne odrzucone strony kodowe, po prostu zostaną ponownie załadowane. Ale z / SWAPRUN te strony są zachowywane w zamian. Służy do plików wykonywalnych na dyskach CD lub dyskach sieciowych. Dlatego system Windows nie musi blokować tych plików.

W przypadku platformy .NET spójrz na Shadow Copy .

MSalters
źródło
1

Decyzja o tym, czy wykonywany kod w pliku ma być zablokowany, czy nie, jest decyzją projektową, a MS po prostu zdecydowało się na blokadę, ponieważ ma to wyraźne zalety w praktyce: w ten sposób nie musisz wiedzieć, który kod, w jakiej wersji jest używany przez którą aplikację. Jest to poważny problem z domyślnym zachowaniem Linuksa, które jest po prostu ignorowane przez większość ludzi. Jeśli zastąpione zostaną biblioteki systemowe, nie będzie łatwo wiedzieć, które aplikacje używają kodu takich bibliotek. W większości przypadków najlepsze, co można uzyskać, to znajomość przez menedżera pakietów niektórych użytkowników tych bibliotek i ponowne ich uruchomienie. Ale to działa tylko w przypadku ogólnych i dobrze znanych rzeczy, takich jak może Postgres i jego biblioteki lub takie. Bardziej interesujące scenariusze dotyczą sytuacji, gdy tworzysz własną aplikację dla niektórych bibliotek innych firm, a te są zastępowane, ponieważ w większości przypadków menedżer pakietów po prostu nie zna Twojej aplikacji. I to' jest to nie tylko problem z natywnym kodem C lub tym podobnym, może się zdarzyć prawie ze wszystkim: po prostu użyj httpd z mod_perl i niektórymi bibliotekami Perla zainstalowanymi za pomocą menedżera pakietów i pozwól menedżerowi pakietów zaktualizować te biblioteki Perl z dowolnego powodu. Nie zrestartuje twojego httpd, po prostu dlatego, że nie zna zależności. Istnieje wiele przykładów takich jak ten, po prostu dlatego, że każdy plik może potencjalnie zawierać kod używany w pamięci przez dowolne środowisko uruchomieniowe, pomyśl o Javie, Pythonie i innych podobnych rzeczach.

Jest więc dobry powód, by sądzić, że domyślne blokowanie plików może być dobrym wyborem. Nie musisz jednak zgadzać się z tymi powodami.

Więc co zrobił SM? Po prostu stworzyli API, które daje aplikacji wywołującej szansę na podjęcie decyzji, czy pliki powinny być blokowane, czy nie, ale zdecydowali, że domyślną wartością tego API jest zapewnienie wyłącznej blokady dla pierwszej aplikacji wywołującej. Spójrz na interfejs API w okolicy CreateFile i jego dwShareModeargument. To jest powód, dla którego możesz nie być w stanie usunąć plików używanych przez jakąś aplikację, po prostu nie dba o Twój przypadek użycia, używał wartości domyślnych i dlatego ma wyłączną blokadę pliku przez system Windows.

Proszę nie wierz w to, że ludzie mówią ci coś o systemie Windows, który nie korzysta z liczenia referencji na UCHWYTACH lub nie obsługuje Hardlinks lub podobnych, to jest całkowicie błędne. Prawie każde API używające HANDLEs dokumentuje swoje zachowanie dotyczące liczenia referencji i możesz łatwo przeczytać w prawie każdym artykule na temat NTFS, który faktycznie obsługuje Hardlinks i zawsze to robił. Od systemu Windows Vista obsługuje również łącza symboliczne, a obsługa łączy twardych została ulepszona poprzez udostępnienie interfejsów API do odczytu wszystkich tych dla danego pliku itp.

Dodatkowo możesz po prostu rzucić okiem na struktury używane do opisu pliku np. W Ext4 w porównaniu do tych w NTFS , które mają wiele wspólnego. Oba działają z koncepcją zakresów, która oddziela dane od atrybutów, takich jak nazwa pliku, a i-węzły to po prostu inna nazwa dla starszej, ale podobnej koncepcji. Nawet Wikipedia wymienia oba systemy plików w swoim artykule .

Jest naprawdę dużo FUD wokół blokowania plików w systemie Windows w porównaniu z innymi systemami operacyjnymi w sieci, podobnie jak w przypadku defragmentacji. Niektóre z tych FUD można wykluczyć, po prostu czytając trochę w Wikipedii .

Thorsten Schöning
źródło
Wątpliwości dotyczące zarządzania wersjami współdzielonych zależności są nieistotne. Musisz poradzić sobie z tymi problemami, nawet jeśli ich aktualizacja wymaga ponownego uruchomienia. W systemie Windows ma nawet nazwę: piekło DLL. Co więcej, opisywane przez ciebie zachowania w czasie wykonywania są w pełni obsługiwane przez przypadek Linuksa, w którym plik jest już załadowany do pamięci i pozostaje on dostępny; aplikacja będzie działać ze starą wersją do momentu ponownego uruchomienia, tak jak wtedy, gdy system Windows wymusza ponowne uruchomienie w celu odblokowania pliku. Nie ma żadnej przewagi na tym froncie.
jpmc26
DLL Hell oczywiście całkowicie mija się z celem i nie mamy już lat 90-tych, po prostu czytaj o takich rzeczach WinSxSi innych rzeczach. Co więcej, nie chodzi o ładowanie rzeczy do pamięci i przechowywanie ich tam, Windows robi dokładnie to, jeśli to konieczne, chodzi o to, aby wiedzieć i decydować, czy pliki powinny zostać zastąpione, czy nie, i kto jest za to odpowiedzialny. Windows-API po prostu pozwala zdecydować pierwszemu użytkownikowi pliku i to ma sens.
Thorsten Schöning
Ale o to mi chodzi: decyzja, której wersji biblioteki DLL użyć, jest częścią piekła DLL. Nazwij to „piekłem zależności”, jeśli chcesz odróżnić niektóre stare idiosynkratyczne zachowania systemu Windows. Niezależnie od tego domyślne blokowanie plików wykonywalnych nie pomaga w zarządzaniu współdzielonymi zależnościami. W ogóle. Elementy zależne od określonego pliku mogą nawet nie działać podczas próby jego aktualizacji; nie ma dodatkowego bezpieczeństwa. Istnieją dwie opcje ze współdzielonymi zależnościami: bezpłatna dla wszystkich, która grozi zepsuciem się rzeczy podczas próby jej uruchomienia lub menedżer pakietów, który może uniemożliwić zainstalowanie rzeczy.
jpmc26
W tym pytaniu nie chodzi o podjęcie decyzji, którego pliku EXE lub DLL w ogóle użyć, chodzi o to, co dzieje się później domyślnie i dlaczego. Dyskutujesz na zupełnie inny temat. Blokowanie jest używane po podjęciu decyzji, który plik EXE lub DLL ma zostać wykonany, aby uzyskać pewien poziom dodatkowej kontroli od pierwszego użytkownika, którym jest sam system Windows w tym przykładzie, i poinformować innych o tej kontroli. I nie pozwalanie „innym” na usuwanie lub zapisywanie plików, których z jakiegoś powodu Windows potrzebuje i dlatego je blokuje, oczywiście jest to mechanizm dodatkowej koordynacji.
Thorsten Schöning
1
Niektóre pliki EXE lub DLL najprawdopodobniej i tak nie są „w pamięci”, ale są do nich domyślnie mapowane. Mapowanie wymaga, aby zawartość pliku była dostępna, więc arbitralne zastąpienie jej jest domyślnie uważane za niebezpieczne i należy wiedzieć, co robi. Co oczywiście nie ma miejsca, jeśli ktoś jest zaskoczony zablokowanymi plikami EXE lub DLL. OTOH, wszystkie inne pliki są blokowane domyślnie, niekoniecznie, więc aplikacje mogą decydować, czy zezwalają na zapisywanie lub usuwanie operacji, w zależności od ich przypadku użycia. Twórcy aplikacji powinni wiedzieć lepiej niż zwykli użytkownicy, jak używają swoich plików i które operacje są bezpieczne.
Thorsten Schöning
0

Warianty NT mają

Otwórz pliki

polecenie, które pokaże, które procesy mają uchwyty do których plików. Wymaga to jednak włączenia globalnej flagi systemu „zachowaj listę obiektów”

openfiles / local /?

mówi, jak to zrobić, a także, że powoduje to spadek wydajności.

wydający
źródło
0

Pliki wykonywalne są stopniowo mapowane do pamięci podczas uruchamiania. Oznacza to, że części pliku wykonywalnego są ładowane w razie potrzeby. Jeśli plik zostanie wymieniony przed mapowaniem wszystkich sekcji, może to spowodować poważną niestabilność.

Ken Netherland
źródło