aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Soltys <soltys@ziu.info>2013-02-14 16:51:46 +0100
committerMichal Soltys <soltys@ziu.info>2013-02-14 16:53:05 +0100
commitc3e12b67d34fbf0efaae33c8b0867ccceb7c5949 (patch)
tree32890270f195cea82ed3da71c3ff0cbe3a74d863
parent907de25858cbfad5807a127fe815ff075b6e4ab3 (diff)
downloadsyslinux-c3e12b67d34fbf0efaae33c8b0867ccceb7c5949.tar.gz
syslinux-c3e12b67d34fbf0efaae33c8b0867ccceb7c5949.tar.xz
syslinux-c3e12b67d34fbf0efaae33c8b0867ccceb7c5949.zip
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.c10
-rw-r--r--com32/chain/mangle.c4
-rw-r--r--com32/chain/options.c6
-rw-r--r--com32/chain/options.h1
-rw-r--r--com32/chain/partiter.c17
-rw-r--r--com32/chain/partiter.h1
-rw-r--r--doc/chain.txt14
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