Re: copy_from_user() fix

Uwe Ohse (uwe@ohse.de)
26 Aug 1998 12:17:09 -0000


Hello H. Peter Anvin,

>This is broken.

It's not. It works under at least eight different operating systems,
even under those which do not provide /dev/zero (i don't care about
95. NT it might even work under).

>If you run zlibc, for example, read() is implemented
>as a library function. You have no guarantee that that works; and it

i very well have the guarantee that zlibc doesn't break operations
on /dev/zero (and even if it does break them: i doubt that zlibc
is an allowed option under the guidelines of the project i wrote
the library for. I doubt that zlibc is an option whereever you
need near perfect reliability).

And just for the records: using zlibc i get even more trouble if i try
to use signal handlers - what if i get a SIGSEGV inside of write()? Then
i don't have a chance to do _anything_ useful, can't even tell somebody
about why the program is going to die.

>may break for reasons that you don't know.

There is not much i can if things go wrong, ok. I can live with that.
But there is no excuse for making things worse.

Just give me an alternative ... catching (and resetting) SIGSEGV,
SIGBUS and SIGILL (?) is not an option i like, because it costs far
too much performance.
The obvious answer "then don't check it, because if the application gives
you bad buffers then it is screwed up anyway" doesn't work under that
guidelines, even though it's true in about 90% of the cases i've seen.

And there is another difference beside performance between

log(...)
{
/* ... */
if (write(fd,msg,strlen(msg))<0 && errno==EFAULT) {
/* uh. bad msg */
const char *msg="fault during log write, message lost\n";
write(2,msg,strlen(msg));
log(...,msg,strlen(msg));
errno=EFAULT;
return -1;
}
/* deal with other problems */
}
and
crash_handler(int sig)
{
const char *msg="fault during log write, program lost\n";
/* can't call log() anymore, might run into reentrancy problems */
write(2,msg,strlen(msg)); /* does someone read our stderr? */
_exit(128+sig); /* or call old_signal_handler() to do this */
}
...
log(...)
{
SETUP_CRASH_HANDLERS(crash_handler);
/* write (...) and deal with problems */
RESTORE_CRASH_HANDLERS();
}

You can't do much useful inside signal handlers. And i doubt that you
can reliably do even cleanup stuff if the signal happened while zlibc
was active.

Make it an option, defaulting to the old behaviour.

Uwe

-
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.altern.org/andrebalsa/doc/lkml-faq.html