-EFAULT fixing was Re: Tiny tty I/O bug in 2.2.x ?

Andi Kleen (ak@muc.de)
Thu, 13 May 1999 11:22:09 +0200


In muc.lists.linux-kernel, you wrote:
>Hello, we are working with Linux kernel 2.2.8 and found tiny
>but very strange error - `read()' and `write()' can't detect EFAULT
>error when file descriptor is associated with a tty and passed data
>is NULL, i.e. `write (1, 0, 1)' and `read (0, 0, 1)' works fine and
>returns 1. But if 0 and 1 are redirected to the regular file
>via shell > or < commands, -1 is returned, EFAULT is detected and
>errno has appropriate value.

This is a common problem in 2.2, e.g. pipes have it too. When the
old verify_area()/memcpy_*_fs() combination was abandoned for the new
faster single step copy_*_user() a lot of the conversion was done badly
without adding complete error checking. The only thing the old verify_area
does in 2.2 is to check if the address isn't in kernel space, it doesn't
check if the user has really mapped the address. That is done by the
MMU in the actual access now - just it has to be checked then.

e.g. old code

if ((err = verify_area(VERIFY_READ, userptr, size)) {
return err;
}

/* do something */
while (work_to_do) {
memcpy_from_fs(buffer, userptr, blocksize);
...
}

new correct code would be:

while (work_to_do) {
if (copy_from_user(buffer, userptr, blocksize)) {
/* cleanup any state */
return -EFAULT;
}
...
}

because people were often lazy about the new interface
they just removed (or sometimes kept the verify_area because they didn't
understand the new semantics and perhaps thought verify_area still does a full
verify) it was often just converted to:

while (work_to_do) {
copy_from_user(buffer, userptr, blocksize);
...
}

As you noticed the -EFAULT error checking was lost.

A security hole does not occur because copy_from_user clears the kernel
memory in case of a error.

What it needs are more volunteers that wade through the source and fix
all these cases correctly without introducing new bugs. Adding the
cleanup part in the inner loops is unfortunately often tricky.

-Andi

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/