• Paul Mackerras's avatar
    powerpc/64: Fix incorrect return value from __copy_tofrom_user · 1a34439e
    Paul Mackerras authored
    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: stable@vger.kernel.org
    Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    1a34439e
copyuser_64.S 10.8 KB