2010-07-27 13 views
6

Quiero asignar una memoria con permisos de ejecución. Así que uso mprotect para cambiar los permisos. Para obtener una memoria alineada con la página, uso una función valloc.¿Cómo asignar una memoria con permisos de ejecución?

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

y luego

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

Ahora quiero añadir más memoria a este bloque asignado. Por lo tanto, uso una función realloc.

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

¿Esta asignación redirigirá automáticamente los permisos de la memoria asignada a los que había configurado antes? En caso de que realloc mueva todo el bloque a una ubicación diferente, ¿cuáles son los permisos de la memoria asignada anteriormente y la memoria recientemente asignada?

Se debe usar mprotect nuevamente para obtener la memoria de permisos de ejecución. Y hay una API a realloc en el límite de tamaño de página como valloc. ?

+2

Debe etiquetar esto con el sistema operativo apropiado, ya que esto es más un problema de sistema operativo que de idioma. –

+0

valloc() es una función heredada de BSD eliminada en el SUSv3. Presume algunos sistemas operativos POSIX como Linux o BSD. – Dummy00001

+0

@David: En realidad, esto no es compatible con Windoze y Linux (no existen otros sistemas operativos), y la API solo varía donde POSIX no se ha estandarizado. –

Respuesta

4

Intente asignar una nueva región con otra valloc y copie los contenidos anteriores. Mejor aún, deje de usar el valloc en desuso, y reemplácelo con llamadas posix_memalign, o directamente mmap para asignaciones muy grandes. Con mremap puede efectivamente realloc regiones de memoria alineadas con la página.

1

Se debe usar mprotect nuevamente para obtener la memoria de permisos de ejecución.

La memoria virtual está organizada en páginas. mprotect() cambia los indicadores en todas las páginas en el bloque dado de memoria virtual. Es independiente de la asignación de memoria real. IOW, debe llamar a mprotect() nuevamente después de realloc para volver a aplicar los permisos. Y tiene que volver a llamarlo para toda la región, ya que realloc() puede en lugar de extender el puntero de retorno de bloque existente a uno nuevo.

Pensando en ello ahora, creo que uno podría necesitar llamar al mprotect() antes del realloc() para eliminar los permisos de ejecución de la región de memoria anterior. malloc()/realloc() son funciones de libc para la gestión de memoria dentro de la memoria virtual de la aplicación, mientras que mprotect() es un syscall que funciona de forma independiente en la memoria virtual de la aplicación.

Y hay una API para realloc en el tamaño límite de página como valloc. ?

Mucho dudas.

En la aplicación de asignación de memoria intensiva, realloc() rara vez es capaz de ampliar el bloque existente y, a menudo termina asignando un nuevo bloque + memcpy() + bloque antiguo libre. Si el rendimiento de realloc() era aceptable antes, su versión codificada a mano (tomando en cuenta una alineación más estricta) también debería estar bien.

Por cierto, POSIXv6 tiene una nueva función llamada posix_memalign(). valloc's man page es una lectura interesante, principalmente por qué uno no debería usar el valloc() en primer lugar.

P.S. También puede utilizar siempre la función POSIX estándar para buscar el tamaño de página sysconf(_SC_PAGESIZE); y alinear el búfer de memoria usted mismo. Obviamente tiene que asignar new_size+(sysconf(_SC_PAGESIZE)-1) bytes para tener suficiente memoria para realinear el puntero.

+0

Definitivamente no desea eliminar el permiso EXEC para una página simplemente porque * un * búfer en esa página ya no lo necesita. A menos que solo tenga un búfer ejecutable dinámicamente asignado, para que sepa que no hay otro búfer ejecutable en la misma página. –

Cuestiones relacionadas