2009-11-08 16 views
9

Implementé algún tipo de dispositivo de caracteres y necesito ayuda con la función copy_ from_user.Linux Kernel: copy_from_user - struct con punteros

tengo una estructura:

struct my_struct{ 

int a; 

int *b; 
}; 

que inicializarlo en el espacio de usuario y pass puntero a my_struct a mi dispositivo de caracteres utilizando la función de 'escribir'. En la función 'escribir' del dispositivo de personaje Space de Kernel lo echo de un * char a este tipo de estructura. Asigno algo de memoria para una estructura usando kmalloc y hago copy_from_user en ella.

Está bien para 'int a' simple, pero copia solo el puntero (dirección) del valor b, no el valor apuntado por b, entonces ahora estoy en Kernel Space y estoy trabajando con un puntero que apunta a una memoria de espacio de usuario. ¿Es esto incorrecto y no debería acceder al puntero de espacio de usuario directamente y tengo que marcar copy_from_user cada puntero en mi estructura y luego copiar cada puntero en la función "leer" usando la función copy_to_user?

Respuesta

6

Usted está en lo correcto sobre su conjetura. Si necesita acceder al valor *b, necesitará usar copy_from_user (y copy_to_user para actualizarlo en el proceso de usuario).

+2

También me gustaría señalar que no puedo pensar en ningún syscalls o ioctls que tomen structs con punteros en ellos. Incluso aquellos que tienen cadenas tendrán una matriz de caracteres en la estructura en su lugar. El hecho de que sea muy molesto escribir código para hacer esto para cada miembro del puntero podría tener algo que ver con eso. :-) – asveikau

+0

@asveikau: 'readv()' y 'writev()'? – caf

13

Siempre debe utilizar copy_from_user y similar para acceder a la memoria de espacio de usuario desde el espacio del kernel, independientemente de cómo haya obtenido el puntero. Como b es un puntero a la memoria de espacio del usuario, debe usar copy_from_user para acceder a él.

Estas funciones hacen dos importantes tareas adicionales:

  1. Aseguran que los puntos del puntero se convierte en espacio de usuario y no espacio del núcleo. Sin esta comprobación, los programas de espacio del usuario podrían leer o escribir en la memoria del núcleo, evitando la seguridad normal.
  2. Manejan las fallas de página correctamente. Normalmente, un error de página en el modo kernel dará como resultado un OOPS o pánico: la familia de funciones copy_*_user tiene una anulación especial que le informa al manejador PF que todo está bien y que la falla se debe manejar normalmente; y en el caso de que IO no pueda satisfacer la falla (es decir, lo que normalmente causaría SIGSEGV o SIGBUS), devuelva un código de error para que la persona que llama pueda realizar la limpieza necesaria antes de regresar al espacio de usuario con -EFAULT.