• Jack Morgenstein's avatar
    IB/mlx4: Fix integer overflow when calculating optimal MTT size · b03bcde9
    Jack Morgenstein authored
    When the kernel was compiled using the UBSAN option,
    we saw the following stack trace:
    
    [ 1184.827917] UBSAN: Undefined behaviour in drivers/infiniband/hw/mlx4/mr.c:349:27
    [ 1184.828114] signed integer overflow:
    [ 1184.828247] -2147483648 - 1 cannot be represented in type 'int'
    
    The problem was caused by calling round_up in procedure
    mlx4_ib_umem_calc_optimal_mtt_size (on line 349, as noted in the stack
    trace) with the second parameter (1 << block_shift) (which is an int).
    The second parameter should have been (1ULL << block_shift) (which
    is an unsigned long long).
    
    (1 << block_shift) is treated by the compiler as an int (because 1 is
    an integer).
    
    Now, local variable block_shift is initialized to 31.
    If block_shift is 31, 1 << block_shift is 1 << 31 = 0x80000000=-214748368.
    This is the most negative int value.
    
    Inside the round_up macro, there is a cast applied to ((1 << 31) - 1).
    However, this cast is applied AFTER ((1 << 31) - 1) is calculated.
    Since (1 << 31) is treated as an int, we get the negative overflow
    identified by UBSAN in the process of calculating ((1 << 31) - 1).
    
    The fix is to change (1 << block_shift) to (1ULL << block_shift) on
    line 349.
    
    Fixes: 9901abf5 ("IB/mlx4: Use optimal numbers of MTT entries")
    Signed-off-by: default avatarJack Morgenstein <jackm@dev.mellanox.co.il>
    Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
    Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
    b03bcde9
mr.c 19.8 KB