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