From aac5f9ee9421ed42bf24b329885771b665ae36f1 Mon Sep 17 00:00:00 2001 From: reyk Date: Mon, 4 Aug 2008 15:58:13 +0000 Subject: [PATCH] fix extended partition support by handling chained EBRs correctly (using a recursion limit). now OpenBSD can be installed in a subsequent DOS/Linux-compatible extended partition. ok krw@ deraadt@ --- sbin/disklabel/disklabel.c | 14 +++++----- .../amd64/stand/installboot/installboot.c | 15 +++++------ sys/arch/amd64/stand/libsa/biosdev.c | 27 +++++++++---------- sys/arch/i386/stand/installboot/installboot.c | 15 +++++------ sys/arch/i386/stand/libsa/biosdev.c | 27 +++++++++---------- 5 files changed, 45 insertions(+), 53 deletions(-) diff --git a/sbin/disklabel/disklabel.c b/sbin/disklabel/disklabel.c index 7c287a3cbcb..abc88b92731 100644 --- a/sbin/disklabel/disklabel.c +++ b/sbin/disklabel/disklabel.c @@ -1,4 +1,4 @@ -/* $OpenBSD: disklabel.c,v 1.133 2008/07/10 00:21:39 krw Exp $ */ +/* $OpenBSD: disklabel.c,v 1.134 2008/08/04 15:58:13 reyk Exp $ */ /* * Copyright (c) 1987, 1993 @@ -39,7 +39,7 @@ static const char copyright[] = #endif /* not lint */ #ifndef lint -static const char rcsid[] = "$OpenBSD: disklabel.c,v 1.133 2008/07/10 00:21:39 krw Exp $"; +static const char rcsid[] = "$OpenBSD: disklabel.c,v 1.134 2008/08/04 15:58:13 reyk Exp $"; #endif /* not lint */ #include @@ -579,19 +579,19 @@ findopenbsd(int f, off_t mbroff, struct dos_partition **first, int *n) "type %02X start %u size %u\n", part, dp[part].dp_typ, letoh32(dp[part].dp_start), letoh32(dp[part].dp_size)); + dp[part].dp_start = + htole32((off_t)letoh32(dp[part].dp_start) + mbroff); return (&dp[part]); + case DOSPTYP_EXTEND: case DOSPTYP_EXTENDL: fprintf(stderr, "# Extended partition %d: " "type %02X start %u size %u\n", part, dp[part].dp_typ, letoh32(dp[part].dp_start), letoh32(dp[part].dp_size)); - start = letoh32(dp[part].dp_start); + start = letoh32(dp[part].dp_start) + mbroff; p = findopenbsd(f, start, NULL, n); - if (p != NULL) { - p->dp_start = - htole32(letoh32(p->dp_start) + start); + if (p != NULL) return (p); - } break; } } diff --git a/sys/arch/amd64/stand/installboot/installboot.c b/sys/arch/amd64/stand/installboot/installboot.c index 88f134a0094..fb0e95ffce0 100644 --- a/sys/arch/amd64/stand/installboot/installboot.c +++ b/sys/arch/amd64/stand/installboot/installboot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: installboot.c,v 1.9 2008/06/25 15:26:44 reyk Exp $ */ +/* $OpenBSD: installboot.c,v 1.10 2008/08/04 15:58:13 reyk Exp $ */ /* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */ /* @@ -231,7 +231,7 @@ findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n) if (!(*n)--) return (-1); - if (lseek(devfd, mbroff, SEEK_SET) < 0 || + if (lseek(devfd, mbroff * dl->d_secsize, SEEK_SET) < 0 || read(devfd, &mbr, sizeof(mbr)) != sizeof(mbr)) err(4, "can't read master boot record"); @@ -242,14 +242,13 @@ findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n) dp++) { if (!dp->dp_size) continue; - startoff = (off_t)dp->dp_start * dl->d_secsize; if (dp->dp_typ == DOSPTYP_OPENBSD) { fprintf(stderr, "using MBR partition %ld: " "type %d (0x%02x) offset %d (0x%x)\n", (long)(dp - mbr.dmbr_parts), dp->dp_typ, dp->dp_typ, dp->dp_start, dp->dp_start); - break; + return (dp->dp_start + mbroff); } else if (dp->dp_typ == DOSPTYP_EXTEND || dp->dp_typ == DOSPTYP_EXTENDL) { fprintf(stderr, "extended partition %ld: " @@ -257,16 +256,14 @@ findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n) (long)(dp - mbr.dmbr_parts), dp->dp_typ, dp->dp_typ, dp->dp_start, dp->dp_start); + startoff = (off_t)dp->dp_start + mbroff; start = findopenbsd(devfd, dl, startoff, n); if (start != -1) - return (dp->dp_start + start); + return (start); } } - /* Don't check for old part number, that is ;-p */ - if (dp >= &mbr.dmbr_parts[NDOSPART]) - return (-1); - return (dp->dp_start); + return (-1); } /* diff --git a/sys/arch/amd64/stand/libsa/biosdev.c b/sys/arch/amd64/stand/libsa/biosdev.c index 7358eab09f6..ad5075e324f 100644 --- a/sys/arch/amd64/stand/libsa/biosdev.c +++ b/sys/arch/amd64/stand/libsa/biosdev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: biosdev.c,v 1.6 2008/06/25 15:32:18 reyk Exp $ */ +/* $OpenBSD: biosdev.c,v 1.7 2008/08/04 15:58:13 reyk Exp $ */ /* * Copyright (c) 1996 Michael Shalayeff @@ -45,8 +45,7 @@ static int biosdisk_errno(u_int); static int CHS_rw (int, int, int, int, int, int, void *); static int EDD_rw (int, int, u_int64_t, u_int32_t, void *); -static daddr_t findopenbsd(bios_diskinfo_t *, daddr_t, daddr_t *, - const char **, int *); +static daddr_t findopenbsd(bios_diskinfo_t *, daddr_t, const char **, int *); extern int debug; int bios_bootdev; @@ -343,8 +342,7 @@ biosd_io(int rw, bios_diskinfo_t *bd, daddr_t off, int nsect, void *buf) * Try to read the bsd label on the given BIOS device */ static daddr_t -findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err, - int *n) +findopenbsd(bios_diskinfo_t *bd, daddr_t off, const char **err, int *n) { int error, i; struct dos_mbr mbr; @@ -370,7 +368,7 @@ findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err, } /* Search for OpenBSD partition */ - for (off = 0, i = 0; off == 0 && i < NDOSPART; i++) { + for (i = 0; i < NDOSPART; i++) { dp = &mbr.dmbr_parts[i]; #ifdef BIOS_DEBUG if (debug) @@ -380,13 +378,14 @@ findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err, dp->dp_typ, dp->dp_typ, dp->dp_start, dp->dp_start); #endif - if (dp->dp_typ == DOSPTYP_OPENBSD) - off = dp->dp_start; - else if (dp->dp_typ == DOSPTYP_EXTEND || + if (dp->dp_typ == DOSPTYP_OPENBSD) { + off = dp->dp_start + off; + break; + } else if (dp->dp_typ == DOSPTYP_EXTEND || dp->dp_typ == DOSPTYP_EXTENDL) { - off = findopenbsd(bd, dp->dp_start, roff, err, n); + off = findopenbsd(bd, dp->dp_start + off, err, n); if (off != 0) - *roff = dp->dp_start; + break; } } @@ -407,7 +406,7 @@ findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err, const char * bios_getdisklabel(bios_diskinfo_t *bd, struct disklabel *label) { - daddr_t off = 0, roff = 0; + daddr_t off = 0; char *buf; const char *err = NULL; int error; @@ -420,14 +419,14 @@ bios_getdisklabel(bios_diskinfo_t *bd, struct disklabel *label) /* MBR is a harddisk thing */ if (bd->bios_number & 0x80) { - off = findopenbsd(bd, DOSBBSECTOR, &roff, &err, &n); + off = findopenbsd(bd, DOSBBSECTOR, &err, &n); if (off == 0) { if (err != NULL) return (err); return "no OpenBSD partition\n"; } } - off = LABELSECTOR + off + roff; + off = LABELSECTOR + off; /* Load BSD disklabel */ buf = alloca(DEV_BSIZE); diff --git a/sys/arch/i386/stand/installboot/installboot.c b/sys/arch/i386/stand/installboot/installboot.c index d0a450147a1..1658d05c0a2 100644 --- a/sys/arch/i386/stand/installboot/installboot.c +++ b/sys/arch/i386/stand/installboot/installboot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: installboot.c,v 1.52 2008/06/25 15:26:44 reyk Exp $ */ +/* $OpenBSD: installboot.c,v 1.53 2008/08/04 15:58:13 reyk Exp $ */ /* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */ /* @@ -227,7 +227,7 @@ findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n) if (!(*n)--) return (-1); - if (lseek(devfd, mbroff, SEEK_SET) < 0 || + if (lseek(devfd, mbroff * dl->d_secsize, SEEK_SET) < 0 || read(devfd, &mbr, sizeof(mbr)) != sizeof(mbr)) err(4, "can't read master boot record"); @@ -238,14 +238,13 @@ findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n) dp++) { if (!dp->dp_size) continue; - startoff = (off_t)dp->dp_start * dl->d_secsize; if (dp->dp_typ == DOSPTYP_OPENBSD) { fprintf(stderr, "using MBR partition %ld: " "type %d (0x%02x) offset %d (0x%x)\n", (long)(dp - mbr.dmbr_parts), dp->dp_typ, dp->dp_typ, dp->dp_start, dp->dp_start); - break; + return (dp->dp_start + mbroff); } else if (dp->dp_typ == DOSPTYP_EXTEND || dp->dp_typ == DOSPTYP_EXTENDL) { fprintf(stderr, "extended partition %ld: " @@ -253,16 +252,14 @@ findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n) (long)(dp - mbr.dmbr_parts), dp->dp_typ, dp->dp_typ, dp->dp_start, dp->dp_start); + startoff = (off_t)dp->dp_start + mbroff; start = findopenbsd(devfd, dl, startoff, n); if (start != -1) - return (dp->dp_start + start); + return (start); } } - /* Don't check for old part number, that is ;-p */ - if (dp >= &mbr.dmbr_parts[NDOSPART]) - return (-1); - return (dp->dp_start); + return (-1); } /* diff --git a/sys/arch/i386/stand/libsa/biosdev.c b/sys/arch/i386/stand/libsa/biosdev.c index 2b8220225ac..3ccc01258cd 100644 --- a/sys/arch/i386/stand/libsa/biosdev.c +++ b/sys/arch/i386/stand/libsa/biosdev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: biosdev.c,v 1.74 2008/06/25 15:32:18 reyk Exp $ */ +/* $OpenBSD: biosdev.c,v 1.75 2008/08/04 15:58:13 reyk Exp $ */ /* * Copyright (c) 1996 Michael Shalayeff @@ -46,8 +46,7 @@ static int biosdisk_errno(u_int); static int CHS_rw (int, int, int, int, int, int, void *); static int EDD_rw (int, int, u_int64_t, u_int32_t, void *); -static daddr_t findopenbsd(bios_diskinfo_t *, daddr_t, daddr_t *, - const char **, int *); +static daddr_t findopenbsd(bios_diskinfo_t *, daddr_t, const char **, int *); extern int debug; int bios_bootdev; @@ -346,8 +345,7 @@ biosd_io(int rw, bios_diskinfo_t *bd, daddr_t off, int nsect, void *buf) * Try to read the bsd label on the given BIOS device */ static daddr_t -findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err, - int *n) +findopenbsd(bios_diskinfo_t *bd, daddr_t off, const char **err, int *n) { int error, i; struct dos_mbr mbr; @@ -373,7 +371,7 @@ findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err, } /* Search for OpenBSD partition */ - for (off = 0, i = 0; off == 0 && i < NDOSPART; i++) { + for (i = 0; i < NDOSPART; i++) { dp = &mbr.dmbr_parts[i]; #ifdef BIOS_DEBUG if (debug) @@ -383,13 +381,14 @@ findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err, dp->dp_typ, dp->dp_typ, dp->dp_start, dp->dp_start); #endif - if (dp->dp_typ == DOSPTYP_OPENBSD) - off = dp->dp_start; - else if (dp->dp_typ == DOSPTYP_EXTEND || + if (dp->dp_typ == DOSPTYP_OPENBSD) { + off = dp->dp_start + off; + break; + } else if (dp->dp_typ == DOSPTYP_EXTEND || dp->dp_typ == DOSPTYP_EXTENDL) { - off = findopenbsd(bd, dp->dp_start, roff, err, n); + off = findopenbsd(bd, dp->dp_start + off, err, n); if (off != 0) - *roff = dp->dp_start; + break; } } @@ -410,7 +409,7 @@ findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err, const char * bios_getdisklabel(bios_diskinfo_t *bd, struct disklabel *label) { - daddr_t off = 0, roff = 0; + daddr_t off = 0; char *buf; const char *err = NULL; int error; @@ -423,14 +422,14 @@ bios_getdisklabel(bios_diskinfo_t *bd, struct disklabel *label) /* MBR is a harddisk thing */ if (bd->bios_number & 0x80) { - off = findopenbsd(bd, DOSBBSECTOR, &roff, &err, &n); + off = findopenbsd(bd, DOSBBSECTOR, &err, &n); if (off == 0) { if (err != NULL) return (err); return "no OpenBSD partition\n"; } } - off = LABELSECTOR + off + roff; + off = LABELSECTOR + off; /* Load BSD disklabel */ buf = alloca(DEV_BSIZE); -- 2.20.1