2021-05-24 11:11:17

by Johan Hovold

[permalink] [raw]
Subject: [PATCH 0/3] media: fix zero-length USB control requests

The direction of the pipe argument must match the request-type direction
bit or control requests may fail depending on the host-controller-driver
implementation.

Control transfers without a data stage are treated as OUT requests by
the USB stack and should be using usb_sndctrlpipe(). Failing to do so
will now trigger a warning.

This series fixes the three media drivers that got this wrong.

Johan


Johan Hovold (3):
media: gspca/gl860: fix zero-length control requests
media: gspca/sunplus: fix zero-length control requests
media: rtl28xxu: fix zero-length control request

drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 3 ++-
drivers/media/usb/gspca/gl860/gl860.c | 4 ++--
drivers/media/usb/gspca/sunplus.c | 8 ++++++--
3 files changed, 10 insertions(+), 5 deletions(-)

--
2.26.3


2021-05-24 11:12:02

by Johan Hovold

[permalink] [raw]
Subject: [PATCH 3/3] media: rtl28xxu: fix zero-length control request

The direction of the pipe argument must match the request-type direction
bit or control requests may fail depending on the host-controller-driver
implementation.

Control transfers without a data stage are treated as OUT requests by
the USB stack and should be using usb_sndctrlpipe(). Failing to do so
will now trigger a warning.

Fix the zero-length i2c-read request used for type detection by
attempting to read a single byte instead.

Reported-by: [email protected]
Fixes: d0f232e823af ("[media] rtl28xxu: add heuristic to detect chip type")
Cc: [email protected] # 4.0
Cc: Antti Palosaari <[email protected]>
Signed-off-by: Johan Hovold <[email protected]>
---
drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index 97ed17a141bb..2c04ed8af0e4 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -612,8 +612,9 @@ static int rtl28xxu_read_config(struct dvb_usb_device *d)
static int rtl28xxu_identify_state(struct dvb_usb_device *d, const char **name)
{
struct rtl28xxu_dev *dev = d_to_priv(d);
+ u8 buf[1];
int ret;
- struct rtl28xxu_req req_demod_i2c = {0x0020, CMD_I2C_DA_RD, 0, NULL};
+ struct rtl28xxu_req req_demod_i2c = {0x0020, CMD_I2C_DA_RD, 1, buf};

dev_dbg(&d->intf->dev, "\n");

--
2.26.3

2021-05-24 11:12:23

by Johan Hovold

[permalink] [raw]
Subject: [PATCH 1/3] media: gspca/gl860: fix zero-length control requests

The direction of the pipe argument must match the request-type direction
bit or control requests may fail depending on the host-controller-driver
implementation.

Control transfers without a data stage are treated as OUT requests by
the USB stack and should be using usb_sndctrlpipe(). Failing to do so
will now trigger a warning.

Fix the gl860_RTx() helper so that zero-length control reads fail with
an error message instead. Note that there are no current callers that
would trigger this.

Fixes: 4f7cb8837cec ("V4L/DVB (12954): gspca - gl860: Addition of GL860 based webcams")
Signed-off-by: Johan Hovold <[email protected]>
---
drivers/media/usb/gspca/gl860/gl860.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/gspca/gl860/gl860.c b/drivers/media/usb/gspca/gl860/gl860.c
index 2c05ea2598e7..ce4ee8bc75c8 100644
--- a/drivers/media/usb/gspca/gl860/gl860.c
+++ b/drivers/media/usb/gspca/gl860/gl860.c
@@ -561,8 +561,8 @@ int gl860_RTx(struct gspca_dev *gspca_dev,
len, 400 + 200 * (len > 1));
memcpy(pdata, gspca_dev->usb_buf, len);
} else {
- r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- req, pref, val, index, NULL, len, 400);
+ gspca_err(gspca_dev, "zero-length read request\n");
+ r = -EINVAL;
}
}

--
2.26.3

2021-05-24 11:14:37

by Johan Hovold

[permalink] [raw]
Subject: [PATCH 2/3] media: gspca/sunplus: fix zero-length control requests

The direction of the pipe argument must match the request-type direction
bit or control requests may fail depending on the host-controller-driver
implementation.

Control transfers without a data stage are treated as OUT requests by
the USB stack and should be using usb_sndctrlpipe(). Failing to do so
will now trigger a warning.

Fix the single zero-length control request which was using the
read-register helper, and update the helper so that zero-length reads
fail with an error message instead.

Fixes: 6a7eba24e4f0 ("V4L/DVB (8157): gspca: all subdrivers")
Cc: [email protected] # 2.6.27
Signed-off-by: Johan Hovold <[email protected]>
---
drivers/media/usb/gspca/sunplus.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/gspca/sunplus.c b/drivers/media/usb/gspca/sunplus.c
index ace3da40006e..971dee0a56da 100644
--- a/drivers/media/usb/gspca/sunplus.c
+++ b/drivers/media/usb/gspca/sunplus.c
@@ -242,6 +242,10 @@ static void reg_r(struct gspca_dev *gspca_dev,
gspca_err(gspca_dev, "reg_r: buffer overflow\n");
return;
}
+ if (len == 0) {
+ gspca_err(gspca_dev, "reg_r: zero-length read\n");
+ return;
+ }
if (gspca_dev->usb_err < 0)
return;
ret = usb_control_msg(gspca_dev->dev,
@@ -250,7 +254,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index,
- len ? gspca_dev->usb_buf : NULL, len,
+ gspca_dev->usb_buf, len,
500);
if (ret < 0) {
pr_err("reg_r err %d\n", ret);
@@ -727,7 +731,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
case MegaImageVI:
reg_w_riv(gspca_dev, 0xf0, 0, 0);
spca504B_WaitCmdStatus(gspca_dev);
- reg_r(gspca_dev, 0xf0, 4, 0);
+ reg_w_riv(gspca_dev, 0xf0, 4, 0);
spca504B_WaitCmdStatus(gspca_dev);
break;
default:
--
2.26.3

2021-05-31 07:57:22

by Johan Hovold

[permalink] [raw]
Subject: Re: [PATCH 3/3] media: rtl28xxu: fix zero-length control request

On Mon, May 24, 2021 at 01:09:20PM +0200, Johan Hovold wrote:
> The direction of the pipe argument must match the request-type direction
> bit or control requests may fail depending on the host-controller-driver
> implementation.
>
> Control transfers without a data stage are treated as OUT requests by
> the USB stack and should be using usb_sndctrlpipe(). Failing to do so
> will now trigger a warning.
>
> Fix the zero-length i2c-read request used for type detection by
> attempting to read a single byte instead.
>
> Reported-by: [email protected]
> Fixes: d0f232e823af ("[media] rtl28xxu: add heuristic to detect chip type")
> Cc: [email protected] # 4.0
> Cc: Antti Palosaari <[email protected]>
> Signed-off-by: Johan Hovold <[email protected]>
> ---
> drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
> index 97ed17a141bb..2c04ed8af0e4 100644
> --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
> +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
> @@ -612,8 +612,9 @@ static int rtl28xxu_read_config(struct dvb_usb_device *d)
> static int rtl28xxu_identify_state(struct dvb_usb_device *d, const char **name)
> {
> struct rtl28xxu_dev *dev = d_to_priv(d);
> + u8 buf[1];
> int ret;
> - struct rtl28xxu_req req_demod_i2c = {0x0020, CMD_I2C_DA_RD, 0, NULL};
> + struct rtl28xxu_req req_demod_i2c = {0x0020, CMD_I2C_DA_RD, 1, buf};
>
> dev_dbg(&d->intf->dev, "\n");

As reported here

https://lore.kernel.org/r/[email protected]

this patch is causing the chip type to no longer be detected correctly,
so please drop this one for now until this has been resolved.

Johan

2021-06-07 07:38:43

by Johan Hovold

[permalink] [raw]
Subject: Re: [PATCH 3/3] media: rtl28xxu: fix zero-length control request

On Mon, May 31, 2021 at 09:55:39AM +0200, Johan Hovold wrote:
> On Mon, May 24, 2021 at 01:09:20PM +0200, Johan Hovold wrote:
> > The direction of the pipe argument must match the request-type direction
> > bit or control requests may fail depending on the host-controller-driver
> > implementation.
> >
> > Control transfers without a data stage are treated as OUT requests by
> > the USB stack and should be using usb_sndctrlpipe(). Failing to do so
> > will now trigger a warning.
> >
> > Fix the zero-length i2c-read request used for type detection by
> > attempting to read a single byte instead.
> >
> > Reported-by: [email protected]
> > Fixes: d0f232e823af ("[media] rtl28xxu: add heuristic to detect chip type")
> > Cc: [email protected] # 4.0
> > Cc: Antti Palosaari <[email protected]>
> > Signed-off-by: Johan Hovold <[email protected]>
> > ---
> > drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 3 ++-
> > 1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
> > index 97ed17a141bb..2c04ed8af0e4 100644
> > --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
> > +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
> > @@ -612,8 +612,9 @@ static int rtl28xxu_read_config(struct dvb_usb_device *d)
> > static int rtl28xxu_identify_state(struct dvb_usb_device *d, const char **name)
> > {
> > struct rtl28xxu_dev *dev = d_to_priv(d);
> > + u8 buf[1];
> > int ret;
> > - struct rtl28xxu_req req_demod_i2c = {0x0020, CMD_I2C_DA_RD, 0, NULL};
> > + struct rtl28xxu_req req_demod_i2c = {0x0020, CMD_I2C_DA_RD, 1, buf};
> >
> > dev_dbg(&d->intf->dev, "\n");
>
> As reported here
>
> https://lore.kernel.org/r/[email protected]
>
> this patch is causing the chip type to no longer be detected correctly,
> so please drop this one for now until this has been resolved.

Looks like this one was applied to the media tree a couple of days after
I sent this nonetheless.

Can you drop this one in favour of the v2 posted here:

https://lore.kernel.org/r/[email protected]

or do you want me to send an incremental fix instead?

Johan