Source-Changes-HG archive

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

[src/trunk]: src/sys/fs/msdosfs Validate FAT entries to avoid some panics cau...



details:   https://anonhg.NetBSD.org/src/rev/381af93275b6
branches:  trunk
changeset: 345033:381af93275b6
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Tue May 03 18:17:28 2016 +0000

description:
Validate FAT entries to avoid some panics caused by a corrupted FAT.

Also print FAT write errors when mount is synchronous (-o sync). This
reveals problems caused by a write protected disklabel on sector 1.

diffstat:

 sys/fs/msdosfs/msdosfs_fat.c |  36 +++++++++++++++++++++++++++---------
 1 files changed, 27 insertions(+), 9 deletions(-)

diffs (78 lines):

diff -r 9f771f058013 -r 381af93275b6 sys/fs/msdosfs/msdosfs_fat.c
--- a/sys/fs/msdosfs/msdosfs_fat.c      Tue May 03 18:14:54 2016 +0000
+++ b/sys/fs/msdosfs/msdosfs_fat.c      Tue May 03 18:17:28 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msdosfs_fat.c,v 1.29 2015/03/28 19:24:05 maxv Exp $    */
+/*     $NetBSD: msdosfs_fat.c,v 1.30 2016/05/03 18:17:28 mlelstv Exp $ */
 
 /*-
  * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@@ -52,7 +52,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: msdosfs_fat.c,v 1.29 2015/03/28 19:24:05 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msdosfs_fat.c,v 1.30 2016/05/03 18:17:28 mlelstv Exp $");
 
 /*
  * kernel include files.
@@ -273,6 +273,18 @@
                 */
                if (cn >= (CLUST_RSRVD & pmp->pm_fatmask))
                        goto hiteof;
+
+               /*
+                * Also stop when cluster is not in the filesystem
+                */
+               if (cn < CLUST_FIRST || cn > pmp->pm_maxcluster) {
+                       DPRINTF(("%s(cn, %lu not in %lu..%lu)\n", __func__,
+                               cn, CLUST_FIRST, pmp->pm_maxcluster));
+                       if (bp)
+                               brelse(bp, 0);
+                       return (EINVAL);
+               }
+
                byteoffset = FATOFS(pmp, cn);
                fatblock(pmp, byteoffset, &bn, &bsize, &bo);
                if (bn != bp_bn) {
@@ -383,7 +395,7 @@
 void
 updatefats(struct msdosfsmount *pmp, struct buf *bp, u_long fatbn)
 {
-       int i;
+       int i, error;
        struct buf *bpn;
 
        DPRINTF(("%s(pmp %p, bp %p, fatbn %lu)\n", __func__, pmp, bp, fatbn));
@@ -448,9 +460,12 @@
                        bpn = getblk(pmp->pm_devvp, de_bn2kb(pmp, fatbn),
                            bp->b_bcount, 0, 0);
                        memcpy(bpn->b_data, bp->b_data, bp->b_bcount);
-                       if (pmp->pm_flags & MSDOSFSMNT_WAITONFAT)
-                               bwrite(bpn);
-                       else
+                       if (pmp->pm_flags & MSDOSFSMNT_WAITONFAT) {
+                               error = bwrite(bpn);
+                               if (error)
+                                       printf("%s: copy FAT %d (error=%d)\n",
+                                                __func__, i, error);
+                       } else
                                bdwrite(bpn);
                }
        }
@@ -458,9 +473,12 @@
        /*
         * Write out the first (or current) FAT last.
         */
-       if (pmp->pm_flags & MSDOSFSMNT_WAITONFAT)
-               bwrite(bp);
-       else
+       if (pmp->pm_flags & MSDOSFSMNT_WAITONFAT) {
+               error =  bwrite(bp);
+               if (error)
+                       printf("%s: write FAT (error=%d)\n",
+                               __func__, error);
+       } else
                bdwrite(bp);
        /*
         * Maybe update fsinfo sector here?



Home | Main Index | Thread Index | Old Index