diff options
author | Michal Soltys <soltys@ziu.info> | 2013-02-14 16:51:46 +0100 |
---|---|---|
committer | Michal Soltys <soltys@ziu.info> | 2013-02-14 16:53:05 +0100 |
commit | c3e12b67d34fbf0efaae33c8b0867ccceb7c5949 (patch) | |
tree | 32890270f195cea82ed3da71c3ff0cbe3a74d863 | |
parent | 907de25858cbfad5807a127fe815ff075b6e4ab3 (diff) | |
download | syslinux-c3e12b67d34fbf0efaae33c8b0867ccceb7c5949.tar.gz |
com32/chain: implement relax flag
This flag tones down sanity checks during partition iteration.
This is useful in situations such as:
- inconsistent layouts, but with some partition still in sane bootable state
- usb sticks/disks moved between different PCs might return different
size, which might cause problems if the partitions span the whole disk
Signed-off-by: Michal Soltys <soltys@ziu.info>
-rw-r--r-- | com32/chain/chain.c | 10 | ||||
-rw-r--r-- | com32/chain/mangle.c | 4 | ||||
-rw-r--r-- | com32/chain/options.c | 6 | ||||
-rw-r--r-- | com32/chain/options.h | 1 | ||||
-rw-r--r-- | com32/chain/partiter.c | 17 | ||||
-rw-r--r-- | com32/chain/partiter.h | 1 | ||||
-rw-r--r-- | doc/chain.txt | 14 |
7 files changed, 42 insertions, 11 deletions
diff --git a/com32/chain/chain.c b/com32/chain/chain.c index ccfeefa3..f1120d93 100644 --- a/com32/chain/chain.c +++ b/com32/chain/chain.c @@ -72,7 +72,7 @@ static int find_by_sig(uint32_t mbr_sig, 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, 0))) + if (!(boot_part = pi_begin(&diskinfo, opt.relax))) continue; /* Check for a MBR disk */ if (boot_part->type != typedos) { @@ -103,7 +103,7 @@ static int find_by_guid(const struct guid *gpt_guid, 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, 0))) + if (!(boot_part = pi_begin(&diskinfo, opt.relax))) continue; /* Check for a GPT disk */ if (boot_part->type != typegpt) { @@ -135,7 +135,7 @@ static int find_by_label(const char *label, struct part_iter **_boot_part) 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, 0))) + if (!(boot_part = pi_begin(&diskinfo, opt.relax))) continue; /* Check for a GPT disk */ if (!(boot_part->type == typegpt)) { @@ -324,7 +324,7 @@ int find_dp(struct part_iter **_iter) if (disk_get_params(drive, &diskinfo)) goto bail; /* this will start iteration over FDD, possibly raw */ - if (!(iter = pi_begin(&diskinfo, 0))) + if (!(iter = pi_begin(&diskinfo, opt.relax))) goto bail; } else if (!strcmp(opt.drivename, "boot") || !strcmp(opt.drivename, "fs")) { @@ -344,7 +344,7 @@ int find_dp(struct part_iter **_iter) if (disk_get_params(drive, &diskinfo)) goto bail; /* this will start iteration over disk emulation, possibly raw */ - if (!(iter = pi_begin(&diskinfo, 0))) + if (!(iter = pi_begin(&diskinfo, opt.relax))) goto bail; /* 'fs' => we should lookup the syslinux partition number and use it */ diff --git a/com32/chain/mangle.c b/com32/chain/mangle.c index b252a66c..252128da 100644 --- a/com32/chain/mangle.c +++ b/com32/chain/mangle.c @@ -537,7 +537,7 @@ int manglepe_hide(struct part_iter *miter) if (miter->index > 4 && !(opt.hide & HIDE_EXT)) warn("Specified partition is logical, so it can't be unhidden without 'unhideall'."); - if (!(iter = pi_begin(&miter->di, PIF_STEPALL))) + if (!(iter = pi_begin(&miter->di, PIF_STEPALL | opt.relax))) return -1; while (!pi_next(iter) && !werr) { @@ -611,7 +611,7 @@ int manglepe_fixchs(struct part_iter *miter) return -1; } - if (!(iter = pi_begin(&miter->di, PIF_STEPALL))) + if (!(iter = pi_begin(&miter->di, PIF_STEPALL | opt.relax))) return -1; while (!pi_next(iter) && !werr) { diff --git a/com32/chain/options.c b/com32/chain/options.c index 93f14f7a..209ad017 100644 --- a/com32/chain/options.c +++ b/com32/chain/options.c @@ -33,6 +33,7 @@ #include <string.h> #include "common.h" #include "chain.h" +#include "partiter.h" #include "utility.h" #include "options.h" @@ -123,6 +124,7 @@ static void usage(void) " keeppxe Keep the PXE and UNDI stacks in memory (PXELINUX)", " warn Wait for a keypress to continue chainloading", " break Don't chainload", +" relax Relax sanity checks", "", " file=<file> Load and execute <file>", " seg=<s[:o[:i]]> Load file at <s:o>, jump to <s:i>", @@ -324,6 +326,10 @@ int opt_parse_args(int argc, char *argv[]) opt.fixchs = true; } else if (!strcmp(argv[i], "nofixchs")) { opt.fixchs = false; + } else if (!strcmp(argv[i], "relax")) { + opt.relax = PIF_RELAX; + } else if (!strcmp(argv[i], "norelax")) { + opt.relax = 0; } else if (!strcmp(argv[i], "warn")) { opt.warn = true; } else if (!strcmp(argv[i], "nowarn")) { diff --git a/com32/chain/options.h b/com32/chain/options.h index ea6e4700..ac8f356b 100644 --- a/com32/chain/options.h +++ b/com32/chain/options.h @@ -64,6 +64,7 @@ struct options { bool filebpb; bool fixchs; bool warn; + int relax; bool brkchain; uint16_t keeppxe; struct syslinux_rm_regs regs; diff --git a/com32/chain/partiter.c b/com32/chain/partiter.c index 65357193..967769f6 100644 --- a/com32/chain/partiter.c +++ b/com32/chain/partiter.c @@ -177,6 +177,9 @@ static int notsane_logical(const struct part_iter *iter) return -1; } + if (iter->flags & PIF_RELAX) + return 0; + end_log = dp[0].start_lba + dp[0].length; if (!dp[0].start_lba || @@ -213,6 +216,9 @@ static int notsane_extended(const struct part_iter *iter) return -1; } + if (iter->flags & PIF_RELAX) + return 0; + end_ebr = dp[1].start_lba + dp[1].length; if (!dp[1].start_lba || @@ -240,6 +246,9 @@ static int notsane_primary(const struct part_iter *iter) if (!dp->ostype) return 0; + if (iter->flags & PIF_RELAX) + return 0; + if (!dp->start_lba || !dp->length || !sane(dp->start_lba, dp->length) || @@ -260,6 +269,9 @@ static int notsane_gpt(const struct part_iter *iter) if (guid_is0(&gp->type)) return 0; + if (iter->flags & PIF_RELAX) + return 0; + if (gp->lba_first < iter->gpt.ufirst || gp->lba_last > iter->gpt.ulast) { error("LBA sectors of GPT partition are beyond the range allowed in GPT header."); @@ -592,14 +604,15 @@ struct part_iter *pi_begin(const struct disk_info *di, int flags) * it as a sanity check base. EFI doesn't specify max (AFAIK). * Apart from that, some extensive sanity checks. */ - if (!gpt_loff || !gpt_lsiz || gpt_lcnt > 255u || + if (!(flags & PIF_RELAX) && ( + !gpt_loff || !gpt_lsiz || gpt_lcnt > 255u || gpth->lba_first_usable > gpth->lba_last_usable || !sane(gpt_loff, gpt_lcnt) || gpt_loff + gpt_lcnt > gpth->lba_first_usable || !sane(gpth->lba_last_usable, gpt_lcnt) || gpth->lba_last_usable + gpt_lcnt >= gpth->lba_alt || gpth->lba_alt >= di->lbacnt || - gpth->part_size < sizeof(struct disk_gpt_part_entry)) { + gpth->part_size < sizeof(struct disk_gpt_part_entry))) { error("Invalid GPT header's values."); goto bail; } diff --git a/com32/chain/partiter.h b/com32/chain/partiter.h index 63dc6dac..a737584e 100644 --- a/com32/chain/partiter.h +++ b/com32/chain/partiter.h @@ -47,6 +47,7 @@ enum {PI_OK, PI_DONE, PI_INSANE, PI_ERRLOAD}; /* flags */ #define PIF_STEPALL 0x01 +#define PIF_RELAX 0x02 struct itertype; struct part_iter; diff --git a/doc/chain.txt b/doc/chain.txt index e71b1c0b..d3c012c0 100644 --- a/doc/chain.txt +++ b/doc/chain.txt @@ -110,8 +110,8 @@ The defaults, if option is not specified, are 0:0x7c00:0x7c00 If any of the fields are omitted (e.g. 0x2000::), they default to 0. sect=<segment>:<offset>:<ip> - nosect *sect=0:0x7c00:0x7c00 + nosect nosect sets: nomaps This triplet lets you alter the addresses a sector will use. It's loaded at @@ -226,8 +226,18 @@ stacks in memory (pxelinux only). This option will wait for a keypress right before continuing the chainloading. Useful to see warnings emited by the chain module. - *nobreak + relax + *norelax + +This option inhibits sanity checks during the traversal of the partition table. +This is potentially useful in corner cases, when for example an usb stick moved +to some different computer would report smaller size than previously with +partitions spanning the whole space. Normally partition iterator would report +an error and abort in such case. Another case scenario is disk corruption in +some later EMBR partition. + break + *nobreak break sets: nofile nomaps nohand It is possible to trigger a "service-only" run - The chain module will do |