Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Feb 2018 12:57:58 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Allan Jude <allanjude@freebsd.org>
Cc:        freebsd-fs <freebsd-fs@freebsd.org>, Kirk McKusick <mckusick@mckusick.com>, markj@freebsd.org
Subject:   Re: UFS panic when attempting to mount wrong device
Message-ID:  <20180219105758.GX94212@kib.kiev.ua>
In-Reply-To: <8be41fc8-ea0a-da87-da89-68f531f1cb88@freebsd.org>
References:  <8be41fc8-ea0a-da87-da89-68f531f1cb88@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, Feb 18, 2018 at 08:14:48PM -0500, Allan Jude wrote:
> I accidentally forgot to specify -t cd9660 when mounting a CD image, and
> UFS panicked the machine:
> 
> Unread portion of the kernel message buffer:
> panic: vtopde on a uva/gpa 0x0
> cpuid = 1
> KDB: stack backtrace:
> db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame
> 0xfffffe0034409550
> vpanic() at vpanic+0x18d/frame 0xfffffe00344095b0
> vpanic() at vpanic/frame 0xfffffe0034409630
> pmap_kextract() at pmap_kextract+0x121/frame 0xfffffe0034409660
> free() at free+0x5e/frame 0xfffffe00344096a0
> ffs_mount() at ffs_mount+0xe2f/frame 0xfffffe0034409840
> vfs_donmount() at vfs_donmount+0xf56/frame 0xfffffe0034409a80
> sys_nmount() at sys_nmount+0x72/frame 0xfffffe0034409ac0
> amd64_syscall() at amd64_syscall+0x79b/frame 0xfffffe0034409bf0
> fast_syscall_common() at fast_syscall_common+0x101/frame 0x7fffffffd990
> 
> 
> 
> (kgdb) bt
> #0  __curthread () at ./machine/pcpu.h:230
> #1  doadump (textdump=1) at
> /zroot/zfs_zstd/head/sys/kern/kern_shutdown.c:347
> #2  0xffffffff80ac9242 in kern_reboot (howto=260) at
> /zroot/zfs_zstd/head/sys/kern/kern_shutdown.c:416
> #3  0xffffffff80ac980d in vpanic (fmt=<optimized out>,
> ap=0xfffffe00344095f0) at /zroot/zfs_zstd/head/sys/kern/kern_shutdown.c:812
> #4  0xffffffff80ac9620 in kassert_panic (fmt=0xffffffff81157632 "vtopde
> on a uva/gpa 0x%0lx") at /zroot/zfs_zstd/head/sys/kern/kern_shutdown.c:698
> #5  0xffffffff80f683a1 in vtopde (va=0) at
> /zroot/zfs_zstd/head/sys/amd64/amd64/pmap.c:835
> #6  pmap_kextract (va=0) at /zroot/zfs_zstd/head/sys/amd64/amd64/pmap.c:2237
> #7  0xffffffff80aa3f2e in vtoslab (va=0) at
> /zroot/zfs_zstd/head/sys/vm/uma_int.h:455
> #8  free (addr=0x8, mtp=0xffffffff8189bb20 <M_UFSMNT>) at
> /zroot/zfs_zstd/head/sys/kern/kern_malloc.c:701
> #9  0xffffffff80dc278f in ffs_mountfs (devvp=<optimized out>,
> mp=<optimized out>, td=<optimized out>)
>     at /zroot/zfs_zstd/head/sys/ufs/ffs/ffs_vfsops.c:1047
> #10 ffs_mount (mp=0xfffff80085dda000) at
> /zroot/zfs_zstd/head/sys/ufs/ffs/ffs_vfsops.c:531
> #11 0xffffffff80b8ebc6 in vfs_domount_first (td=<optimized out>,
> fspath=0xfffff80003723800 "/mnt", vp=0xfffff80085baf938, vfsp=<optimized
> out>,
>     fsflags=<optimized out>, optlist=<optimized out>) at
> /zroot/zfs_zstd/head/sys/kern/vfs_mount.c:827
> #12 vfs_domount (td=<optimized out>, fstype=<optimized out>,
> fspath=<optimized out>, fsflags=<optimized out>, optlist=<optimized out>)
>     at /zroot/zfs_zstd/head/sys/kern/vfs_mount.c:1117
> #13 vfs_donmount (td=0xfffff800139c6560, fsflags=<optimized out>,
> fsoptions=0xfffff800054d6e00) at
> /zroot/zfs_zstd/head/sys/kern/vfs_mount.c:684
> #14 0xffffffff80b8dc42 in sys_nmount (td=0xfffff800139c6560,
> uap=0xfffff800139c6918) at /zroot/zfs_zstd/head/sys/kern/vfs_mount.c:427
> #15 0xffffffff80f7ed0b in syscallenter (td=0xfffff800139c6560) at
> /zroot/zfs_zstd/head/sys/amd64/amd64/../../kern/subr_syscall.c:134
> #16 amd64_syscall (td=0xfffff800139c6560, traced=0) at
> /zroot/zfs_zstd/head/sys/amd64/amd64/trap.c:935
> #17 0xffffffff80f5a66d in fast_syscall_common () at
> /zroot/zfs_zstd/head/sys/amd64/amd64/exception.S:480
> #18 0x0000000800c78000 in ?? ()
> 
> 
> That that maybe a double free?
More likely, a free of the uninitialized pointer.  Try this.

diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c
index 40db8bf01b1..4e167d98b65 100644
--- a/sys/ufs/ffs/ffs_subr.c
+++ b/sys/ufs/ffs/ffs_subr.c
@@ -174,8 +174,12 @@ ffs_sbget(void *devfd, struct fs **fsp, off_t altsuperblock,
 
 	*fsp = NULL;
 	if (altsuperblock != -1) {
-		if ((ret = readsuper(devfd, fsp, altsuperblock, readfunc)) != 0)
+		if ((ret = readsuper(devfd, fsp, altsuperblock, readfunc))
+		    != 0) {
+			if (*fsp != NULL)
+				(*fsp)->fs_csp = NULL;
 			return (ret);
+		}
 	} else {
 		for (i = 0; sblock_try[i] != -1; i++) {
 			if ((ret = readsuper(devfd, fsp, sblock_try[i],
@@ -183,10 +187,15 @@ ffs_sbget(void *devfd, struct fs **fsp, off_t altsuperblock,
 				break;
 			if (ret == ENOENT)
 				continue;
+			if (*fsp != NULL)
+				(*fsp)->fs_csp = NULL;
 			return (ret);
 		}
-		if (sblock_try[i] == -1)
+		if (sblock_try[i] == -1) {
+			if (*fsp != NULL)
+				(*fsp)->fs_csp = NULL;
 			return (ENOENT);
+		}
 	}
 	/*
 	 * If not filling in summary information, NULL out fs_csp and return.



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