• James Cowgill's avatar
    MIPS: OCTEON: Fix copy_from_user fault handling for large buffers · 884b4269
    James Cowgill authored
    If copy_from_user is called with a large buffer (>= 128 bytes) and the
    userspace buffer refers partially to unreadable memory, then it is
    possible for Octeon's copy_from_user to report the wrong number of bytes
    have been copied. In the case where the buffer size is an exact multiple
    of 128 and the fault occurs in the last 64 bytes, copy_from_user will
    report that all the bytes were copied successfully but leave some
    garbage in the destination buffer.
    
    The bug is in the main __copy_user_common loop in octeon-memcpy.S where
    in the middle of the loop, src and dst are incremented by 128 bytes. The
    l_exc_copy fault handler is used after this but that assumes that
    "src < THREAD_BUADDR($28)". This is not the case if src has already been
    incremented.
    
    Fix by adding an extra fault handler which rewinds the src and dst
    pointers 128 bytes before falling though to l_exc_copy.
    
    Thanks to the pwritev test from the strace test suite for originally
    highlighting this bug!
    
    Fixes: 5b3b1688 ("MIPS: Add Cavium OCTEON processor support ...")
    Signed-off-by: default avatarJames Cowgill <James.Cowgill@imgtec.com>
    Acked-by: default avatarDavid Daney <david.daney@cavium.com>
    Reviewed-by: default avatarJames Hogan <james.hogan@imgtec.com>
    Cc: Ralf Baechle <ralf@linux-mips.org>
    Cc: linux-mips@linux-mips.org
    Cc: stable@vger.kernel.org
    Patchwork: https://patchwork.linux-mips.org/patch/14978/Signed-off-by: default avatarJames Hogan <james.hogan@imgtec.com>
    884b4269
octeon-memcpy.S 13 KB