Module Name:    src
Committed By:   tls
Date:           Sun Aug 10 06:52:54 UTC 2014

Modified Files:
        src/sbin/fsck_msdos [tls-earlyentropy]: boot.c check.c dir.c fat.c

Log Message:
Rebase.


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.15.22.1 src/sbin/fsck_msdos/boot.c
cvs rdiff -u -r1.18 -r1.18.22.1 src/sbin/fsck_msdos/check.c
cvs rdiff -u -r1.25 -r1.25.20.1 src/sbin/fsck_msdos/dir.c
cvs rdiff -u -r1.24 -r1.24.6.1 src/sbin/fsck_msdos/fat.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.15 src/sbin/fsck_msdos/boot.c:1.15.22.1
--- src/sbin/fsck_msdos/boot.c:1.15	Sat Apr 11 07:14:50 2009
+++ src/sbin/fsck_msdos/boot.c	Sun Aug 10 06:52:54 2014
@@ -1,4 +1,3 @@
-/*	$NetBSD: boot.c,v 1.15 2009/04/11 07:14:50 lukem Exp $	*/
 
 /*
  * Copyright (C) 1995, 1997 Wolfgang Solfrank
@@ -28,11 +27,12 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: boot.c,v 1.15 2009/04/11 07:14:50 lukem Exp $");
+__RCSID("$NetBSD: boot.c,v 1.15.22.1 2014/08/10 06:52:54 tls Exp $");
 #endif /* not lint */
 
 #include <stdlib.h>
 #include <string.h>
+#include <strings.h>
 #include <stdio.h>
 #include <unistd.h>
 
@@ -64,8 +64,16 @@ readboot(int dosfs, struct bootblock *bo
 	/* decode bios parameter block */
 	boot->BytesPerSec = block[11] + (block[12] << 8);
 	boot->SecPerClust = block[13];
+	if (boot->SecPerClust == 0 || popcount(boot->SecPerClust) != 1) {
+ 		pfatal("Invalid cluster size: %u\n", boot->SecPerClust);
+		return FSFATAL;
+	}
 	boot->ResSectors = block[14] + (block[15] << 8);
 	boot->FATs = block[16];
+	if (boot->FATs == 0) {
+		pfatal("Invalid number of FATs: %u\n", boot->FATs);
+		return FSFATAL;
+	}
 	boot->RootDirEnts = block[17] + (block[18] << 8);
 	boot->Sectors = block[19] + (block[20] << 8);
 	boot->Media = block[21];
@@ -171,6 +179,10 @@ readboot(int dosfs, struct bootblock *bo
 		}
 		/* Check backup FSInfo?					XXX */
 	}
+	if (boot->FATsecs == 0) {
+		pfatal("Invalid number of FAT sectors: %u\n", boot->FATsecs);
+		return FSFATAL;
+	}
 
 	boot->ClusterOffset = (boot->RootDirEnts * 32 + boot->BytesPerSec - 1)
 	    / boot->BytesPerSec
@@ -193,6 +205,12 @@ readboot(int dosfs, struct bootblock *bo
 		boot->NumSectors = boot->HugeSectors;
 	boot->NumClusters = (boot->NumSectors - boot->ClusterOffset) / boot->SecPerClust;
 
+	if (boot->ClusterOffset > boot->NumSectors) {
+		pfatal("Cluster offset too large (%u clusters)\n",
+		    boot->ClusterOffset);
+		return FSFATAL;
+	}
+
 	if (boot->flags&FAT32)
 		boot->ClustMask = CLUST32_MASK;
 	else if (boot->NumClusters < (CLUST_RSRVD&CLUST12_MASK))

Index: src/sbin/fsck_msdos/check.c
diff -u src/sbin/fsck_msdos/check.c:1.18 src/sbin/fsck_msdos/check.c:1.18.22.1
--- src/sbin/fsck_msdos/check.c:1.18	Sat Apr 11 07:14:50 2009
+++ src/sbin/fsck_msdos/check.c	Sun Aug 10 06:52:54 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: check.c,v 1.18 2009/04/11 07:14:50 lukem Exp $	*/
+/*	$NetBSD: check.c,v 1.18.22.1 2014/08/10 06:52:54 tls Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: check.c,v 1.18 2009/04/11 07:14:50 lukem Exp $");
+__RCSID("$NetBSD: check.c,v 1.18.22.1 2014/08/10 06:52:54 tls Exp $");
 #endif /* not lint */
 
 #include <stdlib.h>
@@ -135,7 +135,7 @@ checkfilesys(const char *filename)
 		goto out;
 
 	/* now write the FATs */
-	if (mod & FSFATMOD) {
+	if (mod & (FSFATMOD|FSFIXFAT)) {
 		if (ask(1, "Update FATs")) {
 			mod |= writefat(dosfs, &boot, fat, mod & FSFIXFAT);
 			if (mod & FSFATAL)

Index: src/sbin/fsck_msdos/dir.c
diff -u src/sbin/fsck_msdos/dir.c:1.25 src/sbin/fsck_msdos/dir.c:1.25.20.1
--- src/sbin/fsck_msdos/dir.c:1.25	Sun Feb 20 21:42:50 2011
+++ src/sbin/fsck_msdos/dir.c	Sun Aug 10 06:52:54 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: dir.c,v 1.25 2011/02/20 21:42:50 christos Exp $	*/
+/*	$NetBSD: dir.c,v 1.25.20.1 2014/08/10 06:52:54 tls Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank
@@ -30,7 +30,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: dir.c,v 1.25 2011/02/20 21:42:50 christos Exp $");
+__RCSID("$NetBSD: dir.c,v 1.25.20.1 2014/08/10 06:52:54 tls Exp $");
 #endif /* not lint */
 
 #include <stdio.h>
@@ -420,12 +420,14 @@ checksize(struct bootblock *boot, struct
 		      fullpath(dir));
 		if (ask(1, "Drop superfluous clusters")) {
 			cl_t cl;
-			u_int32_t sz = 0;
+			u_int32_t sz, len;
 
-			for (cl = dir->head; (sz += boot->ClusterSize) < dir->size;)
+			for (cl = dir->head, len = sz = 0;
+			    (sz += boot->ClusterSize) < dir->size; len++)
 				cl = fat[cl].next;
 			clearchain(boot, fat, fat[cl].next);
 			fat[cl].next = CLUST_EOF;
+			fat[dir->head].length = len;
 			return FSFATMOD;
 		} else
 			return FSERROR;

Index: src/sbin/fsck_msdos/fat.c
diff -u src/sbin/fsck_msdos/fat.c:1.24 src/sbin/fsck_msdos/fat.c:1.24.6.1
--- src/sbin/fsck_msdos/fat.c:1.24	Thu Jan 17 16:45:48 2013
+++ src/sbin/fsck_msdos/fat.c	Sun Aug 10 06:52:54 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: fat.c,v 1.24 2013/01/17 16:45:48 jakllsch Exp $	*/
+/*	$NetBSD: fat.c,v 1.24.6.1 2014/08/10 06:52:54 tls Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: fat.c,v 1.24 2013/01/17 16:45:48 jakllsch Exp $");
+__RCSID("$NetBSD: fat.c,v 1.24.6.1 2014/08/10 06:52:54 tls Exp $");
 #endif /* not lint */
 
 #include <stdlib.h>
@@ -355,7 +355,15 @@ tryclear(struct bootblock *boot, struct 
 		clearchain(boot, fat, head);
 		return FSFATMOD;
 	} else if (ask(0, "Truncate")) {
+		uint32_t len;
+		cl_t p;
+
+		for (p = head, len = 0;
+		    p >= CLUST_FIRST && p < boot->NumClusters;
+		    p = fat[p].next, len++)
+			continue;
 		*truncp = CLUST_EOF;
+		fat[head].length = len;
 		return FSFATMOD;
 	} else
 		return FSERROR;
@@ -384,7 +392,8 @@ checkfat(struct bootblock *boot, struct 
 
 		/* follow the chain and mark all clusters on the way */
 		for (len = 0, p = head;
-		     p >= CLUST_FIRST && p < boot->NumClusters;
+		     p >= CLUST_FIRST && p < boot->NumClusters &&
+		     fat[p].head != head;
 		     p = fat[p].next) {
 			fat[p].head = head;
 			len++;
@@ -405,10 +414,10 @@ checkfat(struct bootblock *boot, struct 
 			continue;
 
 		/* follow the chain to its end (hopefully) */
-		for (p = head;
+		for (len = fat[head].length, p = head;
 		     (n = fat[p].next) >= CLUST_FIRST && n < boot->NumClusters;
 		     p = n)
-			if (fat[n].head != head)
+			if (fat[n].head != head || len-- < 2)
 				break;
 		if (n >= CLUST_EOFS)
 			continue;
@@ -416,14 +425,20 @@ checkfat(struct bootblock *boot, struct 
 		if (n == CLUST_FREE || n >= CLUST_RSRVD) {
 			pwarn("Cluster chain starting at %u ends with cluster marked %s\n",
 			      head, rsrvdcltype(n));
+clear:
 			ret |= tryclear(boot, fat, head, &fat[p].next);
 			continue;
 		}
 		if (n < CLUST_FIRST || n >= boot->NumClusters) {
 			pwarn("Cluster chain starting at %u ends with cluster out of range (%u)\n",
-			      head, n);
-			ret |= tryclear(boot, fat, head, &fat[p].next);
-			continue;
+			    head, n);
+			goto clear;
+		}
+		if (head == fat[n].head) {
+			pwarn("Cluster chain starting at %u loops at cluster %u\n",
+			
+			    head, p);
+			goto clear;
 		}
 		pwarn("Cluster chains starting at %u and %u are linked at cluster %u\n",
 		      head, fat[n].head, n);
@@ -540,13 +555,15 @@ writefat(int fs, struct bootblock *boot,
 		default:
 			if (fat[cl].next == CLUST_FREE)
 				boot->NumFree++;
-			if (cl + 1 < boot->NumClusters
-			    && fat[cl + 1].next == CLUST_FREE)
-				boot->NumFree++;
 			*p++ = (u_char)fat[cl].next;
-			*p++ = (u_char)((fat[cl].next >> 8) & 0xf)
-			       |(u_char)(fat[cl+1].next << 4);
-			*p++ = (u_char)(fat[++cl].next >> 4);
+			*p = (u_char)((fat[cl].next >> 8) & 0xf);
+			cl++;
+			if (cl >= boot->NumClusters)
+				break;
+			if (fat[cl].next == CLUST_FREE)
+				boot->NumFree++;
+			*p++ |= (u_char)(fat[cl + 1].next << 4);
+			*p++ = (u_char)(fat[cl + 1].next >> 4);
 			break;
 		}
 	}

Reply via email to