• Alan Stern's avatar
    USB: EHCI: avoid undefined pointer arithmetic and placate UBSAN · 85e3990b
    Alan Stern authored
    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: default avatarAlan Stern <stern@rowland.harvard.edu>
    Reported-by: default avatarValdis Kletnieks <Valdis.Kletnieks@vt.edu>
    Reported-by: default avatarMeelis Roos <mroos@linux.ee>
    Reported-by: default avatarMartin_MOKREJÅ <mmokrejs@gmail.com>
    Reported-by: default avatar"Navin P.S" <navinp1912@gmail.com>
    CC: Andrey Ryabinin <ryabinin.a.a@gmail.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    85e3990b
ehci-hub.c 36.4 KB