Come funzionano i permessi dei file Unix: leggere 755 senza tirare a indovinare
Pubblicato il 24/04/2026 · 7 min di lettura · Strumenti per sviluppatori
Daniel Okonkwo — Sviluppatore front-end e redattore Tech presso OneKitly
Performance web · Formati di file
Verificato su 2 fonti
Un modo di permessi Unix è fatto di tre cifre ottali: una per il proprietario del file, una per il suo gruppo e una per tutti gli altri. All'interno di una cifra la lettura vale 4, la scrittura 2 e l'esecuzione 1, e si sommano: 7 è rwx, 6 è rw-, 5 è r-x, 4 è r--. Quindi 755 è rwxr-xr-x: il proprietario può leggere, scrivere ed eseguire, tutti gli altri possono leggere ed eseguire. Su un file normale il bit di esecuzione consente al kernel di lanciarlo. Su una directory significa tutt'altro: concede il diritto di attraversare la directory, cioè di raggiungere una voce per nome. La lettura su una directory permette solo di elencare i nomi; senza il bit di esecuzione non puoi aprire, interrogare né entrare in nessuna. Una quarta cifra opzionale davanti porta setuid (4000), setgid (2000) e lo sticky bit (1000), ed è per questo che /tmp è 1777.
Lettura 4, scrittura 2, esecuzione 1, e ciascuna delle tre cifre descrive un soggetto diverso. Ciò che quasi tutte le spiegazioni sbagliano è cosa fa il bit di esecuzione su una directory: concede l'attraversamento, non il diritto di eseguire qualcosa.
Tre cifre, tre soggetti, e solo uno si applica
Nell'output di `ls -l` il primo carattere indica il tipo — un trattino per un file normale, d per una directory, l per un collegamento simbolico — e i nove successivi sono tre gruppi di tre: proprietario, gruppo, altri. Quel che sorprende è che non si sommano. Il kernel prende la prima classe a cui appartieni e si ferma lì. Se possiedi un file con modo 477 ottieni r-- e nulla di più, anche se i bit di gruppo e altri sono spalancati: la classe proprietario ha corrisposto per prima e il resto non viene mai consultato.
Ci sono due modi di scrivere una modifica e non sono equivalenti. L'ottale è assoluto: `chmod 644 notes.txt` fissa l'intero modo e cancella ciò che c'era prima. Il simbolico è relativo: `chmod u+x script.sh` aggiunge un bit e lascia intatti gli altri otto. In uno script di deploy vuoi quasi sempre la forma ottale, perché produce lo stesso stato finale qualunque fosse l'aspetto del file all'arrivo.
Su una directory il bit di esecuzione è un diritto del tutto diverso
Nulla viene mai eseguito per aver dato il bit x a una directory. Su una directory quel bit è il permesso di ricerca: consente a un processo di risolvere un nome al suo interno e raggiungere ciò che sta dietro. La distinzione si vede facilmente. Metti una directory a 400 e `ls` stamperà volentieri i nomi che contiene, ma ogni interrogazione fallisce e `cat dir/file` viene rifiutato: vedi le etichette e non tocchi nulla. Mettila a 100 e succede l'opposto: non puoi elencare niente, ma se conosci già il percorso esatto apri il file. Questa asimmetria spiega perché una home a 711 funziona: gli altri raggiungono ~/public_html senza poter enumerare il resto.
La stessa logica spiega un risultato che sembra un bug. Eliminare un file non è una modifica del file: è una modifica della directory che lo elenca. Quindi il permesso che decide se un file può essere rimosso è scrittura più esecuzione sulla directory che lo contiene, e il modo del file stesso è irrilevante. Un file a 444 dentro una directory a 777 può essere cancellato da chiunque sulla macchina. È esattamente il buco che lo sticky bit è stato inventato per tappare, ed è per questo che /tmp è 1777 e non 0777.
La quarta cifra, e perché umask non è un permesso
Tre bit speciali stanno in una cifra iniziale opzionale. Setuid è 4000: su un binario eseguibile lo fa girare con l'identità del proprietario, ed è così che passwd modifica un file che tu non potresti. Su Linux viene ignorato in silenzio sugli script interpretati e non ha alcun significato su una directory. Setgid è 2000: su un binario fa lo stesso per il gruppo, e su una directory fa qualcosa di molto più utile — le nuove voci ereditano il gruppo della directory invece di quello di chi le crea, e le nuove sottodirectory ereditano anche il bit setgid, il modo standard per tenere coerente un albero di progetto condiviso. Lo sticky è 1000: su una directory riserva eliminazione e rinomina al proprietario della voce, al proprietario della directory o a root.
L'umask è il pezzo che si inverte più spesso. Non è il permesso che ricevono i file nuovi: è una maschera di bit da azzerare rispetto a quanto ha chiesto il programma che li crea. I programmi chiedono 666 per un file e 777 per una directory, e ogni bit impostato nell'umask viene spento. Con il consueto umask 022 ottieni quindi 644 per i file e 755 per le directory. E azzera invece di sottrarre: umask 023 produce ancora 644 su un file nuovo, non 643, perché il file non ha mai chiesto il bit di esecuzione e non c'è nulla da togliere. Un parente stretto: `chmod +x` senza lettera di classe non equivale a `chmod a+x`, perché la forma nuda rispetta anch'essa il tuo umask — sotto umask 077 concede l'esecuzione al solo proprietario.
| Cifra | Simbolico | Su un file | Su una directory |
|---|---|---|---|
| 0 | --- | Nessun accesso | Nessun accesso |
| 1 | --x | Il kernel può lanciarlo | Solo attraversamento: raggiungere una voce di cui conosci già il nome esatto, senza mai elencare il contenuto |
| 2 | -w- | Può essere modificato o troncato | Inutile da solo: creare o eliminare una voce richiede anche il bit di esecuzione |
| 3 | -wx | Modificare ed eseguire, ma non leggere | Creare, eliminare e rinominare voci senza poterle elencare: una cassetta di deposito |
| 4 | r-- | Può essere letto | Elencare solo i nomi: ogni tentativo di interrogare o aprire una voce viene rifiutato |
| 5 | r-x | Leggere ed eseguire | Elencare e attraversare: l'impostazione normale per una directory che altri devono sfogliare |
| 6 | rw- | Leggere e modificare: il valore predefinito di un file nuovo | Elencare i nomi, non raggiungere nulla e non creare nulla: scrittura senza esecuzione è peso morto |
| 7 | rwx | Leggere, modificare ed eseguire | Controllo completo: elencare, attraversare, creare, rinominare ed eliminare voci |
Domande frequenti
- Perché chmod 777 è la soluzione sbagliata?
- Dà accesso in scrittura a ogni account della macchina, compresa l'identità con cui gira il tuo server web o un processo compromesso, e il codice scrivibile da tutti è codice che chiunque può sostituire. Di solito manca anche la causa reale, che più spesso è una proprietà sbagliata o un bit di esecuzione assente su una directory superiore, non un permesso troppo stretto. Alcuni programmi si rifiutano del tutto: OpenSSH ignora una chiave privata o un file authorized_keys scrivibile dal gruppo o da tutti.
- chmod 755 rende eseguibile uno script?
- Concede il permesso di provarci, che non equivale a farlo funzionare. Un file di testo ha bisogno anche di una riga shebang che nomini un interprete esistente, altrimenti il kernel non ha a chi consegnarlo. Altre due cose battono del tutto il modo: un filesystem montato con l'opzione noexec rifiuta di eseguire qualsiasi cosa, qualunque cosa dicano i bit, e ogni directory lungo il percorso verso il file ha bisogno del proprio bit di esecuzione perché il file sia anche solo raggiungibile.
- Perché qualcuno può eliminare un file che ho messo in sola lettura?
- Perché l'eliminazione è una modifica alla directory, non al file. Il kernel controlla scrittura ed esecuzione sulla directory che contiene il nome e non guarda mai il modo del file. Per impedirlo, restringi la directory oppure impostale lo sticky bit, che limita eliminazione e rinomina al proprietario della voce, al proprietario della directory e a root — il motivo per cui una /tmp condivisa è 1777.
Articoli che potrebbero interessarti
Tutte le guide →Strumenti correlati
Fonti
Hai notato un errore in questo articolo?