Module Name:    src
Committed By:   mlelstv
Date:           Sat Apr 23 22:40:28 UTC 2022

Modified Files:
        src/sbin/fsck_msdos: boot.c

Log Message:
Support large disk sectors.


To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/sbin/fsck_msdos/boot.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sbin/fsck_msdos/boot.c
diff -u src/sbin/fsck_msdos/boot.c:1.23 src/sbin/fsck_msdos/boot.c:1.24
--- src/sbin/fsck_msdos/boot.c:1.23	Sat Feb 22 09:59:22 2020
+++ src/sbin/fsck_msdos/boot.c	Sat Apr 23 22:40:28 2022
@@ -27,7 +27,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: boot.c,v 1.23 2020/02/22 09:59:22 kamil Exp $");
+__RCSID("$NetBSD: boot.c,v 1.24 2022/04/23 22:40:28 mlelstv Exp $");
 #endif /* not lint */
 
 #include <stdlib.h>
@@ -36,6 +36,8 @@ __RCSID("$NetBSD: boot.c,v 1.23 2020/02/
 #include <inttypes.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/dkio.h>
 
 #include "ext.h"
 #include "fsutil.h"
@@ -43,19 +45,34 @@ __RCSID("$NetBSD: boot.c,v 1.23 2020/02/
 int
 readboot(int dosfs, struct bootblock *boot)
 {
-	u_char block[DOSBOOTBLOCKSIZE];
-	u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
-	u_char backup[DOSBOOTBLOCKSIZE];
+	u_char *block;
+	u_char *fsinfo;
+	u_char *backup;
 	int ret = FSOK;
-	int i;
+	int i, err;
+	u_int secsize;
+
+	secsize = 0;
+	err = ioctl(dosfs, DIOCGSECTORSIZE, &secsize);
+	if (err != 0 || secsize == 0)
+		secsize = DOSBOOTBLOCKSIZE;
+
+	if (secsize < DOSBOOTBLOCKSIZE)
+		pfatal("Invalid sector size %u\n", secsize);
+
+	block = calloc(1, secsize);
+	if (block == NULL)
+		pfatal("Out of memory");
 	
-	if ((size_t)read(dosfs, block, sizeof block) != sizeof block) {
+	if ((size_t)read(dosfs, block, secsize) != secsize) {
 		perr("could not read boot block");
+		free(block);
 		return FSFATAL;
 	}
 
 	if (block[510] != 0x55 || block[511] != 0xaa) {
 		pfatal("Invalid signature in boot block: %02x%02x", block[511], block[510]);
+		free(block);
 		return FSFATAL;
 	}
 
@@ -86,6 +103,13 @@ readboot(int dosfs, struct bootblock *bo
 
 	boot->FATsecs = boot->FATsmall;
 
+	fsinfo = calloc(2, secsize);
+	if (fsinfo == NULL)
+		pfatal("Out of memory");
+	backup = calloc(1, secsize);
+	if (backup == NULL)
+		pfatal("Out of memory");
+
 	if (!boot->RootDirEnts)
 		boot->flags |= FAT32;
 	if (boot->flags & FAT32) {
@@ -108,8 +132,7 @@ readboot(int dosfs, struct bootblock *bo
 
 		if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
 		    != boot->FSInfo * boot->BytesPerSec
-		    || read(dosfs, fsinfo, sizeof fsinfo)
-		    != sizeof fsinfo) {
+		    || read(dosfs, fsinfo, 2 * secsize) != 2 * secsize) {
 			perr("could not read fsinfo block");
 			return FSFATAL;
 		}
@@ -138,6 +161,9 @@ readboot(int dosfs, struct bootblock *bo
 				    || write(dosfs, fsinfo, sizeof fsinfo)
 				    != sizeof fsinfo) {
 					perr("Unable to write FSInfo");
+					free(fsinfo);
+					free(backup);
+					free(block);
 					return FSFATAL;
 				}
 				ret = FSBOOTMOD;
@@ -155,8 +181,11 @@ readboot(int dosfs, struct bootblock *bo
 
 		if (lseek(dosfs, boot->Backup * boot->BytesPerSec, SEEK_SET)
 		    != boot->Backup * boot->BytesPerSec
-		    || read(dosfs, backup, sizeof backup) != sizeof  backup) {
+		    || read(dosfs, backup, secsize) != secsize) {
 			perr("could not read backup bootblock");
+			free(fsinfo);
+			free(backup);
+			free(block);
 			return FSFATAL;
 		}
 		backup[65] = block[65];				/* XXX */
@@ -180,6 +209,11 @@ readboot(int dosfs, struct bootblock *bo
 		}
 		/* Check backup FSInfo?					XXX */
 	}
+
+	free(fsinfo);
+	free(backup);
+	free(block);
+
 	if (boot->FATsecs == 0) {
 		pfatal("Invalid number of FAT sectors: %u\n", boot->FATsecs);
 		return FSFATAL;
@@ -265,12 +299,17 @@ readboot(int dosfs, struct bootblock *bo
 int
 writefsinfo(int dosfs, struct bootblock *boot)
 {
-	u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
+	u_char *fsinfo;
+
+	fsinfo = calloc(2, boot->BytesPerSec);
+	if (fsinfo == NULL)
+		pfatal("Out of memory");
 
 	if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
 	    != boot->FSInfo * boot->BytesPerSec
-	    || read(dosfs, fsinfo, sizeof fsinfo) != sizeof fsinfo) {
+	    || read(dosfs, fsinfo, 2 * boot->BytesPerSec) != 2 * boot->BytesPerSec) {
 		perr("could not read fsinfo block");
+		free(fsinfo);
 		return FSFATAL;
 	}
 	fsinfo[0x1e8] = (u_char)boot->FSFree;
@@ -283,11 +322,14 @@ writefsinfo(int dosfs, struct bootblock 
 	fsinfo[0x1ef] = (u_char)(boot->FSNext >> 24);
 	if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
 	    != boot->FSInfo * boot->BytesPerSec
-	    || write(dosfs, fsinfo, sizeof fsinfo)
-	    != sizeof fsinfo) {
+	    || write(dosfs, fsinfo, 2 * boot->BytesPerSec) != 2 * boot->BytesPerSec) {
 		perr("Unable to write FSInfo");
+		free(fsinfo);
 		return FSFATAL;
 	}
+
+	free(fsinfo);
+
 	/*
 	 * Technically, we should return FSBOOTMOD here.
 	 *

Reply via email to