Anteprima
Vedrai una selezione di 20 pagine su 126
Appunti Sistemi operativi - parte 4 Pag. 1 Appunti Sistemi operativi - parte 4 Pag. 2
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 6
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 11
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 16
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 21
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 26
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 31
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 36
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 41
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 46
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 51
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 56
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 61
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 66
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 71
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 76
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 81
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 86
Anteprima di 20 pagg. su 126.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 4 Pag. 91
1 su 126
D/illustrazione/soddisfatti o rimborsati
Disdici quando
vuoi
Acquista con carta
o PayPal
Scarica i documenti
tutte le volte che vuoi
Estratto del documento

Le code di messaggi e le risorse IPC

Le code di messaggi sono usate nei modelli a sincronizzazione locale e quindi dove le risorse sono locali ai processi. Per avere memorie condivise, semafori e code di messaggi dobbiamo chiedere al kernel di allocarne e quindi devono essere fatte delle chiamate di sistema che prendono il nome di IPC. Linux gestisce le risorse IPC in modo tale che ogni risorsa IPC abbia una chiave che è un valore univoco del sistema. Per creare una risorsa IPC bisogna quindi assegnare una chiave e questa può essere scelta o dal SO ed in questo caso si dice che la IPC è private e quindi non avendola esplicitata il programmatore questa chiave sarà accessibile solo al processo che crea la risorsa, questo è il caso in cui all'interno di un processo viene creata una risorsa IPC, viene poi fatta una fork in modo tale che la risorsa possa poi essere condivisa dal processo padre e dal processo figlio. Quando si fanno esercizi con le fork tipicamente va utilizzata una IPC private.

quando invece viene richiesta un'applicazione multiprocesso senza l'uso della fork in cui abbiamo più processi con main diversi e quindi programmi separati bisogna fare in modo che venga ad essere generata una chiave univoca e anche in questo il kernel ci aiuta con una funzione che prende il nome di ftok. Quindi abbiamo che la chiave di un IPC può essere o locale al programma e quindi quando si fa un programma che fa una fork e crea più processi che condividono un'area di memoria condivisa ci si può disinteressare della chiave e si può dire che la risorsa è di tipo privato e che quindi può essere utilizzata solo dai processi che creiamo nel nostro contesto; quindi nel programma creiamo più processi e questi ereditano questa chiave. Quando i processi non vengono creati dal nostro programma e quindi non vengono usate le fork il SO mette a disposizione una primitiva che si chiama ftok in cui si può leggere una chiave.

univoca e in questo caso è possibile fare più programmi che chiamano ftok, si generano la stessa chiave e possono quindi usare la stessa risorsa.

ftok prende un path name in ingresso ad esempio un file, una directory o qualunque altra cosa, prende un carattere e restituisce un tipo key_t che chiamiamo mykey e che rappresenta una chiave univoca per il nostro sistema, con ftok fornendo come ingressi questi due valori uno di path ed un altro di id siamo sicuri che ciò che ci verrà restituito sarà una chiave univoca. Quindi quei processi che andranno a chiamare ftok con gli stessi parametri otterranno la stessa chiave univoca che identificherà quella risorsa.

Il problema che stiamo analizzando è il seguente. Dato il kernel se vogliamo un'area di memoria condivisa dobbiamo avere una situazione per la quale abbiamo che l'area di memoria venga ad essere condivisa tra i processi e quindi ad esempio venga ad essere condivisa tra il processo

P1 ed il processo P2. Ora poiché questi due processi condividono l'area di memoria dobbiamo andare a chiedere quest'area di memoria al SO. Quindi abbiamo che P1 dovrà fare una richiesta al SO per chiedergli di dargli un pezzo di memoria, P2 dovrà fare la stessa richiesta al SO, il primo processo che arriva a fare la richiesta supponiamo che crea questa area di memoria, quando il kernel crea la memoria vuole una chiave univoca, prende la chiave, prende la memoria e ne restituisce un puntatore. Ora se un secondo processo vuole accedere alla stessa area di memoria dovrà dargli la stessa chiave, altrimenti otterrà una memoria diversa perché ogni pezzettino ha una sua chiave; è un po' un database e quindi ogni risorsa ha una propria chiave. Per fare in modo che P1 e P2 forniscano la stessa chiave si può procedere in modo tale che ambo i processi comunichino tra di loro la chiave ma questo consentirebbe a qualsiasi processo di

conoscere e comunicare la chiave, il kernel allora permette di procedere nel seguente modo, se c'è un programma che genera due processi facendo una fork per P1 e P2 allora specificando nella risorsa IPC PRIVATE il kernel genererà una chiave senza farla conoscere in modo tale che P1 e P2 possano accedere alla stessa area di memoria ma nessun altro processo potrà accedervi non conoscendo la chiave che è privata. Se P1 e P2 non si conoscono i due processi per accedere alla stessa area di memoria possono mettersi d'accordo su uno stesso path name ad esempio "./home/cotroneo/", in questo modo se P1 e P2 si mettono d'accordo su questi parametri quando si andrà a chiamare la funzione ftok fornendo alla funzione i parametri sopra avremo che la funzione fornirà ai due processi la stessa chiave k. Ricapitolando abbiamo che la chiave può essere o fornita in fase di creazione andandola a cablare nel codice oppure.quando viene fatta una fork si può definire una modalità privata o ancora se i programmi sono differenti e la risorsa deve essere condivisa tra più programmi si può andare ad usare una facility del SO per generare una chiave univoca a partire da due parametri che se sono gli stessi in questo modo verrà fornita la stessa chiave. Poiché queste risorse sono gestite dal kernel abbiamo che quando ad esempio un programma crasha queste risorse non vengono deallocate e quindi bisogna procedere in maniera manuale per deallocarle. Nel comando sopra abbiamo che ipcs serve per capire se ci sono risorse ipc aperte invece i flag: - -m indica le risorse ipc della memoria - -s mostra i semafori - -q mostra le code di messaggi Quando viene fatto ipcs -m e notiamo che c'è una risorsa ipc in memoria non deallocata, con il comando ipcrm <shm><IPC_ID> potremmo andarla a rimuovere dando la chiave della risorsa (IPC_ID) chepossiamo andare a deallocarle manualmente utilizzando il comando ipcrm. È importante notare che quando un programma crasha è sempre una buona abitudine deallocare le risorse rimaste in memoria con il comando ipcrm. Il pattern per richiedere una risorsa ipcs è sempre lo stesso, a seconda che chiediamo semafori, memoria o code. Ad esempio, se vogliamo un semaforo utilizzeremo il comando get, se vogliamo una shared memory useremo shm get, se vogliamo una coda dovremo fare una get sulla message queue. Lo stesso discorso vale per le altre primitive. È possibile accedere al manuale dei comandi ipcs utilizzando il comando "man ipcs".di un programma deve essere prevista una deallocazione delle risorse. La primitiva get in generale ha in ingresso la chiave della risorsa ipc che vogliamo creare, ha un flag per i parametri e quello che deve restituire è un descrittore della risorsa. Quando nella chiave è presente la define IPC_PRIVATE la get se la vede lui e genera la chiave, genera la risorsa che può essere condivisa in tutti i processi che vengono creati dal processo corrente. Il flag permette di disciplinare la modalità di creazione o di lettura della risorsa. In particolare possiamo specificare come flag diversi valori in OR. Se ad esempio specifichiamo IPC_CREAT viene creata una risorsa con la chiave data se non esiste, se esiste non fa niente e va avanti. Se in OR mettiamo anche IPC_EXCL dove EXCL sta per EXCLUSIVE, se la risorsa con la chiave specificata esiste viene ritornato un errore; questa è utile per inizializzare più volte la risorsa. Il primo processo.che crea infatti la risorsa, la inizializza a zero e poi la utilizza. Quando arriva un altro processo, questo non sa se è il primo ad utilizzare la risorsa. Pertanto, se la risorsa non esiste, il processo vuole crearla, ma se esiste già, non deve inizializzarla. È quindi importante utilizzare la combinazione dei due valori IPC_PRIVATE e IPC_EXCL, in modo che se la risorsa non esiste venga creata, mentre se esiste già, venga restituito un errore. In questo caso, possiamo gestire l'errore richiedendo l'accesso alla risorsa senza crearla, ottenendo così un descrittore per la risorsa esistente. Questo flag può anche definire i permessi di accesso, che sono rappresentati da ottetti per il creatore, ottetti per il gruppo e ottetti per tutti gli altri (r, w, x -> read, write, executable). 438 Questi bit sono fondamentali, perché ad esempio, se chiediamo al sistema operativo di allocare una memoria e questa memoria viene contrassegnata con il bit x=1, significa che in quell'area di memoria è possibile eseguire codice.

essercidel codice binario e che quindi se viene fatto un JNP a questo indirizzo di memoria sarà possibile andare ad eseguire quell'area di memoria e questo è pericoloso. Se invece si pone x=0 abbiamo che pure se si riesce a modificare il valore di ritorno di una funzione all'indirizzo della zona di memoria creata poiché è marcata come 0 il SO ci darà un'eccezione e quindi non la esegue.

La primitiva ctl (control) sostanzialmente dato un descrittore di ingresso fa un comando che può essere:

  • IPC_RMID -> fa una rimozione
  • IPC_STAT -> richiede informazioni
  • IPC_SET -> si esegue soprattutto per i semafori per incrementare, decrementare o dare nuovi valori.

Quando il kernel crea una risorsa IPC ovviamente si porta dentro una struttura più complessa, questa struttura è importante per i permessi di ottetti e vengono protetti dal kernel ma bisogna fare attenzione ai valori che gli si dà in quanto una buona

Parte di attacchi di buffer overflow vanno proprio a sfruttare una creazione non corretta o poco attenta di questi permessi. Entriamo nello specifico della memoria condivisa, abbiamo che è necessario avere un IPC in quanto i processi non condividono memoria, questo problema non si avrà quando vengono ad essere fatti programmi multi thread. Neanche i processi che sono creati con una fork condividono memoria ma ne viene fatta una copia. Condividere una memoria vuole dire chiedere al kernel di allocare un pezzetto di memoria che deve essere attaccata allo spazio di memoria sia nello spazio di memoria del processo P1 che P2, l'ultima system call che viene ad essere chiamata prende il nome di shm attach. Una volta fatto l'attach viene ad essere restituito un indirizzo e quindi è possibile andare a gestire questa area di memoria come se fosse un puntatore, come se fosse locale al processo e non ci sono più problemi dal punto di vista dell'utilizzo.

iesta di accesso alla shm tramite una chiave univoca. - Avere un processo che crea la shm e poi crea dei processi figli che condividono la stessa shm. Per risolvere il primo problema, possiamo utilizzare il tag ftok per generare una chiave univoca basata su un file esistente nel sistema. Successivamente, utilizziamo il tag shmget per ottenere l'ID della shm associata alla chiave generata. Infine, utilizziamo il tag shmat per attaccare la shm al processo corrente. Per risolvere il secondo problema, il processo padre crea la shm utilizzando il tag shmget e poi crea dei processi figli utilizzando il tag fork. I processi figli possono accedere alla shm utilizzando il tag shmat e condividere i dati tra di loro. In entrambi i casi, è importante utilizzare il tag shmdt per staccare la shm dal processo quando non è più necessaria e il tag shmctl per eliminare la shm quando non è più utilizzata. Questi sono solo alcuni dei tag html che possono essere utilizzati per formattare il testo.
Dettagli
Publisher
A.A. 2022-2023
126 pagine
SSD Ingegneria industriale e dell'informazione ING-INF/05 Sistemi di elaborazione delle informazioni

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher Dadox94 di informazioni apprese con la frequenza delle lezioni di Sistemi operativi e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Università degli studi di Napoli Federico II o del prof Crotoneo Domenico.