• Helge Deller's avatar
    parisc: Fix gcc miscompilation in pa_memcpy() · 8e700e95
    Helge Deller authored
    commit 5b879d78 upstream.
    
    When running the LTP testsuite one may hit this kernel BUG() with the
    write06 testcase:
    
    kernel BUG at mm/filemap.c:2023!
    CPU: 1 PID: 8614 Comm: writev01 Not tainted 3.10.0-rc7-64bit-c3000+ #6
    IASQ: 0000000000000000 0000000000000000 IAOQ: 00000000401e6e84 00000000401e6e88
     IIR: 03ffe01f    ISR: 0000000010340000  IOR: 000001fbe0380820
     CPU:        1   CR30: 00000000bef80000 CR31: ffffffffffffffff
     ORIG_R28: 00000000bdc192c0
     IAOQ[0]: iov_iter_advance+0x3c/0xc0
     IAOQ[1]: iov_iter_advance+0x40/0xc0
     RP(r2): generic_file_buffered_write+0x204/0x3f0
    Backtrace:
     [<00000000401e764c>] generic_file_buffered_write+0x204/0x3f0
     [<00000000401eab24>] __generic_file_aio_write+0x244/0x448
     [<00000000401eadc0>] generic_file_aio_write+0x98/0x150
     [<000000004024f460>] do_sync_readv_writev+0xc0/0x130
     [<000000004025037c>] compat_do_readv_writev+0x12c/0x340
     [<00000000402505f8>] compat_writev+0x68/0xa0
     [<0000000040251d88>] compat_SyS_writev+0x98/0xf8
    
    Reason for this crash is a gcc miscompilation in the fault handlers of
    pa_memcpy() which return the fault address instead of the copied bytes.
    Since this seems to be a generic problem with gcc-4.7.x (and below), it's
    better to simplify the fault handlers in pa_memcpy to avoid this problem.
    
    Here is a simple reproducer for the problem:
    
    int main(int argc, char **argv)
    {
    	int fd, nbytes;
    	struct iovec wr_iovec[] = {
    		{ "TEST STRING                     ",32},
    		{ (char*)0x40005000,32} }; // random memory.
    	fd = open(DATA_FILE, O_RDWR | O_CREAT, 0666);
    	nbytes = writev(fd, wr_iovec, 2);
    	printf("return value = %d, errno %d (%s)\n",
    		nbytes, errno, strerror(errno));
    	return 0;
    }
    
    In addition, John David Anglin wrote:
    There is no gcc PR as pa_memcpy is not legitimate C code. There is an
    implicit assumption that certain variables will contain correct values
    when an exception occurs and the code randomly jumps to one of the
    exception blocks.  There is no guarantee of this.  If a PR was filed, it
    would likely be marked as invalid.
    Signed-off-by: default avatarHelge Deller <deller@gmx.de>
    Signed-off-by: default avatarJohn David Anglin <dave.anglin@bell.net>
    Signed-off-by: default avatarHelge Deller <deller@gmx.de>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    8e700e95
memcpy.c 15.5 KB