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>