lkml.org 
[lkml]   [2020]   [Feb]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.5 075/542] usb: gadget: udc: fix possible sleep-in-atomic-context bugs in gr_probe()
    Date
    From: Jia-Ju Bai <baijiaju1990@gmail.com>

    [ Upstream commit 9c1ed62ae0690dfe5d5e31d8f70e70a95cb48e52 ]

    The driver may sleep while holding a spinlock.
    The function call path (from bottom to top) in Linux 4.19 is:

    drivers/usb/gadget/udc/core.c, 1175:
    kzalloc(GFP_KERNEL) in usb_add_gadget_udc_release
    drivers/usb/gadget/udc/core.c, 1272:
    usb_add_gadget_udc_release in usb_add_gadget_udc
    drivers/usb/gadget/udc/gr_udc.c, 2186:
    usb_add_gadget_udc in gr_probe
    drivers/usb/gadget/udc/gr_udc.c, 2183:
    spin_lock in gr_probe

    drivers/usb/gadget/udc/core.c, 1195:
    mutex_lock in usb_add_gadget_udc_release
    drivers/usb/gadget/udc/core.c, 1272:
    usb_add_gadget_udc_release in usb_add_gadget_udc
    drivers/usb/gadget/udc/gr_udc.c, 2186:
    usb_add_gadget_udc in gr_probe
    drivers/usb/gadget/udc/gr_udc.c, 2183:
    spin_lock in gr_probe

    drivers/usb/gadget/udc/gr_udc.c, 212:
    debugfs_create_file in gr_probe
    drivers/usb/gadget/udc/gr_udc.c, 2197:
    gr_dfs_create in gr_probe
    drivers/usb/gadget/udc/gr_udc.c, 2183:
    spin_lock in gr_probe

    drivers/usb/gadget/udc/gr_udc.c, 2114:
    devm_request_threaded_irq in gr_request_irq
    drivers/usb/gadget/udc/gr_udc.c, 2202:
    gr_request_irq in gr_probe
    drivers/usb/gadget/udc/gr_udc.c, 2183:
    spin_lock in gr_probe

    kzalloc(GFP_KERNEL), mutex_lock(), debugfs_create_file() and
    devm_request_threaded_irq() can sleep at runtime.

    To fix these possible bugs, usb_add_gadget_udc(), gr_dfs_create() and
    gr_request_irq() are called without handling the spinlock.

    These bugs are found by a static analysis tool STCheck written by myself.

    Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
    Signed-off-by: Felipe Balbi <balbi@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/usb/gadget/udc/gr_udc.c | 16 +++++++++-------
    1 file changed, 9 insertions(+), 7 deletions(-)

    diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c
    index 64d80c65bb967..aaf975c809bf9 100644
    --- a/drivers/usb/gadget/udc/gr_udc.c
    +++ b/drivers/usb/gadget/udc/gr_udc.c
    @@ -2175,8 +2175,6 @@ static int gr_probe(struct platform_device *pdev)
    return -ENOMEM;
    }

    - spin_lock(&dev->lock);
    -
    /* Inside lock so that no gadget can use this udc until probe is done */
    retval = usb_add_gadget_udc(dev->dev, &dev->gadget);
    if (retval) {
    @@ -2185,15 +2183,21 @@ static int gr_probe(struct platform_device *pdev)
    }
    dev->added = 1;

    + spin_lock(&dev->lock);
    +
    retval = gr_udc_init(dev);
    - if (retval)
    + if (retval) {
    + spin_unlock(&dev->lock);
    goto out;
    -
    - gr_dfs_create(dev);
    + }

    /* Clear all interrupt enables that might be left on since last boot */
    gr_disable_interrupts_and_pullup(dev);

    + spin_unlock(&dev->lock);
    +
    + gr_dfs_create(dev);
    +
    retval = gr_request_irq(dev, dev->irq);
    if (retval) {
    dev_err(dev->dev, "Failed to request irq %d\n", dev->irq);
    @@ -2222,8 +2226,6 @@ static int gr_probe(struct platform_device *pdev)
    dev_info(dev->dev, "regs: %p, irq %d\n", dev->regs, dev->irq);

    out:
    - spin_unlock(&dev->lock);
    -
    if (retval)
    gr_remove(pdev);

    --
    2.20.1
    \
     
     \ /
      Last update: 2020-02-14 16:51    [W:2.633 / U:0.988 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site