Message ID | 20201209104221.13223-1-johan@kernel.org (mailing list archive) |
---|---|
State | Accepted |
Commit | a251963f76fa0226d0fdf0c4f989496f18d9ae7f |
Headers | show |
Series | USB: serial: option: add interface-number sanity check to flag handling | expand |
On Wed, Dec 09, 2020 at 11:42:21AM +0100, Johan Hovold wrote: > Add an interface-number sanity check before testing the device flags to > avoid relying on undefined behaviour when left shifting in case a device > uses an interface number greater than or equal to BITS_PER_LONG (i.e. 64 > or 32). > > Reported-by: syzbot+8881b478dad0a7971f79@syzkaller.appspotmail.com > Fixes: c3a65808f04a ("USB: serial: option: reimplement interface masking") > Cc: stable@vger.kernel.org > Signed-off-by: Johan Hovold <johan@kernel.org> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
On Wed, Dec 09, 2020 at 11:52:45AM +0100, Greg Kroah-Hartman wrote: > On Wed, Dec 09, 2020 at 11:42:21AM +0100, Johan Hovold wrote: > > Add an interface-number sanity check before testing the device flags to > > avoid relying on undefined behaviour when left shifting in case a device > > uses an interface number greater than or equal to BITS_PER_LONG (i.e. 64 > > or 32). > > > > Reported-by: syzbot+8881b478dad0a7971f79@syzkaller.appspotmail.com > > Fixes: c3a65808f04a ("USB: serial: option: reimplement interface masking") > > Cc: stable@vger.kernel.org > > Signed-off-by: Johan Hovold <johan@kernel.org> > > Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Thanks for reviewing. Now applied. Johan
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 2a3bfd6f867e..c5908c4f2046 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -561,6 +561,9 @@ static void option_instat_callback(struct urb *urb); /* Device flags */ +/* Highest interface number which can be used with NCTRL() and RSVD() */ +#define FLAG_IFNUM_MAX 7 + /* Interface does not support modem-control requests */ #define NCTRL(ifnum) ((BIT(ifnum) & 0xff) << 8) @@ -2089,6 +2092,14 @@ static struct usb_serial_driver * const serial_drivers[] = { module_usb_serial_driver(serial_drivers, option_ids); +static bool iface_is_reserved(unsigned long device_flags, u8 ifnum) +{ + if (ifnum > FLAG_IFNUM_MAX) + return false; + + return device_flags & RSVD(ifnum); +} + static int option_probe(struct usb_serial *serial, const struct usb_device_id *id) { @@ -2105,7 +2116,7 @@ static int option_probe(struct usb_serial *serial, * the same class/subclass/protocol as the serial interfaces. Look at * the Windows driver .INF files for reserved interface numbers. */ - if (device_flags & RSVD(iface_desc->bInterfaceNumber)) + if (iface_is_reserved(device_flags, iface_desc->bInterfaceNumber)) return -ENODEV; /* @@ -2121,6 +2132,14 @@ static int option_probe(struct usb_serial *serial, return 0; } +static bool iface_no_modem_control(unsigned long device_flags, u8 ifnum) +{ + if (ifnum > FLAG_IFNUM_MAX) + return false; + + return device_flags & NCTRL(ifnum); +} + static int option_attach(struct usb_serial *serial) { struct usb_interface_descriptor *iface_desc; @@ -2136,7 +2155,7 @@ static int option_attach(struct usb_serial *serial) iface_desc = &serial->interface->cur_altsetting->desc; - if (!(device_flags & NCTRL(iface_desc->bInterfaceNumber))) + if (!iface_no_modem_control(device_flags, iface_desc->bInterfaceNumber)) data->use_send_setup = 1; if (device_flags & ZLP)
Add an interface-number sanity check before testing the device flags to avoid relying on undefined behaviour when left shifting in case a device uses an interface number greater than or equal to BITS_PER_LONG (i.e. 64 or 32). Reported-by: syzbot+8881b478dad0a7971f79@syzkaller.appspotmail.com Fixes: c3a65808f04a ("USB: serial: option: reimplement interface masking") Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold <johan@kernel.org> --- drivers/usb/serial/option.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)