• Arnd Bergmann's avatar
    scsi: aacraid: address UBSAN warning regression · d1853975
    Arnd Bergmann authored
    As reported by Meelis Roos, my previous patch causes an incorrect
    calculation of the timeout, through an undefined signed integer
    overflow:
    
    [   12.228155] UBSAN: Undefined behaviour in drivers/scsi/aacraid/commsup.c:2514:49
    [   12.228229] signed integer overflow:
    [   12.228283] 964297611 * 250 cannot be represented in type 'long int'
    
    The problem is that doing a multiplication with HZ first and then
    dividing by USEC_PER_SEC worked correctly for 32-bit microseconds,
    but not for 32-bit nanoseconds, which would require up to 41 bits.
    
    This reworks the calculation to first convert the nanoseconds into
    jiffies, which should give us the same result as before and not overflow.
    
    Unfortunately I did not understand the exact intention of the algorithm,
    in particular the part where we add half a second, so it's possible that
    there is still a preexisting problem in this function. I added a comment
    that this would be handled more nicely using usleep_range(), which
    generally works better for waking up at a particular time than the
    current schedule_timeout() based implementation. I did not feel
    comfortable trying to implement that without being sure what the
    intent is here though.
    
    Fixes: 820f1886 ("scsi: aacraid: use timespec64 instead of timeval")
    Tested-by: default avatarMeelis Roos <mroos@linux.ee>
    Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
    Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
    d1853975
commsup.c 68.3 KB