Source-Changes-HG archive

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

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



details:   https://anonhg.NetBSD.org/src/rev/1de496700cf1
branches:  netbsd-6
changeset: 776776:1de496700cf1
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Sun Nov 09 06:37:00 2014 +0000

description:
Pull up following revision(s) (requested by maxv in ticket #1171):
        sys/fs/msdosfs/msdosfs_vfsops.c: revision 1.110 via patch
- From me, FreeBSD, OpenBSD and the FAT specification. Ok christos@
  - Perform sanity checks not just for GEMDOSFS, but for all FAT devices. This
    also fixes a division-by-zero bug that could crash the system.
  - Define GEMDOSFS_BSIZE instead of a hard-coded 512 value, and remove 'bsize'.
  - Rename 'tmp' to 'BlkPerSec'.
- Remove 'secsize==0' and added 'secsize<DEV_BSIZE'

diffstat:

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

diffs (167 lines):

diff -r 01d3c1169032 -r 1de496700cf1 sys/fs/msdosfs/msdosfs_vfsops.c
--- a/sys/fs/msdosfs/msdosfs_vfsops.c   Sun Nov 09 06:29:22 2014 +0000
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c   Sun Nov 09 06:37:00 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msdosfs_vfsops.c,v 1.93.6.2 2014/04/21 10:14:19 bouyer Exp $   */
+/*     $NetBSD: msdosfs_vfsops.c,v 1.93.6.3 2014/11/09 06:37:00 msaitoh 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.93.6.2 2014/04/21 10:14:19 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.93.6.3 2014/11/09 06:37:00 msaitoh Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -93,6 +93,8 @@
 #define DPRINTF(a)
 #endif
 
+#define GEMDOSFS_BSIZE 512
+
 #define MSDOSFS_NAMEMAX(pmp) \
        (pmp)->pm_flags & MSDOSFSMNT_LONGNAME ? WIN_MAXLEN : 12
 
@@ -474,8 +476,7 @@
        struct byte_bpb50 *b50;
        struct byte_bpb710 *b710;
        uint8_t SecPerClust;
-       int     ronly, error, tmp;
-       int     bsize;
+       int     ronly, error, BlkPerSec;
        uint64_t psize;
        unsigned secsize;
 
@@ -493,7 +494,7 @@
                goto error_exit;
 
        error = getdisksize(devvp, &psize, &secsize);
-       if (error || secsize == 0) {
+       if (error) {
                if (argp->flags & MSDOSFSMNT_GEMDOSFS)
                        goto error_exit;
 
@@ -502,16 +503,19 @@
                psize = 0;
                error = 0;
        }
+       if (secsize < DEV_BSIZE) {
+               DPRINTF(("Invalid block secsize (%d < DEV_BSIZE)", secsize));
+               error = EINVAL;
+               goto error_exit;
+       }
 
        if (argp->flags & MSDOSFSMNT_GEMDOSFS) {
-               bsize = secsize;
-               if (bsize != 512) {
-                       DPRINTF(("Invalid block bsize %d for gemdos\n", bsize));
+               if (secsize != GEMDOSFS_BSIZE) {
+                       DPRINTF(("Invalid block secsize %d for GEMDOS\n", secsize));
                        error = EINVAL;
                        goto error_exit;
                }
-       } else
-               bsize = 0;
+       }
 
        /*
         * Read the boot sector of the filesystem, and then check the
@@ -555,19 +559,6 @@
        pmp->pm_Heads = getushort(b50->bpbHeads);
        pmp->pm_Media = b50->bpbMedia;
 
-       if (!(argp->flags & MSDOSFSMNT_GEMDOSFS)) {
-               /* XXX - We should probably check more values here */
-               if (!pmp->pm_BytesPerSec || !SecPerClust
-                       || pmp->pm_SecPerTrack > 63) {
-                       DPRINTF(("bytespersec %d secperclust %d "
-                           "secpertrack %d\n", 
-                           pmp->pm_BytesPerSec, SecPerClust,
-                           pmp->pm_SecPerTrack));
-                       error = EINVAL;
-                       goto error_exit;
-               }
-       }
-
        if (pmp->pm_Sectors == 0) {
                pmp->pm_HiddenSects = getulong(b50->bpbHiddenSecs);
                pmp->pm_HugeSectors = getulong(b50->bpbHugeSectors);
@@ -576,6 +567,29 @@
                pmp->pm_HugeSectors = pmp->pm_Sectors;
        }
 
+       /*
+        * Sanity checks, from the FAT specification:
+        * - sectors per cluster: >= 1, power of 2
+        * - logical sector size: >= 1, power of 2
+        * - cluster size:        <= max FS block size
+        * - number of sectors:   >= 1
+        */
+       if ((SecPerClust == 0) || !powerof2(SecPerClust) ||
+           (pmp->pm_BytesPerSec == 0) || !powerof2(pmp->pm_BytesPerSec) ||
+           (SecPerClust * pmp->pm_BytesPerSec > MAXBSIZE) ||
+           (pmp->pm_HugeSectors == 0)) {
+               DPRINTF(("consistency checks\n"));
+               error = EINVAL;
+               goto error_exit;
+       }
+
+       if (!(argp->flags & MSDOSFSMNT_GEMDOSFS) &&
+           (pmp->pm_SecPerTrack > 63)) {
+               DPRINTF(("SecPerTrack %d\n", pmp->pm_SecPerTrack));
+               error = EINVAL;
+               goto error_exit;
+       }
+
        if (pmp->pm_RootDirEnts == 0) {
                unsigned short vers = getushort(b710->bpbFSVers);
                /*
@@ -614,17 +628,12 @@
 
                /*
                 * Check a few values (could do some more):
-                * - logical sector size: power of 2, >= block size
-                * - sectors per cluster: power of 2, >= 1
-                * - number of sectors:   >= 1, <= size of partition
+                * - logical sector size: >= block size
+                * - number of sectors:   <= size of partition
                 */
-               if ( (SecPerClust == 0)
-                 || (SecPerClust & (SecPerClust - 1))
-                 || (pmp->pm_BytesPerSec < bsize)
-                 || (pmp->pm_BytesPerSec & (pmp->pm_BytesPerSec - 1))
-                 || (pmp->pm_HugeSectors == 0)
-                 || (pmp->pm_HugeSectors * (pmp->pm_BytesPerSec / bsize)
-                     > psize)) {
+               if ((pmp->pm_BytesPerSec < GEMDOSFS_BSIZE) ||
+                   (pmp->pm_HugeSectors *
+                    (pmp->pm_BytesPerSec / GEMDOSFS_BSIZE) > psize)) {
                        DPRINTF(("consistency checks for gemdos\n"));
                        error = EINVAL;
                        goto error_exit;
@@ -635,14 +644,14 @@
                 * always be the same as the number of bytes per disk block
                 * Let's pretend it is.
                 */
-               tmp = pmp->pm_BytesPerSec / bsize;
-               pmp->pm_BytesPerSec  = bsize;
-               pmp->pm_HugeSectors *= tmp;
-               pmp->pm_HiddenSects *= tmp;
-               pmp->pm_ResSectors  *= tmp;
-               pmp->pm_Sectors     *= tmp;
-               pmp->pm_FATsecs     *= tmp;
-               SecPerClust         *= tmp;
+               BlkPerSec = pmp->pm_BytesPerSec / GEMDOSFS_BSIZE;
+               pmp->pm_BytesPerSec  = GEMDOSFS_BSIZE;
+               pmp->pm_HugeSectors *= BlkPerSec;
+               pmp->pm_HiddenSects *= BlkPerSec;
+               pmp->pm_ResSectors  *= BlkPerSec;
+               pmp->pm_Sectors     *= BlkPerSec;
+               pmp->pm_FATsecs     *= BlkPerSec;
+               SecPerClust         *= BlkPerSec;
        }
 
        /* Check that fs has nonzero FAT size */



Home | Main Index | Thread Index | Old Index