diff options
Diffstat (limited to 'sys/arch/amd64/amd64/disksubr.c')
-rw-r--r-- | sys/arch/amd64/amd64/disksubr.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/sys/arch/amd64/amd64/disksubr.c b/sys/arch/amd64/amd64/disksubr.c index af07238bff7..a27cc4d60ac 100644 --- a/sys/arch/amd64/amd64/disksubr.c +++ b/sys/arch/amd64/amd64/disksubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: disksubr.c,v 1.29 2007/02/03 18:22:33 krw Exp $ */ +/* $OpenBSD: disksubr.c,v 1.30 2007/02/18 13:49:22 krw Exp $ */ /* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */ /* @@ -67,6 +67,7 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, struct disklabel *dlp; struct partition *pp; unsigned long extoff = 0; + unsigned int fattest; struct buf *bp = NULL; daddr_t part_blkno = DOSBBSECTOR; char *msg = NULL; @@ -212,7 +213,34 @@ donot: lp->d_sbsize = 64*1024; /* XXX ? */ lp->d_npartitions = MAXPARTITIONS; - /* don't read the on-disk label if we are in spoofed-only mode */ + if (n == 0 && part_blkno == DOSBBSECTOR) { + /* Check for a short jump instruction. */ + fattest = ((bp->b_data[0] << 8) & 0xff00) | (bp->b_data[2] & + 0xff); + if (fattest != 0xeb90 && fattest != 0xe900) + goto notfat; + + /* Check for a valid bytes per sector value. */ + fattest = ((bp->b_data[12] << 8) & 0xff00) | (bp->b_data[11] & + 0xff); + if (fattest < 512 || fattest > 4096 || (fattest % 512 != 0)) + goto notfat; + + /* Check the end of sector marker. */ + fattest = ((bp->b_data[510] << 8) & 0xff00) | (bp->b_data[511] & + 0xff); + if (fattest != 0x55aa) + goto notfat; + + /* Looks like a FAT filesystem. Spoof 'i'. */ + lp->d_partitions['i' - 'a'].p_size = + lp->d_partitions[RAW_PART].p_size; + lp->d_partitions['i' - 'a'].p_offset = 0; + lp->d_partitions['i' - 'a'].p_fstype = FS_MSDOS; + } +notfat: + + /* Don't read the on-disk label if we are in spoofed-only mode. */ if (spoofonly) goto done; |