2012-08-17 7 views
5

Sto scrivendo un modulo del kernel che ha accesso alla memoria di un particolare processo. Ho fatto una mappatura anonimo su alcuni della memoria spazio utente con do_mmap():Cambia flag di protezione memoria spazio utente dal modulo kernel

#define MAP_FLAGS (MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS) 

prot = PROT_WRITE; 
retval = do_mmap(NULL, vaddr, vsize, prot, MAP_FLAGS, 0); 

vaddr e vsize sono impostati in precedenza, e la chiamata riesce. Dopo aver scritto su quel blocco di memoria dal modulo del kernel (tramite copy_to_user), voglio rimuovere l'autorizzazione PROT_WRITE su di esso (come farei con lo mprotect nello spazio utente normale). Non riesco a trovare una funzione che consenta questo.

Ho tentato di annullare la mappatura della regione e di rimapparla con le protezioni corrette, ma questo azzera il blocco di memoria, cancellando tutti i dati che ho appena scritto; impostazione MAP_UNINITIALIZED potrebbe risolvere, ma, dalle pagine man:

MAP_UNINITIALIZED (a partire da Linux 2.6.33)

fare pagine anonimi non chiare. Questo flag ha lo scopo di migliorare le prestazioni sui dispositivi incorporati . Questo flag è onorato solo se il kernel è stato configurato con l'opzione CONFIG_MMAP_ALLOW_UNINITIALIZED. A causa delle implicazioni sulla sicurezza, l'opzione viene normalmente abilitata solo sui dispositivi incorporati (cioè, i dispositivi in ​​cui uno ha il controllo completo del contenuto della memoria utente ).

così, mentre quello potrebbe fare quello che voglio, non sarebbe molto portabile. Esiste un modo standard per realizzare ciò che ho suggerito?

+0

Perché oh, perché stai facendo tutto ciò nel tuo modulo del kernel? Con un'API definita in modo preciso non c'è motivo che non possa essere eseguita dal processo dello spazio utente stesso. – mpe

+0

@mpe Il motivo per cui non riesco a farlo nello spazio utente è che il modulo che sto scrivendo è un caricatore di processi; Non ho alcuna influenza sul codice spaziale dell'utente. – nosuchthingasstars

+0

Cosa intendi con caricatore di processi? Intendi un gestore binfmt? – mpe

risposta

1

Dopo un po 'di ricerca, ho trovato una funzione chiamata get_user_pages() (migliore documentazione che ho trovato è here) che restituisce un elenco di pagine da userspace ad un dato indirizzo che possono essere mappati al kernel spazio con kmap() e scritti che modo (nel mio caso, usando kernel_read()). Questo può essere usato come sostituto di copy_to_user() perché consente di forzare i permessi di scrittura sulle pagine recuperate. L'unico inconveniente è che devi scrivere pagina per pagina, invece che tutto in una volta, ma risolve il problema che ho descritto nella mia domanda.

0

Nello spazio utente è presente una chiamata di sistema mprotect che può modificare i flag di protezione sulla mappatura esistente. Probabilmente dovrai seguire l'implementazione di quella chiamata di sistema o semplicemente chiamarla direttamente dal tuo codice. Vedi mm/protect.c.