| From bc8acc214d3f1cafebcbcd101a695bbac716595d Mon Sep 17 00:00:00 2001 |
| From: Jia-Ju Bai <baijiaju1990@gmail.com> |
| Date: Sat, 1 Sep 2018 16:25:08 +0800 |
| Subject: usb: misc: uss720: Fix two sleep-in-atomic-context bugs |
| |
| From: Jia-Ju Bai <baijiaju1990@gmail.com> |
| |
| commit bc8acc214d3f1cafebcbcd101a695bbac716595d upstream. |
| |
| async_complete() in uss720.c is a completion handler function for the |
| USB driver. So it should not sleep, but it is can sleep according to the |
| function call paths (from bottom to top) in Linux-4.16. |
| |
| [FUNC] set_1284_register(GFP_KERNEL) |
| drivers/usb/misc/uss720.c, 372: |
| set_1284_register in parport_uss720_frob_control |
| drivers/parport/ieee1284.c, 560: |
| [FUNC_PTR]parport_uss720_frob_control in parport_ieee1284_ack_data_avail |
| drivers/parport/ieee1284.c, 577: |
| parport_ieee1284_ack_data_avail in parport_ieee1284_interrupt |
| ./include/linux/parport.h, 474: |
| parport_ieee1284_interrupt in parport_generic_irq |
| drivers/usb/misc/uss720.c, 116: |
| parport_generic_irq in async_complete |
| |
| [FUNC] get_1284_register(GFP_KERNEL) |
| drivers/usb/misc/uss720.c, 382: |
| get_1284_register in parport_uss720_read_status |
| drivers/parport/ieee1284.c, 555: |
| [FUNC_PTR]parport_uss720_read_status in parport_ieee1284_ack_data_avail |
| drivers/parport/ieee1284.c, 577: |
| parport_ieee1284_ack_data_avail in parport_ieee1284_interrupt |
| ./include/linux/parport.h, 474: |
| parport_ieee1284_interrupt in parport_generic_irq |
| drivers/usb/misc/uss720.c, 116: |
| parport_generic_irq in async_complete |
| |
| Note that [FUNC_PTR] means a function pointer call is used. |
| |
| To fix these bugs, GFP_KERNEL is replaced with GFP_ATOMIC. |
| |
| These bugs are found by my static analysis tool DSAC. |
| |
| Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com> |
| Cc: stable <stable@vger.kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/usb/misc/uss720.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/usb/misc/uss720.c |
| +++ b/drivers/usb/misc/uss720.c |
| @@ -369,7 +369,7 @@ static unsigned char parport_uss720_frob |
| mask &= 0x0f; |
| val &= 0x0f; |
| d = (priv->reg[1] & (~mask)) ^ val; |
| - if (set_1284_register(pp, 2, d, GFP_KERNEL)) |
| + if (set_1284_register(pp, 2, d, GFP_ATOMIC)) |
| return 0; |
| priv->reg[1] = d; |
| return d & 0xf; |
| @@ -379,7 +379,7 @@ static unsigned char parport_uss720_read |
| { |
| unsigned char ret; |
| |
| - if (get_1284_register(pp, 1, &ret, GFP_KERNEL)) |
| + if (get_1284_register(pp, 1, &ret, GFP_ATOMIC)) |
| return 0; |
| return ret & 0xf8; |
| } |