• wenlin.kang's avatar
    usb: gadget: printer: fix memory leak · 7e98f600
    wenlin.kang authored
    When read data from g_printer, we see a Segmentation fault. eg:
    
    Unable to handle kernel paging request at virtual address bf048000 pgd
    = cf038000 [bf048000] *pgd=8e8cf811, *pte=00000000, *ppte=00000000
    Internal error: Oops: 7 [#1] PREEMPT ARM Modules linked in: bluetooth
    rfcomm g_printer
    CPU: 0    Not tainted  (3.4.43-WR5.0.1.9_standard #1)
    PC is at __copy_to_user_std+0x310/0x3a8 LR is at 0x4c808010
    pc : [<c036e990>]    lr : [<4c808010>]    psr: 20000013
    sp : cf883ea8  ip : 80801018  fp : cf883f24
    r10: bf04706c  r9 : 18a21205  r8 : 21953888
    r7 : 201588aa  r6 : 5109aa16  r5 : 0705aaa2  r4 : 5140aa8a
    r3 : 0000004c  r2 : 00000fdc  r1 : bf048000  r0 : bef5fc3c
    Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
    Control: 10c5387d  Table: 8f038019  DAC: 00000015 Process
    g_printer_test. (pid: 661, stack limit = 0xcf8822e8)
    Stack: (0xcf883ea8 to 0xcf884000)
    3ea0:                   bf047068 00001fff bef5ecb9 cf882000 00001fff bef5ecb9
    3ec0: 00001fff 00000000 cf2e8724 bf044d3c 80000013 80000013 00000001
    bf04706c
    3ee0: cf883f24 cf883ef0 c012e5ac c0324388 c007c8ac c0046298 00008180
    cf29b900
    3f00: 00002000 bef5ecb8 cf883f68 00000003 cf882000 cf29b900 cf883f54
    cf883f28
    3f20: c012ea08 bf044b0c c000eb88 00000000 cf883f7c 00000000 00000000
    00002000
    3f40: bef5ecb8 00000003 cf883fa4 cf883f58 c012eae8 c012e960 00000001
    bef60cb8
    3f60: 000000a8 c000eb88 00000000 00000000 cf883fa4 00000000 c014329c
    00000000
    3f80: 000000d4 41af63f0 00000003 c000eb88 cf882000 00000000 00000000
    cf883fa8
    3fa0: c000e920 c012eaa4 00000000 000000d4 00000003 bef5ecb8 00002000
    bef5ecb8
    3fc0: 00000000 000000d4 41af63f0 00000003 b6f534c0 00000000 419f9000
    00000000
    3fe0: 00000000 bef5ecac 000086d9 41a986bc 60000010 00000003 0109608a
    0088828a
    Code: f5d1f07c e8b100f0 e1a03c2e e2522020 (e8b15300) ---[ end trace
    97e2618e250e3377 ]--- Segmentation fault
    
    The root cause is the dev->rx_buffers list has been broken.
    When we call printer_read(), the following call tree is triggered:
    
    printer_read()
    	|
    	+---setup_rx_reqs(req)
    	|	|
    	|	+---usb_ep_queue(req)
    	|	|	|
    	|	|	+---...
    	|	|		|
    	|	|		+---rx_complete(req).
    	|	|
    	|	+---add the req to dev->rx_reqs_active
    	|
    	+---while(!list_empty(&dev->rx_buffers)))
    
    The route happens when we don't use DMA or fail to start DMA in USB
    driver. We can see: in the case, in rx_complete() it will add the req
    to dev->rx_buffers. meanwhile we see that we will also add the req to
    dev->rx_reqs_active after usb_ep_queue() return, so this adding will
    break the dev->rx_buffers out.
    
    After, when we call list_empty() to check dev->rx_buffers in while(),
    due to can't check correctly dev->rx_buffers, so the Segmentation fault
    occurs when copy_to_user() is called.
    Signed-off-by: default avatarwenlin.kang <wenlin.kang@windriver.com>
    Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
    7e98f600
printer.c 33.1 KB