/*-
 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
 *
 * Copyright (C) 1995, 1997 Wolfgang Solfrank
 * Copyright (c) 1995 Martin Husemann
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: boot.c,v 1.21 2018/02/08 09:05:17 dholland Exp $");
static const char rcsid[] =
  "$FreeBSD$";
#endif /* not lint */

#include <sys/param.h>

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

#include "ext.h"
#include "fsutil.h"

int
readboot(int dosfs, struct bootblock *boot)
{
	u_char block[DOSBOOTBLOCKSIZE];
	u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
	int ret = FSOK;

	if ((size_t)read(dosfs, block, sizeof block) != sizeof block) {
		perr("could not read boot block");
		return FSFATAL;
	}

	if (block[510] != 0x55 || block[511] != 0xaa) {
		pfatal("Invalid signature in boot block: %02x%02x",
		    block[511], block[510]);
		return FSFATAL;
	}

	memset(boot, 0, sizeof *boot);
	boot->ValidFat = -1;

	/* Decode BIOS Parameter Block */

	/* Bytes per sector: can only be  512, 1024, 2048 and 4096. */
	boot->bpbBytesPerSec = block[11] + (block[12] << 8);
	if (boot->bpbBytesPerSec < DOSBOOTBLOCKSIZE_REAL ||
	    boot->bpbBytesPerSec > DOSBOOTBLOCKSIZE ||
	    !powerof2(boot->bpbBytesPerSec)) {
		pfatal("Invalid sector size: %u", boot->bpbBytesPerSec);
		return FSFATAL;
	}

	/* Sectors per cluster: can only be: 1, 2, 4, 8, 16, 32, 64, 128. */
	boot->bpbSecPerClust = block[13];
	if (boot->bpbSecPerClust == 0 || !powerof2(boot->bpbSecPerClust)) {
		pfatal("Invalid cluster size: %u", boot->bpbSecPerClust);
		return FSFATAL;
	}

	/* Reserved sectors: must be non-zero */
	boot->bpbResSectors = block[14] + (block[15] << 8);
	if (boot->bpbResSectors < 1) {
		pfatal("Invalid reserved sectors: %u",
		    boot->bpbResSectors);
		return FSFATAL;
	}

	/* Number of FATs */
	boot->bpbFATs = block[16];
	if (boot->bpbFATs == 0) {
		pfatal("Invalid number of FATs: %u", boot->bpbFATs);
		return FSFATAL;
	}

	/* Root directory entries for FAT12 and FAT16 */
	boot->bpbRootDirEnts = block[17] + (block[18] << 8);
	if (!boot->bpbRootDirEnts) {
		/* bpbRootDirEnts = 0 suggests that we are FAT32 */
		boot->flags |= FAT32;
	}

	/* Total sectors (16 bits) */
	boot->bpbSectors = block[19] + (block[20] << 8);
	if (boot->bpbSectors != 0 && (boot->flags & FAT32)) {
		pfatal("Invalid 16-bit total sector count on FAT32: %u",
		    boot->bpbSectors);
		return FSFATAL;
	}

	/* Media type: ignored */
	boot->bpbMedia = block[21];

	/* FAT12/FAT16: 16-bit count of sectors per FAT */
	boot->bpbFATsmall = block[22] + (block[23] << 8);
	if (boot->bpbFATsmall != 0 && (boot->flags & FAT32)) {
		pfatal("Invalid 16-bit FAT sector count on FAT32: %u",
		    boot->bpbFATsmall);
		return FSFATAL;
	}

	/* Legacy CHS geometry numbers: ignored */
	boot->SecPerTrack = block[24] + (block[25] << 8);
	boot->bpbHeads = block[26] + (block[27] << 8);

	/* Hidden sectors: ignored */
	boot->bpbHiddenSecs = block[28] + (block[29] << 8) +
	    (block[30] << 16) + (block[31] << 24);

	/* Total sectors (32 bits) */
	boot->bpbHugeSectors = block[32] + (block[33] << 8) +
	    (block[34] << 16) + (block[35] << 24);
	if (boot->bpbHugeSectors == 0) {
		if (boot->flags & FAT32) {
			pfatal("FAT32 with sector count of zero");
			return FSFATAL;
		} else if (boot->bpbSectors == 0) {
			pfatal("FAT with sector count of zero");
			return FSFATAL;
		}
		boot->NumSectors = boot->bpbSectors;
	} else {
		if (boot->bpbSectors != 0) {
			pfatal("Invalid FAT sector count");
			return FSFATAL;
		}
		boot->NumSectors = boot->bpbHugeSectors;
	}

	if (boot->flags & FAT32) {
		/* If the OEM Name field is EXFAT, it's not FAT32, so bail */
		if (!memcmp(&block[3], "EXFAT   ", 8)) {
			pfatal("exFAT filesystem is not supported.");
			return FSFATAL;
		}

		/* 32-bit count of sectors per FAT */
		boot->FATsecs = block[36] + (block[37] << 8)
				+ (block[38] << 16) + (block[39] << 24);

		if (block[40] & 0x80)
			boot->ValidFat = block[40] & 0x0f;

		/* FAT32 version, bail out if not 0.0 */
		if (block[42] || block[43]) {
			pfatal("Unknown file system version: %x.%x",
			       block[43], block[42]);
			return FSFATAL;
		}

		/*
		 * Cluster number of the first cluster of root directory.
		 *
		 * Should be 2 but do not require it.
		 */
		boot->bpbRootClust = block[44] + (block[45] << 8)
			       + (block[46] << 16) + (block[47] << 24);

		/* Sector number of the FSInfo structure, usually 1 */
		boot->bpbFSInfo = block[48] + (block[49] << 8);

		/* Sector number of the backup boot block, ignored */
		boot->bpbBackup = block[50] + (block[51] << 8);

		/* Check basic parameters */
		if (boot->bpbFSInfo == 0) {
			/*
			 * Either the BIOS Parameter Block has been corrupted,
			 * or this is not a FAT32 filesystem, most likely an
			 * exFAT filesystem.
			 */
			pfatal("Invalid FAT32 Extended BIOS Parameter Block");
			return FSFATAL;
		}

		/* Read in and verify the FSInfo block */
		if (lseek(dosfs, boot->bpbFSInfo * boot->bpbBytesPerSec,
		    SEEK_SET) != boot->bpbFSInfo * boot->bpbBytesPerSec
		    || read(dosfs, fsinfo, sizeof fsinfo) != sizeof fsinfo) {
			perr("could not read fsinfo block");
			return FSFATAL;
		}
		if (memcmp(fsinfo, "RRaA", 4)
		    || memcmp(fsinfo + 0x1e4, "rrAa", 4)
		    || fsinfo[0x1fc]
		    || fsinfo[0x1fd]
		    || fsinfo[0x1fe] != 0x55
		    || fsinfo[0x1ff] != 0xaa
		    || fsinfo[0x3fc]
		    || fsinfo[0x3fd]
		    || fsinfo[0x3fe] != 0x55
		    || fsinfo[0x3ff] != 0xaa) {
			pwarn("Invalid signature in fsinfo block\n");
			if (ask(0, "Fix")) {
				memcpy(fsinfo, "RRaA", 4);
				memcpy(fsinfo + 0x1e4, "rrAa", 4);
				fsinfo[0x1fc] = fsinfo[0x1fd] = 0;
				fsinfo[0x1fe] = 0x55;
				fsinfo[0x1ff] = 0xaa;
				fsinfo[0x3fc] = fsinfo[0x3fd] = 0;
				fsinfo[0x3fe] = 0x55;
				fsinfo[0x3ff] = 0xaa;
				if (lseek(dosfs, boot->bpbFSInfo *
				    boot->bpbBytesPerSec, SEEK_SET)
				    != boot->bpbFSInfo * boot->bpbBytesPerSec
				    || write(dosfs, fsinfo, sizeof fsinfo)
				    != sizeof fsinfo) {
					perr("Unable to write bpbFSInfo");
					return FSFATAL;
				}
				ret = FSBOOTMOD;
			} else
				boot->bpbFSInfo = 0;
		} else {
			/* We appear to have a valid FSInfo block, decode */
			boot->FSFree = fsinfo[0x1e8] + (fsinfo[0x1e9] << 8)
				       + (fsinfo[0x1ea] << 16)
				       + (fsinfo[0x1eb] << 24);
			boot->FSNext = fsinfo[0x1ec] + (fsinfo[0x1ed] << 8)
				       + (fsinfo[0x1ee] << 16)
				       + (fsinfo[0x1ef] << 24);
		}
	} else {
		/* !FAT32: FAT12/FAT16 */
		boot->FATsecs = boot->bpbFATsmall;
	}

	if (boot->FATsecs < 1 || boot->FATsecs > UINT32_MAX / boot->bpbFATs) {
		pfatal("Invalid FATs(%u) with FATsecs(%zu)",
			boot->bpbFATs, (size_t)boot->FATsecs);
		return FSFATAL;
	}

	boot->FirstCluster = (boot->bpbRootDirEnts * 32 +
	    boot->bpbBytesPerSec - 1) / boot->bpbBytesPerSec +
	    boot->bpbResSectors + boot->bpbFATs * boot->FATsecs;

	if (boot->FirstCluster + boot->bpbSecPerClust > boot->NumSectors) {
		pfatal("Cluster offset too large (%u clusters)\n",
		    boot->FirstCluster);
		return FSFATAL;
	}

	/*
	 * The number of clusters is derived from available data sectors, divided
	 * by sectors per cluster.
	 */
	boot->NumClusters = (boot->NumSectors - boot->FirstCluster) / boot->bpbSecPerClust;

	if (boot->flags & FAT32) {
		if (boot->NumClusters > (CLUST_RSRVD & CLUST32_MASK)) {
			pfatal("Filesystem too big (%u clusters) for FAT32 partition",
			    boot->NumClusters);
			return FSFATAL;
		}
		if (boot->NumClusters < (CLUST_RSRVD & CLUST16_MASK)) {
			pfatal("Filesystem too small (%u clusters) for FAT32 partition",
			    boot->NumClusters);
			return FSFATAL;
		}
		boot->ClustMask = CLUST32_MASK;

		if (boot->bpbRootClust < CLUST_FIRST ||
		    boot->bpbRootClust >= boot->NumClusters) {
			pfatal("Root directory starts with cluster out of range(%u)",
			       boot->bpbRootClust);
			return FSFATAL;
		}
	} else if (boot->NumClusters < (CLUST_RSRVD&CLUST12_MASK)) {
		boot->ClustMask = CLUST12_MASK;
	} else if (boot->NumClusters < (CLUST_RSRVD&CLUST16_MASK)) {
		boot->ClustMask = CLUST16_MASK;
	} else {
		pfatal("Filesystem too big (%u clusters) for non-FAT32 partition",
		       boot->NumClusters);
		return FSFATAL;
	}

	switch (boot->ClustMask) {
	case CLUST32_MASK:
		boot->NumFatEntries = (boot->FATsecs * boot->bpbBytesPerSec) / 4;
		break;
	case CLUST16_MASK:
		boot->NumFatEntries = (boot->FATsecs * boot->bpbBytesPerSec) / 2;
		break;
	default:
		boot->NumFatEntries = (boot->FATsecs * boot->bpbBytesPerSec * 2) / 3;
		break;
	}

	if (boot->NumFatEntries < boot->NumClusters) {
		pfatal("FAT size too small, %u entries won't fit into %u sectors\n",
		       boot->NumClusters, boot->FATsecs);
		return FSFATAL;
	}

	/*
	 * There are two reserved clusters.  To avoid adding CLUST_FIRST every time
	 * when we perform boundary checks, we increment the NumClusters by 2,
	 * which is CLUST_FIRST to denote the first out-of-range cluster number.
	 */
	boot->NumClusters += CLUST_FIRST;

	boot->ClusterSize = boot->bpbBytesPerSec * boot->bpbSecPerClust;

	boot->NumFiles = 1;
	boot->NumFree = 0;

	return ret;
}

int
writefsinfo(int dosfs, struct bootblock *boot)
{
	u_char fsinfo[2 * DOSBOOTBLOCKSIZE];

	if (lseek(dosfs, boot->bpbFSInfo * boot->bpbBytesPerSec, SEEK_SET)
	    != boot->bpbFSInfo * boot->bpbBytesPerSec
	    || read(dosfs, fsinfo, sizeof fsinfo) != sizeof fsinfo) {
		perr("could not read fsinfo block");
		return FSFATAL;
	}
	fsinfo[0x1e8] = (u_char)boot->FSFree;
	fsinfo[0x1e9] = (u_char)(boot->FSFree >> 8);
	fsinfo[0x1ea] = (u_char)(boot->FSFree >> 16);
	fsinfo[0x1eb] = (u_char)(boot->FSFree >> 24);
	fsinfo[0x1ec] = (u_char)boot->FSNext;
	fsinfo[0x1ed] = (u_char)(boot->FSNext >> 8);
	fsinfo[0x1ee] = (u_char)(boot->FSNext >> 16);
	fsinfo[0x1ef] = (u_char)(boot->FSNext >> 24);
	if (lseek(dosfs, boot->bpbFSInfo * boot->bpbBytesPerSec, SEEK_SET)
	    != boot->bpbFSInfo * boot->bpbBytesPerSec
	    || write(dosfs, fsinfo, sizeof fsinfo)
	    != sizeof fsinfo) {
		perr("Unable to write bpbFSInfo");
		return FSFATAL;
	}
	/*
	 * Technically, we should return FSBOOTMOD here.
	 *
	 * However, since Win95 OSR2 (the first M$ OS that has
	 * support for FAT32) doesn't maintain the FSINFO block
	 * correctly, it has to be fixed pretty often.
	 *
	 * Therefore, we handle the FSINFO block only informally,
	 * fixing it if necessary, but otherwise ignoring the
	 * fact that it was incorrect.
	 */
	return 0;
}
