mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
usb: gadget: f_hid: fixed NULL pointer dereference
commit 2867652e4766360adf14dfda3832455e04964f2a upstream.
Disconnecting and reconnecting the USB cable can lead to crashes
and a variety of kernel log spam.
The problem was found and reproduced on the Raspberry Pi [1]
and the original fix was created in Raspberry's own fork [2].
Link: https://github.com/raspberrypi/linux/issues/3870 [1]
Link: a6e47d5f4e
[2]
Signed-off-by: Maxim Devaev <mdevaev@gmail.com>
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
Cc: stable <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20210723155928.210019-1-mdevaev@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
2ef2d25cd4
commit
9d25976d99
@ -349,6 +349,11 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
|
||||
|
||||
spin_lock_irqsave(&hidg->write_spinlock, flags);
|
||||
|
||||
if (!hidg->req) {
|
||||
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
||||
return -ESHUTDOWN;
|
||||
}
|
||||
|
||||
#define WRITE_COND (!hidg->write_pending)
|
||||
try_again:
|
||||
/* write queue */
|
||||
@ -369,8 +374,14 @@ try_again:
|
||||
count = min_t(unsigned, count, hidg->report_length);
|
||||
|
||||
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
||||
status = copy_from_user(req->buf, buffer, count);
|
||||
|
||||
if (!req) {
|
||||
ERROR(hidg->func.config->cdev, "hidg->req is NULL\n");
|
||||
status = -ESHUTDOWN;
|
||||
goto release_write_pending;
|
||||
}
|
||||
|
||||
status = copy_from_user(req->buf, buffer, count);
|
||||
if (status != 0) {
|
||||
ERROR(hidg->func.config->cdev,
|
||||
"copy_from_user error\n");
|
||||
@ -398,15 +409,18 @@ try_again:
|
||||
|
||||
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
||||
|
||||
status = usb_ep_queue(hidg->in_ep, req, GFP_ATOMIC);
|
||||
if (status < 0) {
|
||||
ERROR(hidg->func.config->cdev,
|
||||
"usb_ep_queue error on int endpoint %zd\n", status);
|
||||
if (!hidg->in_ep->enabled) {
|
||||
ERROR(hidg->func.config->cdev, "in_ep is disabled\n");
|
||||
status = -ESHUTDOWN;
|
||||
goto release_write_pending;
|
||||
} else {
|
||||
status = count;
|
||||
}
|
||||
|
||||
status = usb_ep_queue(hidg->in_ep, req, GFP_ATOMIC);
|
||||
if (status < 0)
|
||||
goto release_write_pending;
|
||||
else
|
||||
status = count;
|
||||
|
||||
return status;
|
||||
release_write_pending:
|
||||
spin_lock_irqsave(&hidg->write_spinlock, flags);
|
||||
|
Loading…
x
Reference in New Issue
Block a user