Re: Fwd: FW: [PATCH 18/31] nds32: Library functions

From: Al Viro
Date: Fri Nov 17 2017 - 22:15:44 EST


On Tue, Nov 14, 2017 at 12:47:04PM +0800, Vincent Chen wrote:

> Thanks
> So, I should keep the area that we've copied into instead of zeroing
> the area even if unpredicted exception is happened. Right?

Yes. Here's what's required: if raw_copy_{from,to}_user(from, to, size)
returns n, we want
* 0 <= n <= size
* no bytes outside of to[0 .. size - n - 1] modified
* all bytes in that range replaced with corresponding bytes of range
from[0 .. size - n - 1]
* non-zero return values should happen only when some loads (in case
of raw_copy_from_user()) or stores (in case of raw_copy_to_user()) had failed.
If everything could have been read and written, we must copy everything.
* return value should be equal to size only if no load or no store
had been possible. In all other cases you need to copy at least something.
You don't have to squeeze all bytes that can be copied (you can, of course,
but it's not required).
* you should not assume that failing load guarantees that subsequent
loads further into the same page will keep failing; normally they will, but
relying upon that is asking for trouble. Several architectures had bugs
of that sort, with varying amounts of nastiness happening when e.g. write(2)
raced with mprotect(2) from another thread...

For almost any architecture these should be more or less parallel to memcpy();
the only exception I know of is the situation when cross-address-space copy
has timing very different from that for normal load+store. s390 is that
way - there's considerable overhead of setting such copying, and you really
want it done in bigger chunks than would be optimal for memcpy(). uml is
similar. However, generally it's memcpy tweaked to deal with exceptions.