Mi chiedo se c'è un modo per proteggere da scrittura ogni pagina in uno spazio di indirizzi del processo Linux (dall'interno del processo stesso, tramite mprotect()
). Per "ogni pagina", intendo davvero ogni pagina dello spazio di indirizzamento del processo che potrebbe essere scritta da un normale programma in esecuzione in modalità utente - quindi, il testo del programma, le costanti, le globali e l'heap - - ma sarei felice con solo costanti, globals e heap. Non voglio proteggere da scrittura lo stack - che sembra una cattiva idea.Posso proteggere da scrittura ogni pagina nello spazio degli indirizzi di un processo Linux?
Un problema è che non so da dove iniziare la protezione di scrittura . Guardando a /proc/pid/maps
, che mostra le sezioni della memoria in uso per un dato pid, sembrano sempre iniziare con l'indirizzo 0x08048000
, con il testo del programma. (In Linux, per quanto posso dire, la memoria di un processo è presentata con il testo del programma sul fondo , quindi le costanti sopra quella, quindi le globali, quindi l'heap, quindi uno spazio vuoto di dimensioni variabili a seconda sulla dimensione dello stack o dello stack e quindi lo stack crescente dalla parte superiore della memoria all'indirizzo virtuale 0xffffffff
.) C'è un modo per indicare dove si trova la parte superiore dello heap (chiamando sbrk(0)
, che restituisce semplicemente un puntatore alla "pausa" corrente , ovvero la parte superiore dell'heap), ma non in realtà un modo per dire a dove inizia l'heap.
Se provo a proteggere tutte le pagine da 0x08048000
fino all'interruzione, I alla fine ottengo un errore mprotect: Cannot allocate memory
. Non so perché mprotect
sarebbe allocando comunque memoria, e Google non è molto utile. Qualche idea?
Tra l'altro, il motivo che voglio fare questo è perché voglio creare un elenco di tutte le pagine che vengono scritti durante una corsa del programma , e il modo in cui posso pensare di fare questo è di proteggere da scrittura tutte le pagine, lasciare che qualsiasi tentativo di scrittura causi un errore di scrittura, quindi implementare un gestore di errori di scrittura che aggiungerà la pagina all'elenco e quindi rimuovere la protezione di scrittura . Penso di sapere come implementare il gestore, se solo potessi capire quali pagine proteggere e come farlo.
Grazie!
In realtà ho già un codice che fa esattamente quello che stai cercando di fare. La tua idea funzionerà, ma non puoi proteggere le pagine in cui risiedono le tue liste "queste pagine scritte", o il tuo gestore SEGV causerà un SEGV! – Borealid
@Borealid, grazie, e questo è ora il problema che sto cercando di risolvere (ho il gestore segfault e l'analisi/proc/self/maps che funziona ora). Come evitare di proteggere le pagine che contengono quell'elenco? L'assegnazione della lista sullo stack funzionerebbe, ma poi non vedo alcun modo per passarlo al gestore. In alternativa, potrei allocarlo come globale, ma mi piacerebbe utilizzare una struttura dati più elaborata di una matrice a lunghezza fissa (come un contenitore STL) e potrei non sapere sempre dove si trova l'elenco che sto scrivendo in memoria. –
@borealid: hai detto che hai codice che fa esattamente questo - ti dispiacerebbe condividere il tuo codice? Sono nuovo qui e non sono riuscito a trovare un modo per contattarti direttamente (back-channel). Sto cercando di fare esattamente ciò che sta facendo Linsey, quindi qualsiasi esempio di codice sarebbe molto utile. –