On Tue, 2016-11-10 at 11:25:47 UTC, Paul Mackerras wrote:
> Debugging a data corruption issue with virtio-net/vhost-net led to
> the observation that __copy_tofrom_user was occasionally returning
> a value 16 larger than it should. Since the return value from
> __copy_tofrom_user is the number of bytes not copied, this means
> that __copy_tofrom_user can occasionally return a value larger
> than the number of bytes it was asked to copy. In turn this can
> cause higher-level copy functions such as copy_page_to_iter_iovec
> to corrupt memory by copying data into the wrong memory locations.
> It turns out that the failing case involves a fault on the store
> at label 79, and at that point the first unmodified byte of the
> destination is at R3 + 16. Consequently the exception handler
> for that store needs to add 16 to R3 before using it to work out
> how many bytes were not copied, but in this one case it was not
> adding the offset to R3. To fix it, this moves the label 179 to
> the point where we add 16 to R3. I have checked manually all the
> exception handlers for the loads and stores in this code and the
> rest of them are correct (it would be excellent to have an
> automated test of all the exception cases).
> This bug has been present since this code was initially
> committed in May 2002 to Linux version 2.5.20.
> Cc: sta...@vger.kernel.org
> Signed-off-by: Paul Mackerras <pau...@ozlabs.org>
Applied to powerpc next, thanks.