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
3fcff11317
commit
3eaf580cba
@@ -138,39 +138,10 @@ static void sz_push_half_space(struct streamzap_ir *sz,
|
||||
sz_push_full_space(sz, value & SZ_SPACE_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
static void sz_process_ir_data(struct streamzap_ir *sz, int len)
|
||||
{
|
||||
struct streamzap_ir *sz;
|
||||
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++) {
|
||||
dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n",
|
||||
i, (unsigned char)sz->buf_in[i]);
|
||||
@@ -219,6 +190,43 @@ static void streamzap_callback(struct urb *urb)
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user