Op ma 2 jul. 2018 om 07:29 schreef Michael Schmitz <schmitzmic@xxxxxxxxx>:
@@ -98,6 +101,79 @@ int amiga_partition(struct parsed_partitions *state) if (checksum_block((__be32 *)pb, be32_to_cpu(pb->pb_SummedLongs) & 0x7F) != 0 ) continue; + /* 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. + */ + + /* CylBlocks is total number of blocks per cylinder */ + cylblk = be32_to_cpu(pb->pb_Environment[3]) * + be32_to_cpu(pb->pb_Environment[5]); +
Could you please create #defines for all these magic offsets in pb_Environment? Below are a few more. This makes the code much more readable. Thanks!
+ /* check for consistency with RDB defined CylBlocks */ + if (cylblk > be32_to_cpu(rdb->rdb_CylBlocks)) { + pr_err("Dev %s: cylblk 0x%lx > rdb_CylBlocks 0x%x!\n", + bdevname(state->bdev, b), + (unsigned long) cylblk, + be32_to_cpu(rdb->rdb_CylBlocks)); + } + + /* check for potential overflows - we are going to multiply + * three 32 bit numbers to one 64 bit result later! + * Condition 1: nr_heads * sects_per_track must fit u32! + * NB: This is a HARD limit for AmigaDOS. We don't care much. + */ + + if (cylblk > UINT_MAX) { + pr_err("Dev %s: hds*sects 0x%lx > UINT_MAX!\n", + bdevname(state->bdev, b), + (unsigned long) cylblk); + + /* lop off low 32 bits */ + cylblk_res = cylblk >> 32; + + /* check for further overflow in end result */ + if (be32_to_cpu(pb->pb_Environment[9]) * + cylblk_res * blksize > UINT_MAX) { + pr_err("Dev %s: start_sect overflows u64!\n", + bdevname(state->bdev, b)); + res = -1; + goto rdb_done; + } + + if (be32_to_cpu(pb->pb_Environment[10]) * + cylblk_res * blksize > UINT_MAX) { + pr_err("Dev %s: end_sect overflows u64!\n", + bdevname(state->bdev, b)); + res = -1; + goto rdb_done; + } + } + + /* Condition 2: even if CylBlocks did not overflow, the end + * result must still fit u64! + */ + + /* how many bits above 32 in cylblk * blksize ? */ + if (cylblk*blksize > (u64) UINT_MAX) + blk_shift = ilog2(cylblk*blksize) - 32; + + if (be32_to_cpu(pb->pb_Environment[9]) + > (u64) UINT_MAX>>blk_shift) { + pr_err("Dev %s: start_sect overflows u64!\n", + bdevname(state->bdev, b)); + res = -1; + goto rdb_done; + } + + if (be32_to_cpu(pb->pb_Environment[10]) + > (u64) UINT_MAX>>blk_shift) { + pr_err("Dev %s: end_sect overflows u64!\n", + bdevname(state->bdev, b)); + res = -1; + goto rdb_done; + } + /* Tell Kernel about it */ nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 -
-- To unsubscribe from this list: send the line "unsubscribe linux-m68k" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html