diff options
author | Michal Soltys <soltys@ziu.info> | 2010-08-16 13:07:12 +0200 |
---|---|---|
committer | Michal Soltys <soltys@ziu.info> | 2010-08-22 23:45:15 +0200 |
commit | d4d713c9ccfe08bf5e129a398d4f2a313b7ffe62 (patch) | |
tree | 98bac67ef7954673a77122efa588f2b0c3374edf | |
parent | 1f948d6ff5f9539cc2d722ca4d20b26eaa5e420d (diff) | |
download | syslinux-d4d713c9ccfe08bf5e129a398d4f2a313b7ffe62.tar.gz syslinux-d4d713c9ccfe08bf5e129a398d4f2a313b7ffe62.tar.xz syslinux-d4d713c9ccfe08bf5e129a398d4f2a313b7ffe62.zip |
chain.c: Don't bruteforce loops detecting fixed drives.
Previously chain module looped all possible fixed disks from 0x80 to
0xFF. It's prone to BIOS bugs, where BIOS can report nonexistent or
phantom drives at higher numbers. It's safer to use fixed disk count
value from 40:75 to limit such loops.
Signed-off-by: Michal Soltys <soltys@ziu.info>
-rw-r--r-- | com32/chain/chain.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/com32/chain/chain.c b/com32/chain/chain.c index 6b693026..6c11a4d1 100644 --- a/com32/chain/chain.c +++ b/com32/chain/chain.c @@ -39,6 +39,7 @@ #define ADDRMIN 0x500 static const char cmldr_signature[8] = "cmdcons"; +static int fixed_cnt; static struct options { uint32_t flin; @@ -83,7 +84,7 @@ static int find_by_sig(uint32_t mbr_sig, struct disk_info diskinfo; int drive; - for (drive = 0x80; drive <= 0xff; drive++) { + for (drive = 0x80; drive < 0x80 + fixed_cnt; drive++) { if (disk_get_params(drive, &diskinfo)) continue; /* Drive doesn't exist */ if (!(boot_part = pi_begin(&diskinfo))) @@ -118,7 +119,7 @@ static int find_by_guid(const struct guid *gpt_guid, struct disk_info diskinfo; int drive; - for (drive = 0x80; drive <= 0xff; drive++) { + for (drive = 0x80; drive < 0x80 + fixed_cnt; drive++) { if (disk_get_params(drive, &diskinfo)) continue; /* Drive doesn't exist */ if (!(boot_part = pi_begin(&diskinfo))) @@ -157,7 +158,7 @@ static int find_by_label(const char *label, struct part_iter **_boot_part) struct disk_info diskinfo; int drive; - for (drive = 0x80; drive <= 0xff; drive++) { + for (drive = 0x80; drive < 0x80 + fixed_cnt; drive++) { if (disk_get_params(drive, &diskinfo)) continue; /* Drive doesn't exist */ if (!(boot_part = pi_begin(&diskinfo))) @@ -651,21 +652,25 @@ int find_dp(struct part_iter **_iter) "'boot' and 'fs' are meaningless.\n"); goto bail; } +#if 0 /* offsets match, but in case it changes in the future */ if(sdi->c.filesystem == SYSLINUX_FS_ISOLINUX) { drive = sdi->iso.drive_number; fs_lba = *sdi->iso.partoffset; } else { +#endif drive = sdi->disk.drive_number; fs_lba = *sdi->disk.partoffset; +#if 0 } +#endif if (disk_get_params(drive, &diskinfo)) goto bail; if (!(iter = pi_begin(&diskinfo))) goto bail; - /* 'fs' => we should lookup the Syslinux partition number and use it */ + /* 'fs' => we should lookup the syslinux partition number and use it */ if (!strcmp(opt.drivename, "fs")) { while (pi_next(&iter)) { if (iter->start_lba == fs_lba) @@ -963,6 +968,10 @@ int main(int argc, char *argv[]) if(opt.regs.ip == 0x7C00 && !opt.regs.cs) opt.regs.esp.l = 0x7C00; + /* Get max fixed disk number */ + + fixed_cnt = *(uint8_t *)(0x475); + /* Get disk/part iterator matching user supplied options */ if(find_dp(&iter)) goto bail; |