USB: EHCI: avoid undefined pointer arithmetic and placate UBSAN
authorAlan Stern <stern@rowland.harvard.edu>
Thu, 19 May 2016 20:29:50 +0000 (16:29 -0400)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Wed, 14 Dec 2016 04:51:07 +0000 (13:51 +0900)
commit72d2a974e0ed7b30480762551639f603f06b62b3
tree82cde49dadf68270862ff81c2988f9ea38c56dcc
parent570497f6664bfd954f6c29fc7ab27402f86406a0
USB: EHCI: avoid undefined pointer arithmetic and placate UBSAN

Several people have reported that UBSAN doesn't like the pointer
arithmetic in ehci_hub_control():

u32 __iomem *status_reg = &ehci->regs->port_status[
(wIndex & 0xff) - 1];
u32 __iomem *hostpc_reg = &ehci->regs->hostpc[(wIndex & 0xff) - 1];

If wIndex is 0 (and it often is), these calculations underflow and
UBSAN complains.

According to the C standard, pointer computations leading to locations
outside the bounds of an array object (other than 1 position past the
end) are undefined.  In this case, the compiler would be justified in
concluding the wIndex can never be 0 and then optimizing away the
tests for !wIndex that occur later in the subroutine.  (Although,
since ehci->regs->port_status and ehci->regs->hostpc are both 0-length
arrays and are thus GCC extensions to the C standard, it's not clear
what the compiler is really allowed to do.)

At any rate, we can avoid all these difficulties, at the cost of
making the code slightly longer, by not decrementing the index when it
is equal to 0.  The runtime effect is minimal, and anyway
ehci_hub_control() is not on a hot path.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Reported-by: Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
Reported-by: Meelis Roos <mroos@linux.ee>
Reported-by: Martin_MOKREJÅ <mmokrejs@gmail.com>
Reported-by: "Navin P.S" <navinp1912@gmail.com>
CC: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[Backport from mainline to remove UBSAN warning on usb-ehci]
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Change-Id: Iead9feb0ae5b53d48baa7603f1808fc898b31127
drivers/usb/host/ehci-hub.c