Source-Changes-HG archive

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

[src/trunk]: src/sys/fs/msdosfs Add more sanity checks for BPB parameters. Ha...



details:   https://anonhg.NetBSD.org/src/rev/2743980ea382
branches:  trunk
changeset: 826194:2743980ea382
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Sun Aug 20 11:48:15 2017 +0000

description:
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 0ba6fbe95dcc -r 2743980ea382 sys/fs/msdosfs/msdosfs_vfsops.c
--- a/sys/fs/msdosfs/msdosfs_vfsops.c   Sun Aug 20 11:06:35 2017 +0000
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c   Sun Aug 20 11:48:15 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msdosfs_vfsops.c,v 1.127 2017/04/17 08:32:00 hannken Exp $     */
+/*     $NetBSD: msdosfs_vfsops.c,v 1.128 2017/08/20 11:48:15 mlelstv 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.127 2017/04/17 08:32:00 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.128 2017/08/20 11:48:15 mlelstv Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -467,6 +467,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)
@@ -710,12 +711,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