libusb Trac | 1 Jun 2012 10:24
Favicon

[libusb] #131: Some application programs ( gqrx, gnuradio ) crash with libusb-1.0.9

#131: Some application programs ( gqrx, gnuradio ) crash with libusb-1.0.9
---------------------------------------+----------------
  Reporter:  dl1ksv                    |     Owner:
      Type:  defect                    |    Status:  new
 Component:  libusb-1.0 Linux backend  |  Keywords:
Blocked By:                            |    Blocks:
---------------------------------------+----------------
 Some application programs that run with libusb-1.0.8 without problems
 crash with libusb-1.0.9 ( Segmentation fault )[[BR]]
 The system is a gentoo linux 64 bit, kernel 3.3.5, gcc 4.5.3
 The backtrace shows[[BR]]
 {{{
 Program terminated with signal 11, Segmentation fault.
 #0  0x00007f23d2014a44 in add_to_flying_list (transfer=0x7f23c4000910) at
 io.c:1185
 1185if (!timerisset(cur_tv) || (cur_tv->tv_sec > timeout->tv_sec) ||
 (gdb) bt
 #0  0x00007f23d2014a44 in add_to_flying_list (transfer=0x7f23c4000910) at
 io.c:1185
 #1  0x00007f23d2014cc3 in libusb_submit_transfer (transfer=0x7f23c4000968)
 at io.c:1305
 #2  0x00007f23d66853fc in read_thread (param=0x18abd50) at
 /gnuradiocomponents/gnuradio/gr-fcd/lib/hid/hid-libusb.c:697
 #3  0x00007f23d4614f26 in start_thread () from /lib64/libpthread.so.0
 #4  0x00007f23d3b37a4d in clone () from /lib64/libc.so.6

 (gdb) p cur
 $1 = (struct usbi_transfer *) 0xfffffffffffffff8

 (gdb) p ctx->flying_transfers
 $2 = {prev = 0x7f23c4000078, next = 0x7f23c4000918}
 (gdb) p ctx->flying_transfers->next
 $3 = (struct list_head *) 0x7f23c4000918
 (gdb) p ctx->flying_transfers->next->next
 $4 = (struct list_head *) 0x0

 }}}

 It seems that the end of the list is not recognized in the
 list_for_each_entry loop.

 I have no ideas why this happens in 1.0.9 but not in 1.0.8.

 I possible solution that avoids the crash:

 Replace
 {{{
 #define list_for_each_entry(pos, head, member, type)
     for (pos = list_entry((head)->next, type, member);[[BR]]
       &pos->member!=(head);
        pos = list_entry(pos->member.next, type, member))
 }}}
 by
 {{{
 #define list_for_each_entry(pos, head, member, type)
     for (pos = list_entry((head)->next, type, member);[[BR]]
       (&pos->member!=(head)) &&(pos->member.next != 0 );
        pos = list_entry(pos->member.next, type, member))
 }}}

--

-- 
Ticket URL: <http://libusb.org/ticket/131>
libusb <http://libusb.org/>
C library for writing portable USB drivers in userspace
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/

Gmane