NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: port-i386/46338: memcpy/memmove/bcopy kernel panics when hitting page boundary on i386
The following reply was made to PR port-i386/46338; it has been noted by GNATS.
From: Nat Sloss <nathanialsloss%yahoo.com.au@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc:
Subject: Re: port-i386/46338: memcpy/memmove/bcopy kernel panics when hitting
page boundary on i386
Date: Tue, 24 Apr 2012 12:20:00 +1000
Hi.
I had made a mistake the kernel paniced and worst yet so did I.
There is nothing wrong with memcpy, bcopy, or memmove. What causes the crash
is not limited to the i386 but to all platforms that support the ubt usb
bluetooth controller.
I have successfully analyzed and fixed the problem so here's what I've found:
To cause the crash. Whilst using a ubt supported controller attach and open a
bluetooth audio sco connection. Play music/ audio on the sco audio device.
Whilst music is playing on the sco device, switch between X and text sessions,
keep doing this and in about six or so attempts it will crash. Sometimes
control-c interrupting the audio process will cause the crash.
You should then have the following from ddb:
fatal page fault in supervisor mode
trap type 6 code 2 eip c08c9da4 cs 8 eflags 210213 cr2 c52d0000 ilevel 4
kernel: supervisor trap page fault, code=0
Stopped in pid 0.3 (system) at netbsd:memcpy+0x14: repe movsl
(%esi),%
es:(%edi)
db{0}> show registers
ds c0c50010 pv_hash_heads+0x1b3d0
es 10
fs c08c0030 null_extant+0xf8
gs dbe30010
edi c52cfffd
esi dd04792b
ebp dbe3dc50
ebx 11
edx de
ecx 3fff5dc0
eax fffffffb
eip c08c9da4 memcpy+0x14
cs 8
eflags 210213
esp dbe3dbd0
ss 10
netbsd:memcpy+0x14: repe movsl (%esi),%es:(%edi)
db{0}> dmesg 200
emulation)
wsdisplay0: screen 2 added (80x25, vt100 emulation)
wsdisplay0: screen 3 added (80x25, vt100 emulation)
wsdisplay0: screen 4 added (80x25, vt100 emulation)
bthub0 at ubt0 local-bdaddr 00:03:7a:c8:7f:e4
btsco0 at bthub0 remote-bdaddr 50:c9:71:2b:10:6f channel 2
audio2 at btsco0: full duplex, playback, capture
i915drm0: interrupting at ioapic0 pin 16
i915drm0: interrupting at ioapic0 pin 16
fatal page fault in supervisor mode
trap type 6 code 2 eip c08c9da4 cs 8 eflags 210213 cr2 c52d0000 ilevel 4
db{0}> bt
memcpy(c4c59284,c4a77268,0,c081c07a,c0bed420,0,0,0,a,c0c30780) at
netbsd:memcpy+
0x14
usb_transfer_complete(c4c59284,1234,4,a,c44fff80,c4c592d8,c4c592d8,c4c59284,c4c5
296c,c4d57044) at netbsd:usb_transfer_complete+0x18a
uhci_idone.clone.8(c4c592d8,1264,4,a,8,c052c9e1,0,c4b6a000,c0b8dac0,dc376278)
at
netbsd:uhci_idone.clone.8+0xb4
uhci_softintr(c4b6a004,0,0,c0100307,0,10,0,c45e3a80,10,c45e3a80) at
netbsd:uhci_
softintr+0x1a3
softint_dispatch(c45e3d20,4,0,0,ffffffff,ffffffff,dbe3dd90,dbe3dc24,dbe3dc40,0)
a
t netbsd:softint_dispatch+0x72
fatal page fault in supervisor mode
trap type 6 code 0 eip c027eef0 cs 8 eflags 210246 cr2 38 ilevel 8
kernel: supervisor trap page fault, code=0
Faulted in DDB; continuing...
Note the high value of the cx register.
The memcpy (found after extensive testing) is from a callback to
ubt_recv_sco_complete.
In ubt_recv_sco_complete: It either memcopys 'size' or MHLEN - 'got' (if size
+ got is > MHLEN.) So what causes the crash is when got is greater than
MHLEN resulting in an extremely large memcpy length. Which memcpy does until
hitting an unmapped page. So I was actually good that it crashed.
The solution is not to memcpy if got is greater than or equal to MHLEN which
is probably a more succinct test than I used in my patch. I decided it was
also a good idea to test whether size was zero or greater than MHLEN so to
avoid any potential crashes, but I'm not certain that this is necessary.
So here's my patch:
--- ubt.c.orig 2012-04-07 21:28:18.000000000 +1000
+++ ubt.c 2012-04-22 14:51:14.000000000 +1000
@@ -1672,10 +1672,14 @@
if (got + size > want)
size = want - got;
- if (got + size > MHLEN)
+ if (got + size > MHLEN) {
+ if (MHLEN - got > 0 && MHLEN - got <= MHLEN)
memcpy(ptr, frame, MHLEN - got);
- else
- memcpy(ptr, frame, size);
+ }
+ else {
+ if (size > 0 && size <= MHLEN)
+ memcpy(ptr, frame, size);
+ }
ptr += size;
got += size;
This problem affects NetBSD 5 and current, so if considered could NetBSD 5
and 6 be pulled up.
Regards,
Nat.
Home |
Main Index |
Thread Index |
Old Index