From 8fb1a96c5da054f4de5d32db808e1d18b855325a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 16 Jul 2023 17:21:56 +0200 Subject: [PATCH] 5.4-stable patches added patches: block-add-overflow-checks-for-amiga-partition-support.patch --- ...w-checks-for-amiga-partition-support.patch | 204 ++++++++++++++++++ queue-5.4/series | 1 + 2 files changed, 205 insertions(+) create mode 100644 queue-5.4/block-add-overflow-checks-for-amiga-partition-support.patch diff --git a/queue-5.4/block-add-overflow-checks-for-amiga-partition-support.patch b/queue-5.4/block-add-overflow-checks-for-amiga-partition-support.patch new file mode 100644 index 00000000000..df58a766bfc --- /dev/null +++ b/queue-5.4/block-add-overflow-checks-for-amiga-partition-support.patch @@ -0,0 +1,204 @@ +From b6f3f28f604ba3de4724ad82bea6adb1300c0b5f Mon Sep 17 00:00:00 2001 +From: Michael Schmitz +Date: Wed, 21 Jun 2023 08:17:25 +1200 +Subject: block: add overflow checks for Amiga partition support + +From: Michael Schmitz + +commit b6f3f28f604ba3de4724ad82bea6adb1300c0b5f upstream. + +The Amiga partition parser module uses signed int for partition sector +address and count, which will overflow for disks larger than 1 TB. + +Use u64 as type for sector address and size to allow using disks up to +2 TB without LBD support, and disks larger than 2 TB with LBD. The RBD +format allows to specify disk sizes up to 2^128 bytes (though native +OS limitations reduce this somewhat, to max 2^68 bytes), so check for +u64 overflow carefully to protect against overflowing sector_t. + +Bail out if sector addresses overflow 32 bits on kernels without LBD +support. + +This bug was reported originally in 2012, and the fix was created by +the RDB author, Joanne Dow . A patch had been +discussed and reviewed on linux-m68k at that time but never officially +submitted (now resubmitted as patch 1 in this series). +This patch adds additional error checking and warning messages. + +Reported-by: Martin Steigerwald +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=43511 +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Message-ID: <201206192146.09327.Martin@lichtvoll.de> +Cc: # 5.2 +Signed-off-by: Michael Schmitz +Reviewed-by: Geert Uytterhoeven +Reviewed-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20230620201725.7020-4-schmitzmic@gmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + block/partitions/amiga.c | 103 ++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 85 insertions(+), 18 deletions(-) + +--- a/block/partitions/amiga.c ++++ b/block/partitions/amiga.c +@@ -11,11 +11,19 @@ + #define pr_fmt(fmt) fmt + + #include ++#include ++#include + #include + + #include "check.h" + #include "amiga.h" + ++/* magic offsets in partition DosEnvVec */ ++#define NR_HD 3 ++#define NR_SECT 5 ++#define LO_CYL 9 ++#define HI_CYL 10 ++ + static __inline__ u32 + checksum_block(__be32 *m, int size) + { +@@ -32,9 +40,12 @@ int amiga_partition(struct parsed_partit + unsigned char *data; + struct RigidDiskBlock *rdb; + struct PartitionBlock *pb; +- sector_t start_sect, nr_sects; +- int blk, part, res = 0; +- int blksize = 1; /* Multiplier for disk block size */ ++ u64 start_sect, nr_sects; ++ sector_t blk, end_sect; ++ u32 cylblk; /* rdb_CylBlocks = nr_heads*sect_per_track */ ++ u32 nr_hd, nr_sect, lo_cyl, hi_cyl; ++ int part, res = 0; ++ unsigned int blksize = 1; /* Multiplier for disk block size */ + int slot = 1; + char b[BDEVNAME_SIZE]; + +@@ -44,7 +55,7 @@ int amiga_partition(struct parsed_partit + data = read_part_sector(state, blk, §); + if (!data) { + if (warn_no_part) +- pr_err("Dev %s: unable to read RDB block %d\n", ++ pr_err("Dev %s: unable to read RDB block %llu\n", + bdevname(state->bdev, b), blk); + res = -1; + goto rdb_done; +@@ -61,12 +72,12 @@ int amiga_partition(struct parsed_partit + *(__be32 *)(data+0xdc) = 0; + if (checksum_block((__be32 *)data, + be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)==0) { +- pr_err("Trashed word at 0xd0 in block %d ignored in checksum calculation\n", ++ pr_err("Trashed word at 0xd0 in block %llu ignored in checksum calculation\n", + blk); + break; + } + +- pr_err("Dev %s: RDB in block %d has bad checksum\n", ++ pr_err("Dev %s: RDB in block %llu has bad checksum\n", + bdevname(state->bdev, b), blk); + } + +@@ -83,11 +94,16 @@ int amiga_partition(struct parsed_partit + blk = be32_to_cpu(rdb->rdb_PartitionList); + put_dev_sector(sect); + for (part = 1; blk>0 && part<=16; part++, put_dev_sector(sect)) { +- blk *= blksize; /* Read in terms partition table understands */ ++ /* Read in terms partition table understands */ ++ if (check_mul_overflow(blk, (sector_t) blksize, &blk)) { ++ pr_err("Dev %s: overflow calculating partition block %llu! Skipping partitions %u and beyond\n", ++ bdevname(state->bdev, b), blk, part); ++ break; ++ } + data = read_part_sector(state, blk, §); + if (!data) { + if (warn_no_part) +- pr_err("Dev %s: unable to read partition block %d\n", ++ pr_err("Dev %s: unable to read partition block %llu\n", + bdevname(state->bdev, b), blk); + res = -1; + goto rdb_done; +@@ -99,19 +115,70 @@ int amiga_partition(struct parsed_partit + if (checksum_block((__be32 *)pb, be32_to_cpu(pb->pb_SummedLongs) & 0x7F) != 0 ) + continue; + +- /* Tell Kernel about it */ ++ /* RDB gives us more than enough rope to hang ourselves with, ++ * many times over (2^128 bytes if all fields max out). ++ * Some careful checks are in order, so check for potential ++ * overflows. ++ * We are multiplying four 32 bit numbers to one sector_t! ++ */ ++ ++ nr_hd = be32_to_cpu(pb->pb_Environment[NR_HD]); ++ nr_sect = be32_to_cpu(pb->pb_Environment[NR_SECT]); ++ ++ /* CylBlocks is total number of blocks per cylinder */ ++ if (check_mul_overflow(nr_hd, nr_sect, &cylblk)) { ++ pr_err("Dev %s: heads*sects %u overflows u32, skipping partition!\n", ++ bdevname(state->bdev, b), cylblk); ++ continue; ++ } ++ ++ /* check for consistency with RDB defined CylBlocks */ ++ if (cylblk > be32_to_cpu(rdb->rdb_CylBlocks)) { ++ pr_warn("Dev %s: cylblk %u > rdb_CylBlocks %u!\n", ++ bdevname(state->bdev, b), cylblk, ++ be32_to_cpu(rdb->rdb_CylBlocks)); ++ } ++ ++ /* RDB allows for variable logical block size - ++ * normalize to 512 byte blocks and check result. ++ */ ++ ++ if (check_mul_overflow(cylblk, blksize, &cylblk)) { ++ pr_err("Dev %s: partition %u bytes per cyl. overflows u32, skipping partition!\n", ++ bdevname(state->bdev, b), part); ++ continue; ++ } ++ ++ /* Calculate partition start and end. Limit of 32 bit on cylblk ++ * guarantees no overflow occurs if LBD support is enabled. ++ */ ++ ++ lo_cyl = be32_to_cpu(pb->pb_Environment[LO_CYL]); ++ start_sect = ((u64) lo_cyl * cylblk); ++ ++ hi_cyl = be32_to_cpu(pb->pb_Environment[HI_CYL]); ++ nr_sects = (((u64) hi_cyl - lo_cyl + 1) * cylblk); + +- nr_sects = ((sector_t)be32_to_cpu(pb->pb_Environment[10]) + 1 - +- be32_to_cpu(pb->pb_Environment[9])) * +- be32_to_cpu(pb->pb_Environment[3]) * +- be32_to_cpu(pb->pb_Environment[5]) * +- blksize; + if (!nr_sects) + continue; +- start_sect = (sector_t)be32_to_cpu(pb->pb_Environment[9]) * +- be32_to_cpu(pb->pb_Environment[3]) * +- be32_to_cpu(pb->pb_Environment[5]) * +- blksize; ++ ++ /* Warn user if partition end overflows u32 (AmigaDOS limit) */ ++ ++ if ((start_sect + nr_sects) > UINT_MAX) { ++ pr_warn("Dev %s: partition %u (%llu-%llu) needs 64 bit device support!\n", ++ bdevname(state->bdev, b), part, ++ start_sect, start_sect + nr_sects); ++ } ++ ++ if (check_add_overflow(start_sect, nr_sects, &end_sect)) { ++ pr_err("Dev %s: partition %u (%llu-%llu) needs LBD device support, skipping partition!\n", ++ bdevname(state->bdev, b), part, ++ start_sect, end_sect); ++ continue; ++ } ++ ++ /* Tell Kernel about it */ ++ + put_partition(state,slot++,start_sect,nr_sects); + { + /* Be even more informative to aid mounting */ diff --git a/queue-5.4/series b/queue-5.4/series index a9c045b6d2b..e09263d28be 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -179,4 +179,5 @@ asoc-mediatek-mt8173-fix-irq-error-path.patch arm-orion5x-fix-d2net-gpio-initialization.patch fs-no-need-to-check-source.patch fanotify-disallow-mount-sb-marks-on-kernel-internal-pseudo-fs.patch +block-add-overflow-checks-for-amiga-partition-support.patch mm-mmap-fix-extra-maple-tree-write.patch -- 2.47.3