]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
block: fix an integer overflow in logical block size
authorMikulas Patocka <mpatocka@redhat.com>
Wed, 15 Jan 2020 13:35:25 +0000 (08:35 -0500)
committerBen Hutchings <ben@decadent.org.uk>
Tue, 28 Apr 2020 18:03:28 +0000 (19:03 +0100)
commit ad6bf88a6c19a39fb3b0045d78ea880325dfcf15 upstream.

Logical block size has type unsigned short. That means that it can be at
most 32768. However, there are architectures that can run with 64k pages
(for example arm64) and on these architectures, it may be possible to
create block devices with 64k block size.

For exmaple (run this on an architecture with 64k pages):

Mount will fail with this error because it tries to read the superblock using 2-sector
access:
  device-mapper: writecache: I/O is not aligned, sector 2, size 1024, block size 65536
  EXT4-fs (dm-0): unable to read superblock

This patch changes the logical block size from unsigned short to unsigned
int to avoid the overflow.

Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
[bwh: Backported to 3.16: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
block/blk-settings.c
drivers/md/dm-snap-persistent.c
drivers/md/raid0.c
include/linux/blkdev.h

index aa02247d227e530223d15e35ecabdacc2b801ce1..f1bd4ca22c6bda41cbfaccc2f9da73ca8b86898f 100644 (file)
@@ -373,7 +373,7 @@ EXPORT_SYMBOL(blk_queue_max_segment_size);
  *   storage device can address.  The default of 512 covers most
  *   hardware.
  **/
-void blk_queue_logical_block_size(struct request_queue *q, unsigned short size)
+void blk_queue_logical_block_size(struct request_queue *q, unsigned int size)
 {
        q->limits.logical_block_size = size;
 
index d3272acc0f0e02976b30d8f2ea19128768439679..2d6a12bd3b28b320f3bcc9d51d0c4e65c223310c 100644 (file)
@@ -16,7 +16,7 @@
 #include "dm-bufio.h"
 
 #define DM_MSG_PREFIX "persistent snapshot"
-#define DM_CHUNK_SIZE_DEFAULT_SECTORS 32       /* 16KB */
+#define DM_CHUNK_SIZE_DEFAULT_SECTORS 32U      /* 16KB */
 
 #define DM_PREFETCH_CHUNKS             12
 
index 8f7dfc58f9657dc095156f9099ed47b009a113e3..61165e528a5e925aa84edad2f85ac02ef34ff915 100644 (file)
@@ -88,7 +88,7 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)
        char b[BDEVNAME_SIZE];
        char b2[BDEVNAME_SIZE];
        struct r0conf *conf = kzalloc(sizeof(*conf), GFP_KERNEL);
-       unsigned short blksize = 512;
+       unsigned blksize = 512;
 
        if (!conf)
                return -ENOMEM;
index b992a89abde29520bbeef5ae9dda94787aaac79d..7983ac9f93e6fa30b995e152edaab8fd0dc0a0b7 100644 (file)
@@ -284,6 +284,7 @@ struct queue_limits {
        unsigned int            max_sectors;
        unsigned int            max_segment_size;
        unsigned int            physical_block_size;
+       unsigned int            logical_block_size;
        unsigned int            alignment_offset;
        unsigned int            io_min;
        unsigned int            io_opt;
@@ -292,7 +293,6 @@ struct queue_limits {
        unsigned int            discard_granularity;
        unsigned int            discard_alignment;
 
-       unsigned short          logical_block_size;
        unsigned short          max_segments;
        unsigned short          max_integrity_segments;
 
@@ -1017,7 +1017,7 @@ extern void blk_queue_max_discard_sectors(struct request_queue *q,
                unsigned int max_discard_sectors);
 extern void blk_queue_max_write_same_sectors(struct request_queue *q,
                unsigned int max_write_same_sectors);
-extern void blk_queue_logical_block_size(struct request_queue *, unsigned short);
+extern void blk_queue_logical_block_size(struct request_queue *, unsigned int);
 extern void blk_queue_physical_block_size(struct request_queue *, unsigned int);
 extern void blk_queue_alignment_offset(struct request_queue *q,
                                       unsigned int alignment);
@@ -1232,7 +1232,7 @@ static inline unsigned int queue_max_segment_size(struct request_queue *q)
        return q->limits.max_segment_size;
 }
 
-static inline unsigned short queue_logical_block_size(struct request_queue *q)
+static inline unsigned queue_logical_block_size(struct request_queue *q)
 {
        int retval = 512;
 
@@ -1242,7 +1242,7 @@ static inline unsigned short queue_logical_block_size(struct request_queue *q)
        return retval;
 }
 
-static inline unsigned short bdev_logical_block_size(struct block_device *bdev)
+static inline unsigned int bdev_logical_block_size(struct block_device *bdev)
 {
        return queue_logical_block_size(bdev_get_queue(bdev));
 }