UFS panic when attempting to mount wrong device
Allan Jude
allanjude at freebsd.org
Mon Feb 19 18:28:49 UTC 2018
On 2018-02-19 05:57, Konstantin Belousov wrote:
> 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.
>
This first patch solved the panic, but returns the wrong error message:
# mount /dev/cd0 /mnt
mount: /dev/cd0: No such file or directory
It does exist, and `mount -t cd9660 /dev/cd0 /mnt` works
I think we should return EINVAL in this case instead of ENOENT?
--
Allan Jude
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 834 bytes
Desc: OpenPGP digital signature
URL: <http://lists.freebsd.org/pipermail/freebsd-fs/attachments/20180219/1edfcedf/attachment.sig>
More information about the freebsd-fs
mailing list