lkml.org 
[lkml]   [2019]   [Jul]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.1 327/371] block: Fix potential overflow in blk_report_zones()
    Date
    From: Damien Le Moal <damien.lemoal@wdc.com>

    commit 113ab72ed4794c193509a97d7c6d32a6886e1682 upstream.

    For large values of the number of zones reported and/or large zone
    sizes, the sector increment calculated with

    blk_queue_zone_sectors(q) * n

    in blk_report_zones() loop can overflow the unsigned int type used for
    the calculation as both "n" and blk_queue_zone_sectors() value are
    unsigned int. E.g. for a device with 256 MB zones (524288 sectors),
    overflow happens with 8192 or more zones reported.

    Changing the return type of blk_queue_zone_sectors() to sector_t, fixes
    this problem and avoids overflow problem for all other callers of this
    helper too. The same change is also applied to the bdev_zone_sectors()
    helper.

    Fixes: e76239a3748c ("block: add a report_zones method")
    Cc: stable@vger.kernel.org
    Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    block/blk-zoned.c | 2 +-
    include/linux/blkdev.h | 4 ++--
    2 files changed, 3 insertions(+), 3 deletions(-)

    --- a/block/blk-zoned.c
    +++ b/block/blk-zoned.c
    @@ -69,7 +69,7 @@ EXPORT_SYMBOL_GPL(__blk_req_zone_write_u
    static inline unsigned int __blkdev_nr_zones(struct request_queue *q,
    sector_t nr_sectors)
    {
    - unsigned long zone_sectors = blk_queue_zone_sectors(q);
    + sector_t zone_sectors = blk_queue_zone_sectors(q);

    return (nr_sectors + zone_sectors - 1) >> ilog2(zone_sectors);
    }
    --- a/include/linux/blkdev.h
    +++ b/include/linux/blkdev.h
    @@ -662,7 +662,7 @@ static inline bool blk_queue_is_zoned(st
    }
    }

    -static inline unsigned int blk_queue_zone_sectors(struct request_queue *q)
    +static inline sector_t blk_queue_zone_sectors(struct request_queue *q)
    {
    return blk_queue_is_zoned(q) ? q->limits.chunk_sectors : 0;
    }
    @@ -1400,7 +1400,7 @@ static inline bool bdev_is_zoned(struct
    return false;
    }

    -static inline unsigned int bdev_zone_sectors(struct block_device *bdev)
    +static inline sector_t bdev_zone_sectors(struct block_device *bdev)
    {
    struct request_queue *q = bdev_get_queue(bdev);


    \
     
     \ /
      Last update: 2019-07-24 22:39    [W:4.030 / U:0.200 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site