drivers/usb/host/max3421-hcd.c | 4 ++++ 1 file changed, 4 insertions(+)
From: Seungjin Bae <eeodqql09@gmail.com>
So if a malicious userspace task with access to the root hub via
/dev/bus/usb/.../001 issues a USBDEVFS_CONTROL ioctl with `wValue`
greater than or equal to 32, the left shift operation invokes
shift-out-of-bounds undefined behavior. This results in arbitrary
bit corruption of `port_status`, including the normally-immutable
change bits, which can bypass internal state checks and confuse the
hub status.
Fix this by rejecting requests whose `value` exceeds the shift width
before performing the shift.
Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.")
Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
---
drivers/usb/host/max3421-hcd.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
index 0e17c988d36a..3d6b351dcb1a 100644
--- a/drivers/usb/host/max3421-hcd.c
+++ b/drivers/usb/host/max3421-hcd.c
@@ -1694,6 +1694,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
!pdata->vbus_active_level);
fallthrough;
default:
+ if (value >= 32)
+ goto error;
max3421_hcd->port_status &= ~(1 << value);
}
break;
@@ -1747,6 +1749,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
max3421_reset_port(hcd);
fallthrough;
default:
+ if (value >= 32)
+ goto error;
if ((max3421_hcd->port_status & USB_PORT_STAT_POWER)
!= 0)
max3421_hcd->port_status |= (1 << value);
--
2.43.0
On Sat, May 16, 2026 at 08:01:46PM -0400, pip-izony wrote:
> From: Seungjin Bae <eeodqql09@gmail.com>
>
> So if a malicious userspace task with access to the root hub via
> /dev/bus/usb/.../001 issues a USBDEVFS_CONTROL ioctl with `wValue`
> greater than or equal to 32, the left shift operation invokes
> shift-out-of-bounds undefined behavior. This results in arbitrary
> bit corruption of `port_status`, including the normally-immutable
> change bits, which can bypass internal state checks and confuse the
> hub status.
>
> Fix this by rejecting requests whose `value` exceeds the shift width
> before performing the shift.
>
> Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.")
> Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
> ---
> drivers/usb/host/max3421-hcd.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
> index 0e17c988d36a..3d6b351dcb1a 100644
> --- a/drivers/usb/host/max3421-hcd.c
> +++ b/drivers/usb/host/max3421-hcd.c
> @@ -1694,6 +1694,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
> !pdata->vbus_active_level);
> fallthrough;
> default:
> + if (value >= 32)
> + goto error;
Cool, what tool found this? I've been running some static checkers and
I don't think it turned this one up yet.
thanks,
greg k-h
2026년 5월 17일 (일) 오전 1:49, Greg Kroah-Hartman <gregkh@linuxfoundation.org>님이 작성:
>
> On Sat, May 16, 2026 at 08:01:46PM -0400, pip-izony wrote:
> > From: Seungjin Bae <eeodqql09@gmail.com>
> >
> > So if a malicious userspace task with access to the root hub via
> > /dev/bus/usb/.../001 issues a USBDEVFS_CONTROL ioctl with `wValue`
> > greater than or equal to 32, the left shift operation invokes
> > shift-out-of-bounds undefined behavior. This results in arbitrary
> > bit corruption of `port_status`, including the normally-immutable
> > change bits, which can bypass internal state checks and confuse the
> > hub status.
> >
> > Fix this by rejecting requests whose `value` exceeds the shift width
> > before performing the shift.
> >
> > Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.")
> > Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
> > ---
> > drivers/usb/host/max3421-hcd.c | 4 ++++
> > 1 file changed, 4 insertions(+)
> >
> > diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
> > index 0e17c988d36a..3d6b351dcb1a 100644
> > --- a/drivers/usb/host/max3421-hcd.c
> > +++ b/drivers/usb/host/max3421-hcd.c
> > @@ -1694,6 +1694,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
> > !pdata->vbus_active_level);
> > fallthrough;
> > default:
> > + if (value >= 32)
> > + goto error;
>
> Cool, what tool found this? I've been running some static checkers and
> I don't think it turned this one up yet.
>
> thanks,
>
> greg k-h
Thanks for your interest!
It's a KLEE-based symbolic execution tool I've been developing for
kernel drivers. It's still a work in progress, but I'd be happy to
share more details and the tool itself once it's in better shape.
Seungjin Bae
On Sun, May 17, 2026 at 02:19:07PM -0400, Seungjin Bae wrote:
> 2026년 5월 17일 (일) 오전 1:49, Greg Kroah-Hartman <gregkh@linuxfoundation.org>님이 작성:
> >
> > On Sat, May 16, 2026 at 08:01:46PM -0400, pip-izony wrote:
> > > From: Seungjin Bae <eeodqql09@gmail.com>
> > >
> > > So if a malicious userspace task with access to the root hub via
> > > /dev/bus/usb/.../001 issues a USBDEVFS_CONTROL ioctl with `wValue`
> > > greater than or equal to 32, the left shift operation invokes
> > > shift-out-of-bounds undefined behavior. This results in arbitrary
> > > bit corruption of `port_status`, including the normally-immutable
> > > change bits, which can bypass internal state checks and confuse the
> > > hub status.
> > >
> > > Fix this by rejecting requests whose `value` exceeds the shift width
> > > before performing the shift.
> > >
> > > Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.")
> > > Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
> > > ---
> > > drivers/usb/host/max3421-hcd.c | 4 ++++
> > > 1 file changed, 4 insertions(+)
> > >
> > > diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
> > > index 0e17c988d36a..3d6b351dcb1a 100644
> > > --- a/drivers/usb/host/max3421-hcd.c
> > > +++ b/drivers/usb/host/max3421-hcd.c
> > > @@ -1694,6 +1694,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
> > > !pdata->vbus_active_level);
> > > fallthrough;
> > > default:
> > > + if (value >= 32)
> > > + goto error;
> >
> > Cool, what tool found this? I've been running some static checkers and
> > I don't think it turned this one up yet.
> >
> > thanks,
> >
> > greg k-h
>
> Thanks for your interest!
>
> It's a KLEE-based symbolic execution tool I've been developing for
> kernel drivers. It's still a work in progress, but I'd be happy to
> share more details and the tool itself once it's in better shape.
As per our documentation, you MUST document the fact that you are using
a tool to find/fix things. Please fix up our newly submitted patches to
include that information.
thanks,
greg k-h
From: Seungjin Bae <eeodqql09@gmail.com>
The `max3421_hub_control()` function handles USB hub class requests
to the virtual root hub. In the `default` branches of both the
`ClearPortFeature` and `SetPortFeature` switch statements, it modifies
`max3421_hcd->port_status` by left shifting 1 by the request's `value`
parameter. However, it does not validate whether this shift will exceed
the width of `port_status`.
So if a malicious userspace task with access to the root hub via
/dev/bus/usb/.../001 issues a USBDEVFS_CONTROL ioctl with `wValue`
greater than or equal to 32, the left shift operation invokes
shift-out-of-bounds undefined behavior. This results in arbitrary
bit corruption of `port_status`, including the normally-immutable
change bits, which can bypass internal state checks and confuse the
hub status.
Fix this by rejecting requests whose `value` exceeds the shift width
before performing the shift.
Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.")
Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
---
v1 -> v2: Restored a paragraph in the commit message that was truncated.
v2 -> v3: No functional changes; reorganized as part of a 2-patch series.
drivers/usb/host/max3421-hcd.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
index 0e17c988d36a..3d6b351dcb1a 100644
--- a/drivers/usb/host/max3421-hcd.c
+++ b/drivers/usb/host/max3421-hcd.c
@@ -1694,6 +1694,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
!pdata->vbus_active_level);
fallthrough;
default:
+ if (value >= 32)
+ goto error;
max3421_hcd->port_status &= ~(1 << value);
}
break;
@@ -1747,6 +1749,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
max3421_reset_port(hcd);
fallthrough;
default:
+ if (value >= 32)
+ goto error;
if ((max3421_hcd->port_status & USB_PORT_STAT_POWER)
!= 0)
max3421_hcd->port_status |= (1 << value);
--
2.43.0
From: Seungjin Bae <eeodqql09@gmail.com>
The `max3421_hub_control()` function handles USB hub class requests
to the virtual root hub. In the `default` branches of both the
`ClearPortFeature` and `SetPortFeature` switch statements, it modifies
`max3421_hcd->port_status` by left shifting 1 by the request's `value`
parameter. However, it does not validate whether this shift will exceed
the width of `port_status`.
So if a malicious userspace task with access to the root hub via
/dev/bus/usb/.../001 issues a USBDEVFS_CONTROL ioctl with `wValue`
greater than or equal to 32, the left shift operation invokes
shift-out-of-bounds undefined behavior. This results in arbitrary
bit corruption of `port_status`, including the normally-immutable
change bits, which can bypass internal state checks and confuse the
hub status.
Fix this by rejecting requests whose `value` exceeds the shift width
before performing the shift.
This issue was found using a KLEE-based symbolic execution tool for
kernel drivers that I'm currently developing.
Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.")
Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
---
v1 -> v2: Restored a paragraph in the commit message that was truncated.
v2 -> v3: No functional changes; reorganized as part of a 2-patch series.
v3 -> v4: Document the tool used to find this issue.
drivers/usb/host/max3421-hcd.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
index 0e17c988d36a..3d6b351dcb1a 100644
--- a/drivers/usb/host/max3421-hcd.c
+++ b/drivers/usb/host/max3421-hcd.c
@@ -1694,6 +1694,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
!pdata->vbus_active_level);
fallthrough;
default:
+ if (value >= 32)
+ goto error;
max3421_hcd->port_status &= ~(1 << value);
}
break;
@@ -1747,6 +1749,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
max3421_reset_port(hcd);
fallthrough;
default:
+ if (value >= 32)
+ goto error;
if ((max3421_hcd->port_status & USB_PORT_STAT_POWER)
!= 0)
max3421_hcd->port_status |= (1 << value);
--
2.43.0
From: Seungjin Bae <eeodqql09@gmail.com>
The `max3421_hub_control()` function handles USB hub class requests
to the virtual root hub. The `GetPortStatus` case correctly rejects
requests with `index != 1`, since the virtual root hub has only a
single port. However, the `ClearPortFeature` and `SetPortFeature`
cases lack the same check.
Fix this by extending the `index != 1` rejection to both cases,
matching the existing behavior of `GetPortStatus`.
Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.")
Suggested-by: Alan Stern <stern@rowland.harvard.edu>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
---
v3: New patch in v3, suggested by Alan Stern.
v3 -> v4: No functional changes.
drivers/usb/host/max3421-hcd.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
index 3d6b351dcb1a..73e76d0e6973 100644
--- a/drivers/usb/host/max3421-hcd.c
+++ b/drivers/usb/host/max3421-hcd.c
@@ -1685,6 +1685,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
case ClearHubFeature:
break;
case ClearPortFeature:
+ if (index != 1)
+ goto error;
switch (value) {
case USB_PORT_FEAT_SUSPEND:
break;
@@ -1728,6 +1730,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
break;
case SetPortFeature:
+ if (index != 1)
+ goto error;
switch (value) {
case USB_PORT_FEAT_LINK_STATE:
case USB_PORT_FEAT_U1_TIMEOUT:
--
2.43.0
From: Seungjin Bae <eeodqql09@gmail.com>
The `max3421_hub_control()` function handles USB hub class requests
to the virtual root hub. The `GetPortStatus` case correctly rejects
requests with `index != 1`, since the virtual root hub has only a
single port. However, the `ClearPortFeature` and `SetPortFeature`
cases lack the same check.
Fix this by extending the `index != 1` rejection to both cases,
matching the existing behavior of `GetPortStatus`.
Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.")
Suggested-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
---
v3: New patch in v3, suggested by Alan Stern.
drivers/usb/host/max3421-hcd.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
index 3d6b351dcb1a..73e76d0e6973 100644
--- a/drivers/usb/host/max3421-hcd.c
+++ b/drivers/usb/host/max3421-hcd.c
@@ -1685,6 +1685,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
case ClearHubFeature:
break;
case ClearPortFeature:
+ if (index != 1)
+ goto error;
switch (value) {
case USB_PORT_FEAT_SUSPEND:
break;
@@ -1728,6 +1730,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
break;
case SetPortFeature:
+ if (index != 1)
+ goto error;
switch (value) {
case USB_PORT_FEAT_LINK_STATE:
case USB_PORT_FEAT_U1_TIMEOUT:
--
2.43.0
On Sun, May 17, 2026 at 03:03:08PM -0400, pip-izony wrote:
> From: Seungjin Bae <eeodqql09@gmail.com>
>
> The `max3421_hub_control()` function handles USB hub class requests
> to the virtual root hub. The `GetPortStatus` case correctly rejects
> requests with `index != 1`, since the virtual root hub has only a
> single port. However, the `ClearPortFeature` and `SetPortFeature`
> cases lack the same check.
>
> Fix this by extending the `index != 1` rejection to both cases,
> matching the existing behavior of `GetPortStatus`.
>
> Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.")
> Suggested-by: Alan Stern <stern@rowland.harvard.edu>
> Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
> ---
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
Heh, this made me go back and look at dummy-hcd.c. It's missing the
same check in the same places!
Would you like to submit a patch to fix that driver as well? If not,
I'll take care of it.
Alan Stern
> v3: New patch in v3, suggested by Alan Stern.
>
> drivers/usb/host/max3421-hcd.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
> index 3d6b351dcb1a..73e76d0e6973 100644
> --- a/drivers/usb/host/max3421-hcd.c
> +++ b/drivers/usb/host/max3421-hcd.c
> @@ -1685,6 +1685,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
> case ClearHubFeature:
> break;
> case ClearPortFeature:
> + if (index != 1)
> + goto error;
> switch (value) {
> case USB_PORT_FEAT_SUSPEND:
> break;
> @@ -1728,6 +1730,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
> break;
>
> case SetPortFeature:
> + if (index != 1)
> + goto error;
> switch (value) {
> case USB_PORT_FEAT_LINK_STATE:
> case USB_PORT_FEAT_U1_TIMEOUT:
> --
> 2.43.0
>
2026년 5월 18일 (월) 오후 5:54, Alan Stern <stern@rowland.harvard.edu>님이 작성:
>
> On Sun, May 17, 2026 at 03:03:08PM -0400, pip-izony wrote:
> > From: Seungjin Bae <eeodqql09@gmail.com>
> >
> > The `max3421_hub_control()` function handles USB hub class requests
> > to the virtual root hub. The `GetPortStatus` case correctly rejects
> > requests with `index != 1`, since the virtual root hub has only a
> > single port. However, the `ClearPortFeature` and `SetPortFeature`
> > cases lack the same check.
> >
> > Fix this by extending the `index != 1` rejection to both cases,
> > matching the existing behavior of `GetPortStatus`.
> >
> > Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.")
> > Suggested-by: Alan Stern <stern@rowland.harvard.edu>
> > Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
> > ---
>
> Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
>
> Heh, this made me go back and look at dummy-hcd.c. It's missing the
> same check in the same places!
>
> Would you like to submit a patch to fix that driver as well? If not,
> I'll take care of it.
Thanks for pointing this out.
I'll send a separate patch for that shortly.
Seungjin Bae
>
> Alan Stern
>
> > v3: New patch in v3, suggested by Alan Stern.
> >
> > drivers/usb/host/max3421-hcd.c | 4 ++++
> > 1 file changed, 4 insertions(+)
> >
> > diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
> > index 3d6b351dcb1a..73e76d0e6973 100644
> > --- a/drivers/usb/host/max3421-hcd.c
> > +++ b/drivers/usb/host/max3421-hcd.c
> > @@ -1685,6 +1685,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
> > case ClearHubFeature:
> > break;
> > case ClearPortFeature:
> > + if (index != 1)
> > + goto error;
> > switch (value) {
> > case USB_PORT_FEAT_SUSPEND:
> > break;
> > @@ -1728,6 +1730,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
> > break;
> >
> > case SetPortFeature:
> > + if (index != 1)
> > + goto error;
> > switch (value) {
> > case USB_PORT_FEAT_LINK_STATE:
> > case USB_PORT_FEAT_U1_TIMEOUT:
> > --
> > 2.43.0
> >
From: Seungjin Bae <eeodqql09@gmail.com>
The `max3421_hub_control()` function handles USB hub class requests
to the virtual root hub. In the `default` branches of both the
`ClearPortFeature` and `SetPortFeature` switch statements, it modifies
`max3421_hcd->port_status` by left shifting 1 by the request's `value`
parameter. However, it does not validate whether this shift will exceed
the width of `port_status`.
So if a malicious userspace task with access to the root hub via
/dev/bus/usb/.../001 issues a USBDEVFS_CONTROL ioctl with `wValue`
greater than or equal to 32, the left shift operation invokes
shift-out-of-bounds undefined behavior. This results in arbitrary
bit corruption of `port_status`, including the normally-immutable
change bits, which can bypass internal state checks and confuse the
hub status.
Fix this by rejecting requests whose `value` exceeds the shift width
before performing the shift.
Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.")
Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
---
v1 -> v2: Restored a paragraph in the commit message that was truncated.
drivers/usb/host/max3421-hcd.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
index 0e17c988d36a..3d6b351dcb1a 100644
--- a/drivers/usb/host/max3421-hcd.c
+++ b/drivers/usb/host/max3421-hcd.c
@@ -1694,6 +1694,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
!pdata->vbus_active_level);
fallthrough;
default:
+ if (value >= 32)
+ goto error;
max3421_hcd->port_status &= ~(1 << value);
}
break;
@@ -1747,6 +1749,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
max3421_reset_port(hcd);
fallthrough;
default:
+ if (value >= 32)
+ goto error;
if ((max3421_hcd->port_status & USB_PORT_STAT_POWER)
!= 0)
max3421_hcd->port_status |= (1 << value);
--
2.43.0
On Sat, May 16, 2026 at 08:07:31PM -0400, pip-izony wrote: > From: Seungjin Bae <eeodqql09@gmail.com> > > The `max3421_hub_control()` function handles USB hub class requests > to the virtual root hub. In the `default` branches of both the > `ClearPortFeature` and `SetPortFeature` switch statements, it modifies > `max3421_hcd->port_status` by left shifting 1 by the request's `value` > parameter. However, it does not validate whether this shift will exceed > the width of `port_status`. > > So if a malicious userspace task with access to the root hub via > /dev/bus/usb/.../001 issues a USBDEVFS_CONTROL ioctl with `wValue` > greater than or equal to 32, the left shift operation invokes > shift-out-of-bounds undefined behavior. This results in arbitrary > bit corruption of `port_status`, including the normally-immutable > change bits, which can bypass internal state checks and confuse the > hub status. > > Fix this by rejecting requests whose `value` exceeds the shift width > before performing the shift. Another problem is that the root hub is supposed to reject requests to clear or set a feature for a non-existent port. Just as in the GetPortStatus case, the ClearPortFeature and SetPortFeature cases should check for index != 1. Alan Stern
2026년 5월 16일 (토) 오후 9:15, Alan Stern <stern@rowland.harvard.edu>님이 작성: > > On Sat, May 16, 2026 at 08:07:31PM -0400, pip-izony wrote: > > From: Seungjin Bae <eeodqql09@gmail.com> > > > > The `max3421_hub_control()` function handles USB hub class requests > > to the virtual root hub. In the `default` branches of both the > > `ClearPortFeature` and `SetPortFeature` switch statements, it modifies > > `max3421_hcd->port_status` by left shifting 1 by the request's `value` > > parameter. However, it does not validate whether this shift will exceed > > the width of `port_status`. > > > > So if a malicious userspace task with access to the root hub via > > /dev/bus/usb/.../001 issues a USBDEVFS_CONTROL ioctl with `wValue` > > greater than or equal to 32, the left shift operation invokes > > shift-out-of-bounds undefined behavior. This results in arbitrary > > bit corruption of `port_status`, including the normally-immutable > > change bits, which can bypass internal state checks and confuse the > > hub status. > > > > Fix this by rejecting requests whose `value` exceeds the shift width > > before performing the shift. > > Another problem is that the root hub is supposed to reject requests to > clear or set a feature for a non-existent port. Just as in the > GetPortStatus case, the ClearPortFeature and SetPortFeature cases should > check for index != 1. > > Alan Stern Good point. I'll add the index != 1 check to both the ClearPortFeature and SetPortFeature cases in v3. Thank you for the review. Seungjin Bae
© 2016 - 2026 Red Hat, Inc.