Re: AUDIT: copy_from_user is a deathtrap.

Albert D. Cahalan
2002-05-21T19:03:12Z

Christoph Hellwig writes:

------
> FreeBSD has:
> /* return 0 on success, EFAULT on failure */
> int copyin(const void *udaddr, void *kaddr, size_t len);
> int copyout(const void *kaddr, void *udaddr, size_t len);

return copyin(x,y,z); /* want EFAULT */
return copyin(x,y,z) ? -1 : 0; /* want -1 */
return copyin(x,y,z); /* want non-zero */

FreeBSD behavior might be best, considering where we
are most likely to share drivers.

------
> System V and derivates have:
> /* return 0 on success, -1 on failure */
> int copyin(const void *userbuf, void *driverbuf, size_t cn);
> int copyout(const void *driverbuf, void *userbuf, size_t cn);

System V behavior is the easiest to use:

return copyin(x,y,z) & EFAULT; /* want EFAULT */
return copyin(x,y,z); /* want -1 */
return copyin(x,y,z); /* want non-zero */

------
> OSF/1 has:
> /* return 0 on success, some non-specified error on failure) */
> int copyin(caddr_t user_src, caddr_t kernel_dest, u_int bcount);
> int copyout(caddr_t kernel_src, caddr_t user_dest, u_int bcount);

return copyin(x,y,z) ? EFAULT : 0; /* want EFAULT */
return copyin(x,y,z) ? -1 : 0; /* want -1 */
return copyin(x,y,z); /* want non-zero */

Yuck... but good if it makes the assembly any faster.

------
With -EFAULT on an error:

return -copyin(x,y,z); /* want EFAULT */
return copyin(x,y,z)>>31; /* want -1 (rely on gcc's sign awareness) */
return copyin(x,y,z); /* want non-zero */

Well, I like it.