Le directory /tmp
e /usr/tmp
(successivamente /var/tmp
) era la discarica di tutto e di tutti. L'unico meccanismo di protezione per i file in queste directory è lo sticky bit che limita l'eliminazione o la ridenominazione dei file ai rispettivi proprietari. Come ha sottolineato Marcelm in un commento, in linea di principio non c'è nulla che impedisca a qualcuno di creare file con nomi utilizzati dai servizi (come nginx.pid
o sshd.pid
). (In pratica, però, gli script di avvio potrebbero rimuovere prima tali file fasulli.)
/run
è stato stabilito per i dati di runtime non persistenti di servizi di lunga durata come blocchi, socket, file pid e simili. Dal momento che non è scrivibile per il pubblico, protegge i dati di runtime del servizio dal caos in /tmp
e lavori che puliscono lì. In effetti:due distribuzioni che eseguo (nessun gioco di parole) hanno i permessi 755 su /run
, mentre /tmp
e /var/tmp
(e /dev/shm
del resto) hanno i permessi 1777.
/tmp
è la posizione per la creazione di directory e file temporanei. Non è utilizzabile per memorizzare "nomi noti" (ovvero nomi di cui un altro processo potrebbe essere a conoscenza senza che tu debba comunicargli il nome in qualche modo) perché nessuno ha la proprietà dello spazio dei nomi; chiunque può creare file lì. In quanto tale, generalmente lo usi quando hai un'utilità che necessita di un file (cioè non una pipe o simili) come input o output, dove qualsiasi nome (generato casualmente) funzionerà fintanto che passi il nome.
Storicamente, alcune cose (come X) violavano questo principio e mettevano nomi noti (come .X11-unix
) in /tmp
. Questo è ovviamente difettoso e consente a qualsiasi utente di DoS del servizio che necessita di farlo semplicemente correndo per creare prima un file con il nome desiderato. Queste cose appartengono a /run
(o equivalentemente /var/run
se non ti iscrivi al revisionismo di Freedesktop.org). Ovviamente sarebbe ancora meglio correggerli in modo che non usino nomi noti in uno spazio dei nomi globale, ma passino invece un percorso.
Non c'è motivo di avere sia /run che /tmp
Penso tu abbia ragione. /tmp
è essenzialmente deprecato ora che abbiamo /run
. Se il tuo programma è in grado di farlo (il che richiede che sia stato installato come operazione privilegiata), oggigiorno useresti una sottodirectory di /run
. Questo è per motivi di sicurezza.
Per esempio. il demone di stampa CUPS non viene eseguito come root, ma viene generalmente installato da un pacchetto del sistema operativo. Il pacchetto installa /usr/lib/tmpfiles.d/cups.conf
e systemd-tmpfiles
crea una directory a cui può accedere. Poiché la directory è sotto /run
, il nome non può essere stato rivendicato intenzionalmente da un utente senza privilegi, a differenza di /tmp
che è scrivibile in tutto il mondo.
"Programmi non privilegiati" che non possono utilizzare /run
direttamente
La vera distinzione è se il tuo programma viene eseguito da un utente arbitrario senza privilegi, con il proprio ID utente. Ma generalmente non vuoi usare /tmp
, perché vi possono accedere altri utenti non privilegiati. Preferiresti usare $XDG_RUNTIME_DIR
. Tipicamente questo è implementato come /run/user/$(id -u)
- quindi sembra essere una sottodirectory di /run
anche. La posizione non è garantita però; i programmi dovrebbero sempre usare la variabile d'ambiente.
/tmp
sarebbe utile solo per la cooperazione ad hoc tra diversi utenti non privilegiati sul sistema. Tali sistemi ad-hoc sono vulnerabili a un utente malintenzionato che si rifiuta di cooperare e rovinare le cose per tutti :). Un esempio potrebbero essere gli utenti senza privilegi che decidono di eseguire una versione del talk
demone, utilizzando un socket unix.
Informazioni originali da Lennart Poettering
Nota, l'elenco di controllo di Poettering riportato di seguito affermava che /tmp
sarebbe utile per "piccoli file", mentre /run
dovrebbe essere usato solo per "primitivi di comunicazione". Non credo che sia vera neanche questa distinzione. Il ragazzo poster di /run
è udev
, e sono abbastanza sicuro /run/udev
include database interni . Una volta ottenuto un /run
directory, non credo che qualcuno voglia seguire la distinzione dichiarata e crearne un'altra directory, per ingombrare /tmp
. Quindi in pratica usiamo solo /run
al giorno d'oggi.
L'utilizzo di spazi dei nomi condivisi scrivibili in tutto il mondo [come /tmp] per scopi di comunicazione è sempre stato problematico, poiché per stabilire la comunicazione sono necessari nomi stabili, ma i nomi stabili aprono le porte agli attacchi DoS. Questo può essere corretto parzialmente, stabilendo directory protette per app per determinati servizi durante l'avvio anticipato (come facciamo per X11), ma questo risolve il problema solo parzialmente, poiché funziona correttamente solo se ogni installazione di pacchetto è seguita da un riavvio.
...
Un'altra caratteristica di Fedora (per Fedora 17) ha cambiato la semantica di /tmp per molti servizi di sistema per renderli più sicuri, isolando i namespace /tmp dei vari servizi
...
Poiché /tmp non è più necessariamente uno spazio dei nomi condiviso, generalmente non è adatto come posizione per le primitive di comunicazione.
...
[/run] è garantito per essere un tmpfs e quindi viene scaricato automaticamente all'avvio. Oltre a ciò, non viene eseguita alcuna pulizia automatica.
...
Ecco una guida approssimativa su come suggeriamo a te (uno sviluppatore di applicazioni Linux) di scegliere la directory giusta da usare:
- Hai bisogno di un posto dove mettere il tuo socket (o altra primitiva di comunicazione) e il tuo codice viene eseguito con privilegi:usa una sottodirectory sotto /run. (O sotto /var/run per maggiore compatibilità.)
- Hai bisogno di un posto dove mettere il tuo socket (o altra primitiva di comunicazione) e il tuo codice viene eseguito senza privilegi:usa una sottodirectory sotto $XDG_RUNTIME_DIR.
- Hai bisogno di un posto dove mettere i tuoi download e download più grandi in corso ed eseguirli senza privilegi:usa $XDG_DOWNLOAD_DIR.
- Hai bisogno di un posto dove mettere i file di cache che dovrebbero essere persistenti ed essere eseguiti senza privilegi:usa $XDG_CACHE_HOME.
- Niente di quanto sopra si applica e devi inserire un piccolo file che non ha bisogno di persistenza:usa $TMPDIR con un fallback su /tmp. E usa mkstemp(), e mkdtemp() e niente di homegrown.
- Altrimenti usa $TMPDIR con un fallback su /var/tmp. Usa anche mkstemp()/mkdtemp().
Si noti che queste regole di cui sopra sono solo suggerite da noi. Queste regole tengono conto di tutto ciò che sappiamo su questo argomento ed evitano problemi con le distribuzioni attuali e future, per quanto possiamo vederle. Considera l'idea di aggiornare i tuoi progetti per seguire queste regole e tienile a mente se scrivi un nuovo codice.
Una cosa che vorremmo sottolineare è che /tmp e /var/tmp il più delle volte non sono in realtà la scelta giusta per il tuo caso d'uso. Esistono usi validi di queste directory, ma molto spesso un'altra directory potrebbe effettivamente essere il posto migliore. Quindi, fai attenzione, considera le altre opzioni, ma se scegli /tmp o /var/tmp assicurati almeno di usare mkstemp()/mkdtemp().
In un certo senso ce la caviamo con l'eredità Ho letto male /tmp
socket utilizzato dal sistema X Window, come descritto sopra.tmpfiles.d/x11.conf
. Sembra più che si basi sulla cooperazione :). Presumo che il codice sia stato verificato, in modo tale che il denial of service sia il peggio che possa accadere.