¿Alguien puede explicarme cómo funciona exactamente la función copy_from_user interna? ¿Utiliza cualquier buffers o hay algún mapeo de memoria hecho teniendo en cuenta el hecho de que kernel tiene el privilegio de acceder al espacio de usuario mem.¿Cómo funciona copy_from_user del kernel de Linux internamente?
Respuesta
La implementación de copy_from_user()
depende en gran medida de la arquitectura.
En x86 y x86-64, simplemente realiza una lectura directa desde la dirección del espacio de usuario y escribe en la dirección del espacio de kernel, mientras deshabilita temporalmente SMAP (Supervisor Mode Access Prevention) si está configurado. La parte engañosa de esto es que el código copy_from_user()
se coloca en una región especial para que el controlador de fallas de página pueda reconocer cuándo ocurre un error dentro de él. Un error de protección de memoria que ocurre en copy_from_user()
no mata el proceso como lo haría si se desencadena por otro código de contexto de proceso, o entra en pánico al kernel como si ocurriera en un contexto de interrupción; simplemente reanuda la ejecución en un código ruta que devuelve -EFAULT
a la persona que llama.
La implementación de la llamada al sistema copy_from_user() se realiza utilizando dos almacenamientos intermedios desde diferentes espacios de direcciones.
- El tampón de espacio de usuario en dirección virtual del usuario.
- kernel-space buffer en kernel virtual address.
Cuando se invoca la llamada al sistema copy_from_user() los datos se copian del búfer de usuario al búfer del kernel.
Una parte (operación de escritura) del código de controlador de dispositivo de caracteres, donde se utiliza copy_from_user() es la siguiente:
ssize_t cdev_fops_write (estructura de archivos * flip, const __user char * ubuf, recuento size_t, loff_t * f_pos)
{
unsigned int *kbuf; copy_from_user(kbuf, ubuf, count); printk(KERN_INFO "Data: %d",*kbuf);
}
ok mi duda con su respuesta es que está bien para copy_from_user. .how bout copy_to_user dado que el kernel está pasando la dirección de espacio del kernel, cómo puede acceder un proceso de espacio de usuario. Hace que el kernel realice un mappin previo en la máquina virtual de espacio de usuario para que el usuario pueda acceder desde allí – Santi1986
con respecto a "cómo bout copy_to_user dado que el kernel está pasando la dirección de espacio del kernel, cómo puede acceder un proceso de espacio de usuario"
Un proceso de espacio de usuario puede intentar acceder a cualquier dirección. Sin embargo, si la dirección no está asignada en ese espacio de usuario de proceso (es decir, en las tablas de página de ese proceso) o si hay un problema con el acceso como un intento de escritura a una ubicación de solo lectura, se genera un error de página. Tenga en cuenta que al menos en el x86, cada proceso tiene todo el espacio del kernel mapeado en el más bajo 1 gigabyte del espacio de direcciones virtuales del proceso, mientras que los 3 gigabytes superiores del espacio de direcciones total de 4GB (estoy usando aquí el clásico de 32 bits caso) se utilizan para el texto de proceso (es decir, código) y datos. Una copia hacia o desde el espacio de usuario es ejecutada por el código kernel que se está ejecutando en nombre del proceso y en realidad es la asignación de memoria (es decir, las tablas de página) de ese proceso que están en uso durante la copia. Esto tiene lugar mientras la ejecución está en modo kernel, es decir, modo privilegiado/supervisor en lenguaje x86. Suponiendo que el código de espacio de usuario ha pasado una ubicación de destino legítima (es deciruna dirección correctamente asignada en ese espacio de direcciones de proceso) para copiar los datos, copy_to_user, ejecutar desde el contexto del kernel, normalmente podría escribir en esa dirección/región sin problemas y luego de que el control regrese al usuario, el espacio de usuario también puede lea esta configuración de ubicación por el proceso mismo para comenzar. Se pueden encontrar detalles más interesantes en los capítulos 9 y 10 de Understanding the Linux Kernel, 3rd Edition, por Daniel P. Bovet, Marco Cesati. En particular, access_ok() es una verificación de validez necesaria pero no suficiente. El usuario aún puede pasar direcciones que no pertenecen al espacio de direcciones del proceso. En este caso, se producirá una excepción de falla de página mientras el código del núcleo está ejecutando la copia. La parte más interesante es cómo el controlador de fallas de la página kernel determina que el error de la página en ese caso no se debe a un error en el código del núcleo sino a una dirección incorrecta del usuario (especialmente si el código kernel en cuestión es de un módulo kernel cargado).
La mejor respuesta tiene algo malo, copy_ (de | a) usuario no puede ser utilizado en el contexto de interrupción, pueden dormir, copiar (de | a) función de usuario sólo se puede utilizar en el contexto de proceso, la tabla de páginas del proceso incluye toda la información que necesita el kernel para acceder, así kernel puede dirigir el acceso a la dirección de espacio de usuario si podemos asegurarnos de que la página direccionada está en la memoria, use copy (de | a) _función de usuario, porque puede comprobarlo por nosotros y si la página de espacio de usuario no es residente, nos la arreglará directamente.
- 1. Linux Kernel: copy_from_user - struct con punteros
- 2. Programación del kernel de Linux
- 3. Hash: ¿Cómo funciona internamente?
- 4. ¿Cómo funciona stringstream internamente?
- 5. desarrollo del kernel de Linux
- 6. ¿Cómo funciona Firebug internamente?
- 7. cómo funciona printf internamente.
- 8. ¿cómo funciona fgets internamente?
- 9. ¿Cómo funciona LINQ internamente?
- 10. módulo del kernel Linux compilar
- 11. ¿Cómo funciona C# eventhandler internamente?
- 12. ¿Cómo funciona PHP PDO internamente?
- 13. ¿Cómo funciona BULK INSERT internamente?
- 14. ¿Impresiones de depuración del kernel de Linux?
- 15. Símbolo exportado del kernel de Linux
- 16. Ubicación del Módulo Kernel de Linux
- 17. Programación del controlador del dispositivo del kernel de Linux
- 18. Cómo codificar un módulo kernel de Linux?
- 19. ¿Cómo funciona el intercambio de variables internamente?
- 20. ¿Cómo funciona el operador "es" internamente
- 21. Cómo comenzar con el desarrollo del kernel de Linux
- 22. ¿Cómo detener los hilos del kernel de Linux en rmmod?
- 23. ¿Cómo funciona un cursor SQLite internamente?
- 24. ¿Cómo sabe Linux Kernel dónde buscar el firmware del controlador?
- 25. Linux kernel aio funcionalidad
- 26. ¿Cómo funciona phoneGap (Cordova) internamente, iOS específica
- 27. ¿Cómo funciona LinkedList internamente en Java?
- 28. ¿Cómo funciona el enrutamiento ASP.NET internamente?
- 29. ¿Cómo funciona la palabra clave "como" internamente?
- 30. Cómo usar ioctl() desde el espacio del kernel en Linux?
Gracias, estaba seguro del acceso directo del kernel, así que básicamente supongo que hace una comprobación previa del puntero/dirección que se pasa para verificar si alguna dirección inválida no se pasa a la función i significa decir la dirección que pertenece a algún otro proceso de espacio de usuario ... de todos modos no sabía acerca de la protección de memoria cosa que ha mencionado .... Así que mi DOubt es wht combate en el caso de copy_to_user ... desde el espacio de usuario se pasa una dirección dentro de la VM del espacio del kernel ... cómo lo acepta el espacio de usuario ... o es que el kernel mapea esa dirección a alguna dirección de espacio de usuario – Santi1986
@ Santi1986: 'copy_to_user()' funciona exactamente igual manera, excepto que las direcciones de origen y destino se intercambian: lee de las direcciones del kernel y escribe en las direcciones del espacio de usuario. El único control que se realiza en ambos es que la dirección del espacio de usuario realmente * está * debajo del núcleo/división del usuario; no es necesario verificar las direcciones que pertenecen a otros procesos de usuario, porque 'copy _ * _ user()' se llama solo en el contexto del proceso, lo que significa que * todas * las direcciones son direcciones de kernel o pertenecen al proceso actual. – caf
Gracias por su tiempo, solo hojeé el código y descubrí que este kernel verifica la validez de los punteros a través de access_ok), básicamente se llama a la función __copy _ * _ que usa internamente esta función __copy _ * _ user_inatomic que finalmente llama a __copy __ * _ user_ll, que la copia actual y también las PAGINAS SON PINNADAS ANTERIORMENTE COPIANDO ... si no se copian todos los datos, se rellenan con cero (por el len pasado a la llamada) – Santi1986