2010-07-27 23 views
6

Desidero allocare una memoria con autorizzazioni di esecuzione. Quindi uso mprotect per modificare le autorizzazioni. Per ottenere una memoria allineata alle pagine, utilizzo una funzione valloc.Come allocare una memoria con autorizzazioni di esecuzione?

void * temp = (void *) valloc(x); 

e poi

if(mprotect(temp, BLOCK_SIZE, (PROT_READ | PROT_WRITE |PROT_EXEC))) { 
    exit(-1); 
} 

Ora voglio aggiungere più memoria a questo blocco allocato. Quindi io uso una funzione realloc.

void * new_temp = (void *) realloc(temp, 1024); 

Sarà questo RIALLOCAZIONE cambiare automaticamente le autorizzazioni della memoria allocata a quelle che avevo impostate in precedenza ?? Nel caso in cui realloc sposta l'intero blocco in una posizione diversa, quali sono i permessi della memoria allocata in precedenza e la memoria appena allocata?

Dovrebbe essere utilizzato nuovamente mprotect per ottenere la memoria delle autorizzazioni di esecuzione. E c'è un'API a realloc sul limite delle dimensioni della pagina come valloc. ?

+2

Si dovrebbe contrassegnare questo con il sistema operativo appropriato, in quanto si tratta più di un sistema operativo che di una domanda di lingua. –

+0

valloc() è una funzione legacy BSD rimossa in SUSv3. Presume alcuni sistemi POSIX come Linux o BSD. – Dummy00001

+0

@David: Non proprio, questa roba è supportata da Windoze e Linux (altri sistemi operativi non esistono) e l'API varia solo dove POSIX non è standardizzato. –

risposta

4

Provare ad assegnare una nuova regione con un altro valloc e copiare i vecchi contenuti. Meglio ancora, smettere di usare il deprecato valloc e sostituirlo con le chiamate posix_memalign o direttamente con mmap per allocazioni molto grandi. Utilizzando mremap potresti efficacemente realloc regioni di memoria allineate alla pagina.

1

Mprotect deve essere utilizzato nuovamente per ottenere la memoria delle autorizzazioni di esecuzione.

La memoria virtuale è organizzata in pagine. mprotect() modifica i flag su tutte le pagine nel blocco dato di memoria virtuale. È indipendente dall'allocazione effettiva della memoria. IOW, devi chiamare nuovamente mprotect() dopo realloc per riapplicare le autorizzazioni. E devi chiamarlo di nuovo per l'intera regione, dal momento che il realloc() può invece estendere il puntatore di ritorno del blocco esistente a uno nuovo.

Pensandoci ora, penso che potrebbe essere necessario chiamare mprotect() prima dello realloc() per rimuovere i permessi exec dalla vecchia area di memoria. malloc()/realloc() sono funzioni libc per la gestione della memoria all'interno della memoria virtuale dell'applicazione, mentre mprotect() è un syscall che funziona in modo indipendente sulla memoria virtuale dell'applicazione stessa.

E c'è un'API per realloc sul limite della dimensione della pagina come valloc. ?

Molto dubbio.

Nell'applicazione intensiva di allocazione di memoria, realloc() è raramente in grado di estendere il blocco esistente e spesso finisce per allocare nuovo blocco + memcpy() + blocco vecchio gratuito. Se la prestazione realloc() era accettabile prima, allora la sua versione codificata a mano (tenendo conto dell'allineamento più severo) dovrebbe andare bene.

BTW, POSIXv6 ha una nuova funzione denominata posix_memalign(). valloc's man page è una lettura interessante, soprattutto perché non si dovrebbe usare valloc() in primo luogo.

P.S. Inoltre è sempre possibile utilizzare la funzione POSIX standard per trovare le dimensioni della pagina sysconf(_SC_PAGESIZE); e allineare il buffer di memoria. Ovviamente è necessario allocare i byte new_size+(sysconf(_SC_PAGESIZE)-1) per avere memoria sufficiente per riallineare il puntatore.

+0

Non si desidera rimuovere l'autorizzazione EXEC per una pagina solo perché * un * buffer in quella pagina non ne ha più bisogno. A meno che non si abbia sempre un solo buffer eseguibile allocato in modo dinamico, così si sa che non esiste un altro buffer eseguibile nella stessa pagina. –

Problemi correlati