Come il sistema operativo rileva le violazioni dell'accesso alla memoria


12

Come fa un sistema operativo (preferibilmente Linux) a sapere che hai avuto accesso a una posizione di memoria che non ti è consentito?

Questa domanda è stata ispirata da quei maledetti puntatori! Per come la vedo io: tutto nei computer riguarda un compromesso tra velocità, sicurezza, integrità e cose del genere.

Sono ben consapevole delle mappe di memoria in Linux, ma mi sembra un po 'ridicolo che il kernel controlli se la posizione a cui stai tentando di accedere risiede in un intervallo valido OGNI VOLTA che fai un accesso. Sembra che perderebbe così tanto tempo, che potrebbe essere speso facendo qualcosa di più produttivo (ma forse meno sicuro senza alcun controllo!). O forse ricorda tutti gli accessi recenti e li controlla su ogni tick del timer hardware? (Ma sembra pericoloso e, ancora una volta, lento.)

Sono rimasto sorpreso dal fatto che questa domanda sembra essere senza risposta ovunque. È qualcosa che mi sono sempre chiesto. Mi fa pensare che ci sia una sezione dell'hardware che lo farà per conto del sistema operativo, in un livello di astrazione piacevole e conveniente. Tuttavia, sarebbe probabilmente necessario caricare le mappe di memoria dei processi successivi su ogni interruttore di contesto, che suona ancora lentamente.

Quindi sì, comunque, vado un po 'avanti: come fa un sistema operativo a rilevare una violazione della memoria?

Grazie

Risposte:


11

(La seguente risposta presuppone un desktop, un server o una piattaforma embedded "moderna" (come smartphone e sempre più piccoli sistemi). Per i sistemi x86, moderni significa 386 e successivi. La seguente risposta presuppone anche un Sistema operativo "moderno", come quasi ogni unix, o Windows dal 95.)

Questo non sta accadendo nel sistema operativo, sta accadendo nel processore, in particolare nella MMU ( unità di gestione della memoria ) . La MMU supporta l'indirizzamento virtuale, per cui i bit che compongono un puntatore non indicano direttamente la posizione fisica dei bit in memoria.

In una MMU tipica, quando viene indicato un puntatore, la MMU suddivide i bit in due gruppi: i bit di ordine superiore compongono il numero di pagina e i bit di ordine inferiore compongono l'indirizzo all'interno della pagina. La maggior parte delle macchine desktop e server utilizza pagine da 4kB. La MMU cerca il numero di pagina virtuale in una tabella chiamata TLB (questo è ciò che hai chiamato "mappe della memoria di processo"). Il TLB indica il numero della pagina fisica che corrisponde a questa pagina virtuale. La MMU quindi recupera i dati dalla pagina fisica in memoria.

Se il TLB non contiene una voce per questo particolare numero di pagina virtuale, la MMU notifica al processore che si è verificato un accesso non valido; questo è in genere chiamato un'eccezione.

Si noti che finora non ho menzionato il sistema operativo. Questo perché tutte queste operazioni sono indipendenti dal sistema operativo. Il sistema operativo entra in gioco perché configura le cose in due modi:

  • Il sistema operativo è responsabile del cambio di attività. Quando lo fa, come sospettavi, salva il TLB corrente e lo sostituisce con il TLB salvato per l'attività pianificata successiva. In questo modo, ogni processo ha un TLB, quindi l'indirizzo 0x123456nel processo X potrebbe non puntare allo stesso posto effettivo nella RAM dello stesso indirizzo nel processo Y, o potrebbe semplicemente non essere valido. Se un processo tenta di dereferenziare un puntatore al di fuori del suo spazio di indirizzamento, non raggiunge lo spazio di un altro processo, piuttosto non arriva da nessuna parte .

  • Il sistema operativo decide cosa succede quando viene sollevata un'eccezione. Può terminare il processo per eseguire un accesso alla memoria non valido (errore di segmentazione, errore di protezione generale, ...). Questo è anche il modo in cui viene implementato lo scambio: il gestore delle eccezioni potrebbe decidere di recuperare alcuni dati dallo spazio di scambio, aggiornare il TLB di conseguenza ed eseguire nuovamente l'accesso.

Si noti che la MMU fornisce sicurezza poiché il processo non può modificare il proprio TLB. Solo il kernel del sistema operativo può modificare i TLB. Il funzionamento delle autorizzazioni di modifica TLB va oltre lo scopo di questa risposta.


6

1) I segfault vengono rilevati dall'unità di gestione della memoria. Quando si richiede memoria, il sistema operativo richiede all'unità di gestione della memoria di ottenerne un po 'dall'hardware. Deve esserci qualcosa che tenga traccia di tutti i grandi blocchi di memoria che il sistema operativo ti offre. Il tipo di sistema operativo che passa alla MMU. Dal momento che conosce tutta la memoria che ti ha dato, può anche dirti quando provi ad accedere a una posizione di memoria che non hai ricevuto dalle allocazioni, Il sistema operativo ha specificamente un evento per questo, memoria che non possiedi. Alla fine il sistema operativo uccide la tua app, innescando un segfault o l'equivalente su altri sistemi operativi.

Non tutti i sistemi operativi hanno questa protezione. MacOS fino a 9 non aveva nulla di tutto ciò, anche se la MMU lo supportava. Nemmeno Win 3.1. Win95 aveva una certa protezione, poiché passava dal non avere alcuna protezione all'aggiunta di qualcosa.

2) Il sistema operativo non conosce altri dettagli oltre a questo. Se hai un puntatore vagante che accede alla memoria che non hai mai allocato, lo sa. Se ne hai uno che va in un'altra parte dell'applicazione, ovviamente non lo sa. Ti permette di corrompere questo. È qui che ottieni stack corrotti, con puntatori vaganti dalla tua app che sovrascrivono altre parti della tua app.

Quindi sì, puoi rovinare i tuoi dati. Se hai un puntatore vagante che sovrascrive la tua app, SPERIMI, colpisci il tuo stack, dal momento che probabilmente causerà un'altra violazione quando provi a tornare fuori dallo stack, ma se colpisci i tuoi dati, non lo saprai mai.

Puoi provare a essere più severo di "nessuna protezione", c'è uno strumento chiamato Electric Fence ( http://perens.com/FreeSoftware/ElectricFence/ ) che indurrà la tua MMU a funzionare un po 'di più e farà sì che rilevi di più difetti.


Okay, puoi essere più specifico su come funziona? Come, come fa a sapere che un determinato processo non può accedere a una determinata posizione? Cosa dice a quali processi può accedere dove? Come si distingue? Grazie
Doddy,

1
@panic - cerca Memory_management_unit in wikipedia e i link da quella pagina. Si noti che lo stato del processo include lo stato MMU. Puoi spendere semestri sulla progettazione, le funzionalità e l'integrazione di MMU.
mpez0
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.