• Vitaly Kuznetsov's avatar
    lib/string_helpers.c: fix infinite loop in string_get_size() · 62bef58a
    Vitaly Kuznetsov authored
    Some string_get_size() calls (e.g.:
     string_get_size(1, 512, STRING_UNITS_10, ..., ...)
     string_get_size(15, 64, STRING_UNITS_10, ..., ...)
    ) result in an infinite loop. The problem is that if size is equal to
    divisor[units]/blk_size and is smaller than divisor[units] we'll end
    up with size == 0 when we start doing sf_cap calculations:
    
    For string_get_size(1, 512, STRING_UNITS_10, ..., ...) case:
       ...
       remainder = do_div(size, divisor[units]); -> size is 0, remainder is 1
       remainder *= blk_size; -> remainder is 512
       ...
       size *= blk_size; -> size is still 0
       size += remainder / divisor[units]; -> size is still 0
    
    The caller causing the issue is sd_read_capacity(), the problem was
    noticed on Hyper-V, such weird size was reported by host when scanning
    collides with device removal.  This is probably a separate issue worth
    fixing, this patch is intended to prevent the library routine from
    infinite looping.
    Signed-off-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
    Acked-by: default avatarJames Bottomley <JBottomley@Odin.com>
    Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
    Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
    Cc: "K. Y. Srinivasan" <kys@microsoft.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    62bef58a
string_helpers.c 10.5 KB