mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
media: streamzap: prevent processing IR data on URB failure
commit 549f6d348167fb2f7800ed7c8d4bce9630c74498 upstream.
If streamzap_callback() receives an urb with any non-critical error
status, i.e. any error code other than -ECONNRESET, -ENOENT or -ESHUTDOWN,
it will try to process IR data, ignoring a possible transfer failure.
Make streamzap_callback() process IR data only when urb->status is 0.
Move processing logic to a separate function to make code cleaner and
more similar to the URB completion handlers in other RC drivers.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Fixes: 19770693c3 ("V4L/DVB: staging/lirc: add lirc_streamzap driver")
Cc: stable@vger.kernel.org
Signed-off-by: Murad Masimov <m.masimov@mt-integration.ru>
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
a3f4d28273
commit
b31a8ec0d8
@@ -138,39 +138,10 @@ static void sz_push_half_space(struct streamzap_ir *sz,
|
|||||||
sz_push_full_space(sz, value & SZ_SPACE_MASK);
|
sz_push_full_space(sz, value & SZ_SPACE_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void sz_process_ir_data(struct streamzap_ir *sz, int len)
|
||||||
* streamzap_callback - usb IRQ handler callback
|
|
||||||
*
|
|
||||||
* This procedure is invoked on reception of data from
|
|
||||||
* the usb remote.
|
|
||||||
*/
|
|
||||||
static void streamzap_callback(struct urb *urb)
|
|
||||||
{
|
{
|
||||||
struct streamzap_ir *sz;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int len;
|
|
||||||
|
|
||||||
if (!urb)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sz = urb->context;
|
|
||||||
len = urb->actual_length;
|
|
||||||
|
|
||||||
switch (urb->status) {
|
|
||||||
case -ECONNRESET:
|
|
||||||
case -ENOENT:
|
|
||||||
case -ESHUTDOWN:
|
|
||||||
/*
|
|
||||||
* this urb is terminated, clean up.
|
|
||||||
* sz might already be invalid at this point
|
|
||||||
*/
|
|
||||||
dev_err(sz->dev, "urb terminated, status: %d\n", urb->status);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n",
|
dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n",
|
||||||
i, (unsigned char)sz->buf_in[i]);
|
i, (unsigned char)sz->buf_in[i]);
|
||||||
@@ -219,6 +190,43 @@ static void streamzap_callback(struct urb *urb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ir_raw_event_handle(sz->rdev);
|
ir_raw_event_handle(sz->rdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* streamzap_callback - usb IRQ handler callback
|
||||||
|
*
|
||||||
|
* This procedure is invoked on reception of data from
|
||||||
|
* the usb remote.
|
||||||
|
*/
|
||||||
|
static void streamzap_callback(struct urb *urb)
|
||||||
|
{
|
||||||
|
struct streamzap_ir *sz;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (!urb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sz = urb->context;
|
||||||
|
len = urb->actual_length;
|
||||||
|
|
||||||
|
switch (urb->status) {
|
||||||
|
case 0:
|
||||||
|
dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
|
||||||
|
sz_process_ir_data(sz, len);
|
||||||
|
break;
|
||||||
|
case -ECONNRESET:
|
||||||
|
case -ENOENT:
|
||||||
|
case -ESHUTDOWN:
|
||||||
|
/*
|
||||||
|
* this urb is terminated, clean up.
|
||||||
|
* sz might already be invalid at this point
|
||||||
|
*/
|
||||||
|
dev_err(sz->dev, "urb terminated, status: %d\n", urb->status);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
usb_submit_urb(urb, GFP_ATOMIC);
|
usb_submit_urb(urb, GFP_ATOMIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user