Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-7]: src/sys/fs/msdosfs Pull up following revision(s) (requested b...



details:   https://anonhg.NetBSD.org/src/rev/a518f3f7eae6
branches:  netbsd-7
changeset: 800352:a518f3f7eae6
user:      snj <snj%NetBSD.org@localhost>
date:      Mon Oct 23 19:10:46 2017 +0000

description:
Pull up following revision(s) (requested by mlelstv in ticket #1514):
        sys/fs/msdosfs/msdosfs_vfsops.c: revision 1.128
Add more sanity checks for BPB parameters. Handle FAT12 format for media
with sectors >= 32kByte.
Does fix PR 52485.

diffstat:

 sys/fs/msdosfs/msdosfs_vfsops.c |  41 +++++++++++++++++++++++++++++++++++------
 1 files changed, 35 insertions(+), 6 deletions(-)

diffs (71 lines):

diff -r 2d305b7cce9b -r a518f3f7eae6 sys/fs/msdosfs/msdosfs_vfsops.c
--- a/sys/fs/msdosfs/msdosfs_vfsops.c   Mon Oct 23 19:03:34 2017 +0000
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c   Mon Oct 23 19:10:46 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msdosfs_vfsops.c,v 1.115 2014/07/18 17:24:34 maxv Exp $        */
+/*     $NetBSD: msdosfs_vfsops.c,v 1.115.2.1 2017/10/23 19:10:46 snj Exp $     */
 
 /*-
  * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@@ -48,7 +48,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.115 2014/07/18 17:24:34 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.115.2.1 2017/10/23 19:10:46 snj Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -468,6 +468,7 @@
        int     ronly, error, BlkPerSec;
        uint64_t psize;
        unsigned secsize;
+       u_long fatbytes, fatblocksecs;
 
        /* Flush out any old buffers remaining from a previous use. */
        if ((error = vinvalbuf(devvp, V_SAVE, l->l_cred, l, 0, 0)) != 0)
@@ -695,12 +696,40 @@
                        pmp->pm_fatdiv = 1;
                }
        }
-       if (FAT12(pmp))
-               pmp->pm_fatblocksize = 3 * pmp->pm_BytesPerSec;
-       else
+
+       /* validate cluster count against FAT */
+       if ((pmp->pm_maxcluster & pmp->pm_fatmask) != pmp->pm_maxcluster) {
+               DPRINTF("maxcluster %lu outside of mask %#lx\n",
+                       pmp->pm_maxcluster, pmp->pm_fatmask);
+               error = EINVAL;
+               goto error_exit;
+       }
+
+       /* validate FAT size */
+       fatbytes = (pmp->pm_maxcluster+1) * pmp->pm_fatmult / pmp->pm_fatdiv;
+       fatblocksecs = howmany(fatbytes, pmp->pm_BytesPerSec);
+
+       if (pmp->pm_FATsecs != fatblocksecs) {
+               DPRINTF("FATsecs %lu != real %lu\n", pmp->pm_FATsecs,
+                       fatblocksecs);
+               error = EINVAL;
+               goto error_exit;
+       }
+
+       if (FAT12(pmp)) {
+               /*
+                * limit block size to what is needed to read a FAT block
+                * to not exceed MAXBSIZE
+                */
+               pmp->pm_fatblocksec = min(3, fatblocksecs);
+               pmp->pm_fatblocksize = pmp->pm_fatblocksec
+                       * pmp->pm_BytesPerSec;
+       } else {
                pmp->pm_fatblocksize = MAXBSIZE;
+               pmp->pm_fatblocksec = pmp->pm_fatblocksize
+                       / pmp->pm_BytesPerSec;
+       }
 
-       pmp->pm_fatblocksec = pmp->pm_fatblocksize / pmp->pm_BytesPerSec;
        pmp->pm_bnshift = ffs(pmp->pm_BytesPerSec) - 1;
 
        /*



Home | Main Index | Thread Index | Old Index