Re: [PATCH] block: fix Amiga partition support for disks >= 1 TB

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Kars,

thanks for your comments - will do.

Cheers,

  Michael


On Mon, Jul 2, 2018 at 6:38 PM, Kars de Jong <jongk@xxxxxxxxxxxxxx> wrote:
> 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 -



[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux