2010-11-09 13 views
5

Según el diseño de Linux en x86 y ppc, el espacio de direcciones virtuales 4g se divide en 3: 1. Las direcciones virtuales del usuario son hasta 3g.¿Por qué se requiere copy_to/from_user?

Ahora, si la aplicación del usuario hace un ioctl pasando un puntero a un búfer, el módulo kernel puede hacer directamente un memcpy, lo intenté y funcionó. => ¿Por qué necesitamos un usuario copy_to/copy_from?

Nota: Si la página se intercambia, el manejador de la página del núcleo no lo devolverá, y es invisible para el módulo kernel.

necesito yr ideas ... comentarios

Respuesta

9

Hay varias buenas razones por las que copy_to_user/copy_from_user son las funciones correctas a utilizar:

  • En algunas arquitecturas un simple memcpy() hace no trabajo, por lo que el uso de estas funciones permite a su código para trabajar allí. Creo que incluso x86 con la opción de configuración HIGHMEM seleccionada está en este barco.

  • Estas funciones hacen un cheque access_ok() para asegurar que las direcciones del espacio de usuario referenciados realmente son direcciones del espacio de usuario genuinos. Si solo hace un memcpy(), la persona que llama al ioctl() puede suministrar un rango de direcciones que se superpone a las direcciones del kernel, que es un agujero de seguridad.

  • Sin embargo, el motivo principal es manejar correctamente las direcciones de usuario incorrecto. Si solo usa un bare memcpy(), la falla no controlada dará como resultado un kernel ¡Uy! Las funciones de acceso del usuario usan "fixup" mechanism, que permite que se maneje la falla (la lectura o escritura es corta, y generalmente EFAULT se devuelve al espacio de usuario en este caso).

+0

bien, entonces la razón principal es el manejo de direcciones ** bad **. – mSO

+0

y si las direcciones son válidas (digamos, en el mejor de los casos, nadie está haciendo ningún daño) la memcpy debería funcionar. – mSO

+0

@Manish: no es necesariamente "travesura", podría ser simplemente un viejo error en el espacio de usuario: el kernel debe manejar estos errores con elegancia. Y el 'memcpy()' solo funcionará en algunas arquitecturas. – caf

0

Tuviste suerte de que funcionó.

El espacio de usuario y el kernel operan en espacios de direcciones completamente diferentes. Cuando copie_a_usuario, el kernel traduce la dirección virtual de espacios de usuario en una dirección física real y copia los datos allí. Un proceso similar ocurre al revés.

Es posible saltear la copia a/desde los pasos directamente si su hardware es compatible con scatter/gather DMA. Aquí asigna un fragmento contiguo de memoria virtual en una serie de páginas físicas y luego utiliza esa información en DMA directamente en el espacio de usuario. Por supuesto, esto tiene complicaciones si alguno de los espacios de direcciones virtuales no está actualmente mapeado en la memoria física (think swap o archivos respaldados por mmaps).

+0

la división 3g: 1g debería encargarse de eso. El núcleo AFAIK no necesita traducir va a pa para copiar. – mSO

Cuestiones relacionadas