Re: [PATCH v4 1/2] m68k: Handle __generic_copy_to_user faults more carefully

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On Mon, 29 Apr 2024, Michael Schmitz wrote:

As mentioned by Finn Thain in his patch to improve put_user
exception handling on 040, a similar problem exists on 030
processors.

A moves instruction that crosses a page boundary from a
mapped page into an unmapped one will cause a mid-instruction
bus error exception (frame format b), with the PC pointing
(usually) two instructions past the faulting movesl instruction.

Our exception handling in __generic_copy_to_user only covers
the instruction immediately following the faulting one. As
a result, fixup_exception in send_fault_sig does not detect
this case, and cause send_fault_sig to oops.

Extend the exception table to cover one additional instruction
beyond the moves[lwb] instructions.

Tested on 68030 (Atari Falcon 030) with transfers beginning
at one to six bytes offset from the end of a mapped page,
followed by further bytes on an unmapped page (testcase
derived from stress-ng sysbadaddr stressor by Finn Thain).

Tested on 68040 (Mac Quadra) and 68030 (Mac IIci) by Finn Thain.

A similar problem is present in __clear_user(); modify the
exception table for that function in the same way (tested by
Finn Thain).


Well, that __clear_user() bug is no longer theoretical. I accidentally 
bumped into it when I sent a ^C to a shell script I wrote to test some 
mac_scsi driver patches...


[    0.000000] Linux version 6.10.0-mac-00011-gd1d490afeb2a (fthain@nippy) (m68k-unknown-linux-musl-gcc (Gentoo 13.2.1_p20240210 p14) 13.2.1 20240210, GNU ld (Gentoo 2.40 p7) 2.40.0) #39 Sat Aug  3 19:57:43 AEST 2024

...

root@(none):/# bash scsi-test.sh /dev/sda5
bs=512k count=1
[  130.090000] sd 0:0:0:0: [sda] tag#9 PDMA fixup: DRQ timeout
[  130.090000] sd 0:0:0:0: [sda] tag#9 switching to slow handshake
[  130.180000] sd 0:0:0:0: Power-on or device reset occurred
1+0 records in
1+0 records out
524288 bytes (524 kB, 512 KiB) copied, 5.13732 s, 102 kB/s
[  136.030000] bash (57): drop_caches: 3
^C
root@(none):/# bash scsi-test.sh /dev/sdb5
bs=512k count=1
1+0 records in
1+0 records out
524288 bytes (524 kB, 512 KiB) copied, 1.1273 s, 465 kB/s
[  160.440000] bash (61): drop_caches: 3
1+0 records in
1+0 records out
524288 bytes (524 kB, 512 KiB) copied, 1.12763 s, 465 kB/s
[  171.920000] bash (61): drop_caches: 3

bs=64k count=8
8+0 records in
8+0 records out
524288 bytes (524 kB, 512 KiB) copied, 1.03469 s, 507 kB/s
[  184.480000] bash (61): drop_caches: 3
8+0 records in
8+0 records out
524288 bytes (524 kB, 512 KiB) copied, 1.03221 s, 508 kB/s
[  196.340000] bash (61): drop_caches: 3

bs=4k count=128
128+0 records in
128+0 records out
524288 bytes (524 kB, 512 KiB) copied, 1.13089 s, 464 kB/s
[  208.860000] bash (61): drop_caches: 3
128+0 records in
128+0 records out
524288 bytes (524 kB, 512 KiB) copied, 1.13089 s, 464 kB/s
[  220.850000] bash (61): drop_caches: 3

bs=512 count=1k
1024+0 records in
1024+0 records out
524288 bytes (524 kB, 512 KiB) copied, 3.69678 s, 142 kB/s
[  236.020000] bash (61): drop_caches: 3
1024+0 records in
1024+0 records out
524288 bytes (524 kB, 512 KiB) copied, 3.68874 s, 142 kB/s
[  250.570000] bash (61): drop_caches: 3

bs=512k count=1
1+0 records in
1+0 records out
524288 bytes (524 kB, 512 KiB) copied, 1.12338 s, 467 kB/s
[  263.120000] bash (61): drop_caches: 3
1+0 records in
1+0 records out
524288 bytes (524 kB, 512 KiB) copied, 1.12665 s, 465 kB/s
[  275.110000] bash (61): drop_caches: 3

bs=64k count=8
8+0 records in
8+0 records out
524288 bytes (524 kB, 512 KiB) copied, 1.08861 s, 482 kB/s
[  287.610000] bash (61): drop_caches: 3
8+0 records in
8+0 records out
524288 bytes (524 kB, 512 KiB) copied, 1.03319 s, 507 kB/s
[  299.510000] bash (61): drop_caches: 3
^C[  303.190000] Unable to handle kernel access at virtual address d7d17fd7
[  303.200000] Oops: 00000000
[  303.210000] Modules linked in:
[  303.220000] PC: [<004301fe>] __clear_user+0x22/0x40
[  303.240000] SR: 2000  SP: 4841d159  a2: 00b78590
[  303.250000] d0: 000003ab    d1: 00000000    d2: 00000000    d3: 8000c150
[  303.260000] d4: 00002000    d5: 00000000    a0: 8000c154    a1: 009bdb3c
[  303.280000] Process cmp (pid: 92, task=7d95deea)
[  303.290000] Frame format=B ssw=0709 isc=0801 isb=0001 daddr=8000c150 dobuf=00000000
[  303.310000] baddr=00430202 dibuf=8000c150 ver=f
[  303.320000] Stack from 0149de8c:
[  303.320000]         8001c2c4 0149deb8 00139904 8000c150 00000eb0 00983c00 00000000 00000003
[  303.320000]         00000003 8000bf00 00983a00 0149df40 0013a1fa 00912480 8000bf00 00983c60
[  303.320000]         00000003 00000012 00000000 fffffff8 00000006 d012f728 00000000 00983a5a
[  303.320000]         00000004 00983a00 000579d4 0052b7e8 009125a0 00912480 00983a5a 80000034
[  303.320000]         000d1704 014994c0 80008864 80000000 00000000 80008864 80008864 00000000
[  303.320000]         01497800 00000000 00000034 fffffff8 fffffff8 0149df7c 000e9296 00983a00
[  303.380000] Call Trace: [<00139904>] elf_load+0x192/0x1da
[  303.390000]  [<0013a1fa>] load_elf_binary+0x8ae/0xe46
[  303.400000]  [<000579d4>] try_module_get+0x0/0x48
[  303.410000]  [<000d1704>] kfree+0x0/0x160
[  303.420000]  [<000e9296>] bprm_execve+0x134/0x416
[  303.430000]  [<000e9daa>] copy_string_kernel+0x0/0x184
[  303.440000]  [<000e9fa4>] copy_strings+0x0/0x310
[  303.460000]  [<000ea3f6>] do_execveat_common+0x142/0x1d2
[  303.480000]  [<000eb128>] sys_execve+0x2a/0x36
[  303.490000]  [<0000275e>] syscall+0x8/0xc
[  303.510000]  [<0008c010>] do_read_cache_folio+0xde/0x2c8
[  303.520000] 
[  303.520000] Code: 206e 0008 4282 4a80 6708 0e98 2800 5380 <66f8> 0801 0001 6704 0e58 2800 0801 0000 6704 0e10 2800 241f 4e5e 4e75 4e75 4e56
[  303.560000] Disabling lock debugging due to kernel taint

root@(none):/# 


Also, it appears that the patch Michael posted in this thread would have 
prevented that oops because the "jne 1b" at __clear_user+0x22 would have 
been found in the exception table.




[Index of Archives]     [Video for Linux]     [Yosemite News]     [Linux S/390]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux