one time crash in usb_allocmem_flags

2014-02-09 Thread Alexander Nasonov
Hi,

I was running current amd64 (last updated few weeks ago) when I got
a random crash shortly after switching to X mode. If my analysis is
correct, it crashed in usb_allocmem_flags inside this loop:

LIST_FOREACH(f, &usb_frag_freelist, next) {
KDASSERTMSG(usb_valid_block_p(f->block, &usb_blk_fraglist),
"%s: usb frag %p: unknown block pointer %p",
 __func__, f, f->block);
if (f->block->tag == tag)
break;
}

It couldn't access f->block->tag. I wasn't actively using any of
the usb devices at that time. I wonder if it's a known problem or
should I file a PR? Details of the analysis is below.

Thanks,
Alex

crash> dmesg
...
fatal protection fault in supervisor mode
trap type 4 code 0 rip 808515e2 cs 8 rflags 13282 cr2
7f7ff5773020 ilevel 0 rsp fe80ca6f16c0
curlwp 0xfe811a8aaba0 pid 475.1 lowest kstack 0xfe80ca6ee000
panic: trap
cpu2: Begin traceback...
vpanic() at netbsd:vpanic+0x13e
printf_nolog() at netbsd:printf_nolog
startlwp() at netbsd:startlwp
alltraps() at netbsd:alltraps+0x9e
ehci_allocm() at netbsd:ehci_allocm+0x2c
usbd_transfer() at netbsd:usbd_transfer+0x5f
usbd_open_pipe_intr() at netbsd:usbd_open_pipe_intr+0xcb
uhidev_open() at netbsd:uhidev_open+0xb3
wsmouseopen() at netbsd:wsmouseopen+0xf3
cdev_open() at netbsd:cdev_open+0x87
spec_open() at netbsd:spec_open+0x183
VOP_OPEN() at netbsd:VOP_OPEN+0x33
vn_open() at netbsd:vn_open+0x1b0
do_open() at netbsd:do_open+0x102
do_sys_openat() at netbsd:do_sys_openat+0x68
sys_open() at netbsd:sys_open+0x24
syscall() at netbsd:syscall+0x9a
--- syscall (number 5) ---
7f7ff403af3a:
cpu2: End traceback...
rebooting in 10 9 8 7 6 5 4 3 2 1 0

crash> dmesg|grep usb
usb0 at xhci0: USB revision 2.0
usb1 at ehci0: USB revision 2.0
uhub0 at usb0: NetBSD xHCI Root Hub, class 9/0, rev 2.00/1.00, addr 0
uhub1 at usb1: vendor 0x8086 EHCI root hub, class 9/0, rev 2.00/1.00,
addr 1
usbd_transfer() at netbsd:usbd_transfer+0x5f
usbd_open_pipe_intr() at netbsd:usbd_open_pipe_intr+0xcb

crash> x 0x808515e2
usb_allocmem_flags+0xfd:751a3948


$ objdump -d /netbsd
...
8085158b:   48 c7 c7 60 15 f8 80mov$0x80f81560,%rdi
80851592:   e8 69 42 d3 ff  callq  80585800 

80851597:   48 8b 05 c2 bf 69 00mov0x69bfc2(%rip),%rax  
  # 80eed560 
8085159e:   48 85 c0test   %rax,%rax
808515a1:   75 3c   jne808515df 


/* You don't need to look at this block */
808515a3:   48 8d 4d c8 lea-0x38(%rbp),%rcx
808515a7:   45 31 c0xor%r8d,%r8d
808515aa:   ba 40 00 00 00  mov$0x40,%edx
808515af:   be 00 10 00 00  mov$0x1000,%esi
808515b4:   48 89 dfmov%rbx,%rdi
808515b7:   e8 f4 fb ff ff  callq  808511b0 

808515bc:   89 c3   mov%eax,%ebx
808515be:   85 c0   test   %eax,%eax
808515c0:   75 ac   jne8085156e 

808515c2:   48 8b 4d c8 mov-0x38(%rbp),%rcx
808515c6:   c7 41 38 00 00 00 00movl   $0x0,0x38(%rcx)
808515cd:   bb 40 00 00 00  mov$0x40,%ebx
808515d2:   31 d2   xor%edx,%edx
808515d4:   eb 57   jmp8085162d 

/* end of block. */

/*  LIST_FOREACH(f, &usb_frag_freelist, next) { */
808515d6:   48 8b 40 10 mov0x10(%rax),%rax
808515da:   48 85 c0test   %rax,%rax
808515dd:   74 c4   je 808515a3 

808515df:   48 8b 10mov(%rax),%rdx
808515e2:   48 39 1acmp%rbx,(%rdx)
808515e5:   75 ef   jne808515d6 



crash> ps
PIDLID S CPU FLAGS   STRUCT LWP *   NAME WAIT
475  >   1 7   2 0   fe811a8aaba0   Xorg
72   1 2   3   902   fe811a709b80  xinit
43   1 2   3   802   fe811a709760 sh
437  1 2   3   802   fe811d311720ksh
420  1 2   2   802   fe811e2b6240  getty
435  1 2   0   802   fe811e2b6a80  getty
429  1 2   3   802   fe811e2b6660  login
412  1 2   0   802   fe811e4c1220  getty
390  1 2   0   802   fe8119a90b60   cron
407  1 2   0   802   fe811d767b00  inetd
342  1 2   3   802   fe811d311300privoxy
357  1 2   3   802   fe811c3b9b20   sshd
332  >   1 7   0   802   fe811d7812a0tor
31

Re: one time crash in usb_allocmem_flags

2014-02-10 Thread Nick Hudson

On 02/09/14 19:48, Alexander Nasonov wrote:

Hi,

I was running current amd64 (last updated few weeks ago) when I got
a random crash shortly after switching to X mode. If my analysis is
correct, it crashed in usb_allocmem_flags inside this loop:

 LIST_FOREACH(f, &usb_frag_freelist, next) {
 KDASSERTMSG(usb_valid_block_p(f->block, &usb_blk_fraglist),
 "%s: usb frag %p: unknown block pointer %p",
  __func__, f, f->block);
 if (f->block->tag == tag)
 break;
 }

It couldn't access f->block->tag. I wasn't actively using any of
the usb devices at that time. I wonder if it's a known problem or
should I file a PR? Details of the analysis is below.


Please fill a PR so it doesn't get forgotten about.

At first glance it doesn't look like that usb_frag_freelist isn't 
protected correctly. I looks more like random corruption. What was the 
value of %edx?


Thanks,
Nick



Re: one time crash in usb_allocmem_flags

2014-02-10 Thread Alexander Nasonov
10.02.14, 12:15, "Nick Hudson" ":
> 
> Please fill a PR so it doesn't get forgotten about.

Sure, will do.

> 
> At first glance it doesn't look like that usb_frag_freelist isn't 
> protected correctly. I looks more like random corruption. What was the 
> value of %edx?

The stack isn't in that function anymore, I'm not sure it shows the right 
values. 'show registers' command prints all zeroes except rbp=fe80ca6f1450 
and rsp=fe80ca6f1410.

-- 
Alex