Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 11 Nov 2016 19:37:51 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r308544 - stable/11/sys/fs/msdosfs
Message-ID:  <201611111937.uABJbpOj000332@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Fri Nov 11 19:37:51 2016
New Revision: 308544
URL: https://svnweb.freebsd.org/changeset/base/308544

Log:
  MFC r308024:
  Ensure that cluster allocations never allocate clusters outside the
  volume limits.

Modified:
  stable/11/sys/fs/msdosfs/msdosfs_fat.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/fs/msdosfs/msdosfs_fat.c
==============================================================================
--- stable/11/sys/fs/msdosfs/msdosfs_fat.c	Fri Nov 11 19:35:58 2016	(r308543)
+++ stable/11/sys/fs/msdosfs/msdosfs_fat.c	Fri Nov 11 19:37:51 2016	(r308544)
@@ -382,6 +382,8 @@ usemap_alloc(struct msdosfsmount *pmp, u
 
 	MSDOSFS_ASSERT_MP_LOCKED(pmp);
 
+	KASSERT(cn <= pmp->pm_maxcluster, ("cn too large %lu %lu", cn,
+	    pmp->pm_maxcluster));
 	KASSERT((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0,
 	    ("usemap_alloc on ro msdosfs mount"));
 	KASSERT((pmp->pm_inusemap[cn / N_INUSEBITS] & (1 << (cn % N_INUSEBITS)))
@@ -398,6 +400,9 @@ usemap_free(struct msdosfsmount *pmp, u_
 {
 
 	MSDOSFS_ASSERT_MP_LOCKED(pmp);
+
+	KASSERT(cn <= pmp->pm_maxcluster, ("cn too large %lu %lu", cn,
+	    pmp->pm_maxcluster));
 	KASSERT((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0,
 	    ("usemap_free on ro msdosfs mount"));
 	pmp->pm_freeclustercount++;
@@ -637,6 +642,8 @@ chainlength(struct msdosfsmount *pmp, u_
 
 	MSDOSFS_ASSERT_MP_LOCKED(pmp);
 
+	if (start > pmp->pm_maxcluster)
+		return (0);
 	max_idx = pmp->pm_maxcluster / N_INUSEBITS;
 	idx = start / N_INUSEBITS;
 	start %= N_INUSEBITS;
@@ -644,11 +651,18 @@ chainlength(struct msdosfsmount *pmp, u_
 	map &= ~((1 << start) - 1);
 	if (map) {
 		len = ffs(map) - 1 - start;
-		return (len > count ? count : len);
+		len = MIN(len, count);
+		if (start + len > pmp->pm_maxcluster)
+			len = pmp->pm_maxcluster - start + 1;
+		return (len);
 	}
 	len = N_INUSEBITS - start;
-	if (len >= count)
-		return (count);
+	if (len >= count) {
+		len = count;
+		if (start + len > pmp->pm_maxcluster)
+			len = pmp->pm_maxcluster - start + 1;
+		return (len);
+	}
 	while (++idx <= max_idx) {
 		if (len >= count)
 			break;
@@ -659,7 +673,10 @@ chainlength(struct msdosfsmount *pmp, u_
 		}
 		len += N_INUSEBITS;
 	}
-	return (len > count ? count : len);
+	len = MIN(len, count);
+	if (start + len > pmp->pm_maxcluster)
+		len = pmp->pm_maxcluster - start + 1;
+	return (len);
 }
 
 /*
@@ -918,6 +935,11 @@ fillinusemap(struct msdosfsmount *pmp)
 	}
 	if (bp != NULL)
 		brelse(bp);
+
+	for (cn = pmp->pm_maxcluster + 1; cn < (pmp->pm_maxcluster +
+	    N_INUSEBITS) / N_INUSEBITS; cn++)
+		pmp->pm_inusemap[cn / N_INUSEBITS] |= 1 << (cn % N_INUSEBITS);
+
 	return (0);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611111937.uABJbpOj000332>