2012-08-17 15 views
5

Estoy escribiendo un módulo kernel que tiene acceso a la memoria de un proceso en particular. He hecho un mapeo anónimo en parte de la memoria del espacio de usuario con do_mmap():Cambiar marcadores de protección de memoria de espacio de usuario del módulo kernel

#define MAP_FLAGS (MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS) 

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

vaddr y vsize se establecen antes, y la llamada se realiza correctamente. Después de escribir en ese bloque de memoria desde el módulo kernel (a través de copy_to_user), quiero eliminar el permiso PROT_WRITE (como lo haría con mprotect en el espacio normal de usuario). Parece que no puedo encontrar una función que permita esto.

Intenté eliminar el mapa de la región y reasignarlo con las protecciones correctas, pero eso pone a cero el bloque de memoria, borrando todos los datos que acabo de escribir; establecer MAP_UNINITIALIZED podría arreglar eso, pero, desde las páginas de manual:

MAP_UNINITIALIZED (desde Linux 2.6.33)

no desactive páginas anónimas. Este indicador está destinado a mejorar el rendimiento en dispositivos integrados . Este indicador solo se respeta si el kernel se configuró con la opción CONFIG_MMAP_ALLOW_UNINITIALIZED. Debido a las implicaciones de seguridad, esa opción normalmente está habilitada solo en dispositivos integrados (es decir, dispositivos en los que uno tiene control completo del contenido de la memoria del usuario).

Así que, aunque eso podría hacer lo que yo quiera, no sería muy portátil. ¿Hay una manera estándar de lograr lo que he sugerido?

+0

¿Por qué oh por qué haces todo eso en tu módulo kernel? Con una API bien definida, no hay ninguna razón por la que el proceso del espacio de usuario no pueda hacerlo. – mpe

+0

@mpe La razón por la que no puedo hacerlo en el espacio de usuario es que el módulo que estoy escribiendo es un cargador de procesos; No tengo ninguna influencia sobre el código de espacio del usuario. – nosuchthingasstars

+0

¿Qué quiere decir con cargador de procesos? ¿Te refieres a un controlador binfmt? – mpe

Respuesta

1

Después de algunas investigaciones más, me encontré con una función llamada get_user_pages() (mejor documentación que he encontrado es here) que devuelve una lista de páginas de espacio de usuario en una dirección determinada que se pueden asignar al espacio del núcleo con kmap() y escrita en tal manera (en mi caso, usando kernel_read()). Esto se puede utilizar como reemplazo de copy_to_user() porque permite forzar permisos de escritura en las páginas recuperadas. El único inconveniente es que debe escribir página por página, en lugar de hacerlo todo de una vez, pero resuelve el problema que describí en mi pregunta.

0

En el espacio de usuario hay una llamada al sistema mprotect que puede modificar los indicadores de protección en la asignación existente. Probablemente deba seguir desde la implementación de esa llamada al sistema, o simplemente llamar directamente desde su código. Ver mm/protect.c.

Cuestiones relacionadas