Esercizio - Permessi dei file con stat e chmod (laboratorio 9)
In questa pagina 3
Testo (laboratorio 9 del corso di Sistemi Operativi, Ing. Informatica UniPD).
- Task 1. Creare con un editor un file di testo
abcde.txtcon poche parole. Controllare i permessi conls -l(si ottiene qualcosa come-rw-r--r-- 1 debianos debianos 20 May 8 15:29 abcde.txt). Conchmod 444 abcde.txtrenderlo di sola lettura per tutti (anche per il proprietario), riaprirlo con l'editor e verificare che non si può salvare. Provare altre combinazioni. - Task 2. Il programma
permissions.clegge il nome di un file, ne stampa i permessi e li cambia constat()echmod()in lettura e scrittura per il proprietario e in sola lettura per gruppo e altri. Modificarlo in modo che il file diventi leggibile e scrivibile solo dal proprietario e dal suo gruppo; consegnarepermissions_new.c.
Teoria: File system - interfaccia, directory e implementazioneUn file è uno spazio di indirizzi logici contigui con attributi (nome, identificatore, tipo, posizione, dimensione, protezione, date) e operazioni (create, read, write, seek, delete, truncate, open, close); il sistema tiene una tabella dei file aperti di sistema e una per processo; l'accesso è sequenziale o diretto; le directory si organizzano a livello singolo, a due livelli, ad albero, a grafo aciclico (hard link e link simbolici) o a grafo generale; i permessi UNIX rwx per proprietario, gruppo e altri (chmod 754); il file system è a strati (file system logico, organizzazione dei file, file system di base, controllo dell'I/O), con strutture su disco (boot block, superblock, directory, FCB o inode) e in memoria; i blocchi si allocano in modo contiguo (extent), concatenato (FAT) o indicizzato (inode con puntatori diretti e indiretti, ext4 con extent); lo spazio libero con bitmap, lista, raggruppamento o conteggio; mount, VFS, file system distribuiti (NFS) e semantiche di consistenza.File system - interfaccia, directory e implementazione →, Sicurezza e protezione nei sistemi operativiLe minacce all'accesso sono gli intrusi (masquerader, misfeasor, clandestine user) e il software malevolo (parassita: virus, logic bomb, backdoor; indipendente: worm, bot); contromisure: sistemi di rilevamento delle intrusioni (IDS, host o network, con sensori, analizzatori e interfaccia), autenticazione (identificazione + verifica con qualcosa che si sa, si ha, si è, si fa) e controllo degli accessi (permessi, sudo, SELinux, ACL, auditing, firewall); il buffer overflow scrive oltre un buffer nello stack e può sovrascrivere variabili o l'indirizzo di ritorno (code injection, shellcode); difese a compilazione (linguaggi sicuri, codice sicuro, librerie, stack protection con canarino) e a esecuzione (NX bit, ASLR, guard pages); sulla rete ci sono sniffing, spoofing e man-in-the-middle, e la crittografia (simmetrica e asimmetrica, RSA) limita mittenti e destinatari; la tolleranza ai guasti usa ridondanza (spaziale, temporale, informativa) e si misura con R(t), MTTF, MTTR e disponibilità.Sicurezza e protezione nei sistemi operativi →.
Task 1: come si leggono i permessi
ls -l mostra dieci caratteri:
-rw-r--r-- 1 debianos debianos 20 May 8 15:29 abcde.txt- il primo carattere è il tipo (
-file normale,ddirectory,llink simbolico); - i nove successivi sono tre gruppi di tre: proprietario (
rw-), gruppo (r--), altri (r--); - in ogni gruppo:
r= lettura (4),w= scrittura (2),x= esecuzione (1);-= permesso assente.
I tre numeri ottali si ottengono sommando: rw- , r-- : i permessi sono 644.
| numero | binario | permessi |
|---|---|---|
| 7 | 111 | rwx |
| 6 | 110 | rw- |
| 5 | 101 | r-x |
| 4 | 100 | r-- |
| 0 | 000 | --- |
chmod 444 abcde.txt dà r--r--r--: nessuno può scrivere, neanche il proprietario. L'editor, aprendo il file, lo segnala di sola lettura e il salvataggio fallisce (il proprietario deve prima fare chmod u+w oppure chmod 644). Altre combinazioni: chmod 754 abc (rwxr-xr--: il proprietario fa tutto, il gruppo legge ed esegue, gli altri leggono); chmod 600 (solo il proprietario); chmod g+w aggiunge la scrittura al gruppo. Per cambiare il gruppo: sudo groupadd team, poi sudo chgrp team abc.
Un esempio delle slide: un file con permessi rwxr-xr-- può essere letto, scritto ed eseguito dal proprietario, letto ed eseguito dal gruppo, solo letto da tutti gli altri.
Task 2: il programma
Il programma del corso:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
int main() {
char filename[100];
struct stat fileStat;
printf("Enter the filename: ");
scanf("%s", filename); /* nome letto dalla tastiera */
stat(filename, &fileStat); /* permessi attuali */
printf("Current file permissions: %o\n", fileStat.st_mode & 0777);
chmod(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* rw-r--r-- */
stat(filename, &fileStat);
printf("Updated file permissions: %o\n", fileStat.st_mode & 0777);
return 0;
}stat(nome, &st)riempie la strutturastruct statcon le informazioni del file; il campost_modecontiene tipo e permessi:st_mode & 0777isola i 9 bit dei permessi (si stampano in ottale con%o).chmod(nome, modo)imposta i permessi:modoè l'OR di costanti:S_IRUSR(lettura proprietario),S_IWUSR,S_IXUSR;S_IRGRP,S_IWGRP,S_IXGRP(gruppo);S_IROTH,S_IWOTH,S_IXOTH(altri).
La soluzione richiesta: lettura e scrittura al proprietario e al gruppo, niente agli altri, cioè rw-rw---- . Basta cambiare il modo: S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP. Versione completa e più robusta (nome del file come argomento, controllo degli errori):
/* permessi.c - legge i permessi di un file e li porta a rw-rw---- (660).
* Compilare: gcc -Wall -Wextra -o permessi permessi.c
* Usare: ./permessi abcde.txt
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
int main(int argc, char *argv[]) {
struct stat st;
if (argc != 2) { fprintf(stderr, "uso: %s file\n", argv[0]); return EXIT_FAILURE; }
if (stat(argv[1], &st) < 0) { perror("stat"); return EXIT_FAILURE; }
printf("permessi attuali: %03o\n", (unsigned)(st.st_mode & 0777));
/* proprietario rw-, gruppo rw-, altri --- */
mode_t nuovi = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
if (chmod(argv[1], nuovi) < 0) { perror("chmod"); return EXIT_FAILURE; }
if (stat(argv[1], &st) < 0) { perror("stat"); return EXIT_FAILURE; }
printf("permessi nuovi: %03o\n", (unsigned)(st.st_mode & 0777));
return EXIT_SUCCESS;
}Compilato con zig cc per Linux, senza avvisi; non eseguito. Con un file di permessi iniziali 644 l'uscita attesa è permessi attuali: 644 e permessi nuovi: 660.
Differenze rispetto al programma del corso:
- il nome arriva da
argv[1]e non dascanf("%s", filename), che con un buffer da 100 byte è un buffer overflow se si scrive un nome più lungo (Sicurezza e protezione nei sistemi operativiLe minacce all'accesso sono gli intrusi (masquerader, misfeasor, clandestine user) e il software malevolo (parassita: virus, logic bomb, backdoor; indipendente: worm, bot); contromisure: sistemi di rilevamento delle intrusioni (IDS, host o network, con sensori, analizzatori e interfaccia), autenticazione (identificazione + verifica con qualcosa che si sa, si ha, si è, si fa) e controllo degli accessi (permessi, sudo, SELinux, ACL, auditing, firewall); il buffer overflow scrive oltre un buffer nello stack e può sovrascrivere variabili o l'indirizzo di ritorno (code injection, shellcode); difese a compilazione (linguaggi sicuri, codice sicuro, librerie, stack protection con canarino) e a esecuzione (NX bit, ASLR, guard pages); sulla rete ci sono sniffing, spoofing e man-in-the-middle, e la crittografia (simmetrica e asimmetrica, RSA) limita mittenti e destinatari; la tolleranza ai guasti usa ridondanza (spaziale, temporale, informativa) e si misura con R(t), MTTF, MTTR e disponibilità.Sicurezza e protezione nei sistemi operativi →); - si controlla il valore di ritorno di
statechmod(se il file non esiste,statrestituisce-1estnon è inizializzata); %03ostampa sempre 3 cifre ottali.
Solo il proprietario del file (o l'amministratore) può cambiare i permessi con chmod.
Errori tipici
- Scambiare l'ordine: il primo numero è del proprietario, il secondo del gruppo, il terzo di tutti gli altri.
- Dimenticare di mascherare con
0777il campost_mode, che contiene anche il tipo di file. - Scrivere
S_IROTHper "gruppo" (il gruppo èS_IRGRP,S_IWGRP). - Non controllare il valore di ritorno di
statechmod. - Aspettarsi che
chmod 444impedisca al proprietario di cambiare di nuovo i permessi: può sempre rifarlo.
Versione ripasso
Permessi. ls -l: tipo + rwx per proprietario, gruppo, altri; r=4, w=2, x=1. -rw-r--r-- ; chmod 444 r--r--r--; chmod 754 rwxr-xr--. chgrp team abc.
Programma. stat(nome, &st); st.st_mode & 0777 (permessi in ottale, %o); chmod(nome, modo) con S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH.
Soluzione. Nuovo modo S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP (rw-rw----). Meglio: nome da argv[1], controllo di stat e chmod, %03o.
Tabella ottale. 7 rwx, 6 rw-, 5 r-x, 4 r--, 0 ---; 644 rw-r--r--; 660 rw-rw----; 754 rwxr-xr--; 444 r--r--r--. Core del programma. stat(argv[1], &st); printf("%03o", st.st_mode & 0777); chmod(argv[1], S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); con controllo di -1 (e perror); chmod g+w aggiunge la scrittura al gruppo; solo il proprietario o l'amministratore può usare chmod.
Perché la versione con argv. scanf("%s", filename) su 100 byte può andare in overflow; argv[1] no. stat fallita lascia st non inizializzata: sempre controllare il ritorno. Il primo carattere di ls -l è il tipo (- file, d directory, l link); chmod 444 toglie la scrittura anche al proprietario, che può comunque rimetterla con chmod u+w.
Errori tipici: ordine proprietario/gruppo/altri; st_mode senza maschera; S_IROTH al posto di S_IRGRP; ritorni non controllati; scanf("%s") su 100 byte (overflow).