Adresáře /tmp
a /usr/tmp
(později /var/tmp
) bývala smetištěm všeho a všech. Jediný ochranný mechanismus pro soubory v těchto adresářích je lepivý bit, který omezuje mazání nebo přejmenování souborů na jejich vlastníky. Jak upozornil marcelm v komentáři, v zásadě nic nebrání někomu vytvářet soubory s názvy, které používají služby (například nginx.pid
nebo sshd.pid
). (V praxi by však spouštěcí skripty mohly takové falešné soubory nejprve odstranit.)
/run
byl vytvořen pro neperzistentní runtime data služeb s dlouhou životností, jako jsou zámky, sockety, pid soubory a podobně. Protože do něj nelze zapisovat pro veřejnost, chrání data za běhu služby před nepořádkem v /tmp
a práce, které tam uklízí. Skutečně:Dvě distribuce, které provozuji (bez slovní hříčky), mají oprávnění 755 na /run
, zatímco /tmp
a /var/tmp
(a /dev/shm
na to přijde) mají oprávnění 1777.
/tmp
je místo pro vytváření dočasných souborů a adresářů. Není použitelný pro ukládání „dobře známých jmen“ (tj. jmen, která by si jiný proces mohl být vědom, aniž byste mu museli jméno nějak sdělit), protože nikdo nemá vlastnictví nad jmenným prostorem; kdokoli tam může vytvářet soubory. Jako takový jej obecně používáte, když máte obslužný program, který potřebuje jako vstup nebo výstup soubor (tj. ne roura apod.), kde bude fungovat jakýkoli (náhodně vygenerovaný) název, pokud název předáte.
Historicky některé věci (jako X) tuto zásadu porušovaly a dávaly známá jména (jako .X11-unix
) v /tmp
. To je samozřejmě chybné a umožňuje každému uživateli provést službu, která to potřebuje, jednoduše tím, že nejprve vytvoří soubor s požadovaným názvem. Takové věci patří pod /run
(nebo ekvivalentně /var/run
pokud se nepřihlásíte k revizionismu Freedesktop.org). Samozřejmě ještě lepší by bylo opravit je tak, aby nepoužívaly známá jména v globálním jmenném prostoru, ale místo toho předávaly cestu.
Není důvod mít oba /run i /tmp
Myslím, že máte pravdu. /tmp
je v podstatě zastaralý, nyní máme /run
. Pokud je váš program schopen tak učinit (což vyžaduje, aby byl instalován jako privilegovanou operaci), pak byste dnes použili podadresář /run
. Je to z bezpečnostních důvodů.
Např. tiskový démon CUPS se nespouští jako uživatel root, ale obvykle se instaluje z balíčku OS. Balíček nainstaluje /usr/lib/tmpfiles.d/cups.conf
a systemd-tmpfiles
vytvoří adresář, ke kterému má přístup. Protože adresář je pod /run
, na rozdíl od /tmp
si jméno nemohl nárokovat se zlými úmysly neprivilegovaný uživatel který je světově zapisovatelný.
"Neprivilegované programy", které nemohou používat /run
přímo
Skutečný rozdíl je v tom, zda váš program spouští libovolný neprivilegovaný uživatel pod svým vlastním ID uživatele. Ale stále obecně nechcete používat /tmp
, protože k němu mohou přistupovat jiní neprivilegovaní uživatelé. Raději byste použili $XDG_RUNTIME_DIR
. Obvykle je to implementováno jako /run/user/$(id -u)
- takže je to náhodou podadresář /run
také. Místo však není zaručeno; programy by měly vždy používat proměnnou prostředí.
/tmp
by bylo užitečné pouze pro ad-hoc spolupráci mezi různými neprivilegovanými uživateli v systému. Takové ad-hoc systémy jsou zranitelné vůči uživateli se zlými úmysly, který odmítá spolupracovat a kazí věci všem :). Jedním příkladem mohou být neprivilegovaní uživatelé, kteří se rozhodnou spustit verzi talk
démona pomocí unixového socketu.
Původní informace od Lennarta Poetteringa
Poznámka:Poetteringův kontrolní seznam níže tvrdil, že /tmp
by bylo užitečné pro "malé soubory", zatímco /run
by měl být používán pouze pro "komunikační primitiva". Myslím, že ani toto rozlišení není pravdivé. Plakát pro /run
je udev
a jsem si docela jistý /run/udev
zahrnuje interní databáze. Jakmile budete mít /run
adresář, nemyslím si, že by se někdo chtěl řídit nárokovaným rozlišením a vytvořit další adresáře, aby zahltil /tmp
. V praxi tedy používáme pouze /run
v dnešní době.
Použití světově zapisovatelných sdílených jmenných prostorů [jako /tmp] pro komunikační účely bylo vždy problematické, protože k navázání komunikace potřebujete stabilní jména, ale stabilní jména otevírají dveře DoS útokům. To lze částečně opravit vytvořením chráněných adresářů pro určité služby během časného spouštění (jako to děláme pro X11), ale problém to řeší pouze částečně, protože to funguje správně pouze v případě, že po každé instalaci balíčku následuje restart.
...
Další funkce Fedory (pro Fedoru 17) změnila sémantiku /tmp pro mnoho systémových služeb, aby byly bezpečnější, izolováním jmenných prostorů /tmp různých služeb
...
Protože /tmp již není nutně sdílený jmenný prostor, je obecně nevhodný jako umístění pro komunikační primitiva.
...
[/run] je zaručeno, že je tmpfs, a proto se automaticky vyprázdní při bootování. Kromě toho se neprovádí žádné automatické čištění.
...
Zde je hrubý průvodce, jak vám (vývojáři aplikací pro Linux) doporučujeme vybrat správný adresář, který chcete použít:
- Potřebujete místo pro umístění soketu (nebo jiného komunikačního primitiva) a váš kód běží privilegovaně:použijte podadresář pod /run. (Nebo pod /var/run pro další kompatibilitu.)
- Potřebujete místo pro umístění soketu (nebo jiného primitiva komunikace) a váš kód běží bez oprávnění:použijte podadresář pod $XDG_RUNTIME_DIR.
- Potřebujete místo, kam umístit svá větší stahování a probíhající stahování a spustit je bez oprávnění:použijte $XDG_DOWNLOAD_DIR.
- Potřebujete místo pro uložení souborů mezipaměti, které by mělo být trvalé a spouštět bez oprávnění:použijte $XDG_CACHE_HOME.
- Nic z výše uvedeného neplatí a je třeba umístit malý soubor, který nepotřebuje žádnou perzistenci:použijte $TMPDIR s nouzovým nastavením na /tmp. A použijte mkstemp() a mkdtemp() a nic domácího.
- Jinak použijte $TMPDIR se záložním nastavením na /var/tmp. Použijte také mkstemp()/mkdtemp().
Upozorňujeme, že výše uvedená pravidla jsme pouze navrhli. Tato pravidla berou v úvahu vše, co o tomto tématu víme, a vyhýbají se problémům se současnými a budoucími distribucemi, pokud je můžeme vidět. Zvažte prosím aktualizaci svých projektů tak, aby dodržovaly tato pravidla, a mějte je na paměti, pokud budete psát nový kód.
Jedna věc, kterou bychom rádi zdůraznili, je, že /tmp a /var/tmp ve skutečnosti často nejsou tou správnou volbou pro váš případ použití. Existují platná použití těchto adresářů, ale dost často může být lepším místem jiný adresář. Takže buďte opatrní, zvažte další možnosti, ale pokud se rozhodnete pro /tmp nebo /var/tmp, pak se ujistěte, že používáte mkstemp()/mkdtemp().
Tak trochu nám projde starý Špatně jsem si přečetl /tmp
socket používaný systémem X window, jak je popsáno výše.tmpfiles.d/x11.conf
. Spíš to vypadá, že to spoléhá na spolupráci :). Předpokládám, že kód byl auditován, takže odmítnutí služby je to nejhorší, co se může stát.