Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Nov 2014 16:15:17 -0500
From:      Henry Hu <henry.hu.sh@gmail.com>
To:        FreeBSD CURRENT <freebsd-current@freebsd.org>
Subject:   Fatal trap 12 in fuse_vnop_create and patch
Message-ID:  <CAEJt7ha96XDg%2Bxr-gOMXAVNMC-1DDCSjxa1JcE8r_KbrruVMeQ@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
Hi,

I've hit a crash in the fuse module when doing a rsync to an ntfs volume
mounted with ntfs-3g.
The crash is the same as ones reported before, in

https://lists.freebsd.org/pipermail/freebsd-current/2013-October/045993.htm=
l

and there are other similar reports:

http://www.bsdforen.de/threads/probleme-mit-rsync-und-sshfs.29323/

After digging it a bit, I found that the problem is in fuse_vnop_create().
Check
https://github.com/freebsd/freebsd/blame/master/sys/fs/fuse/fuse_vnops.c#L3=
37
.
At line 337, it checks if vap->va_type is VREG, and if it is not, it goes
to label bringup.
Then, feo is assigned with fdip->answ and used. But fdip which points to
fdi is initialized after the goto. As a result, when vap->va_type !=3D VREG=
,
fdi is not initialized and feo is invalid.

I made the following patch and it works for me. In my case, the problematic
file is a socket.

Index: fuse_vnops.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- fuse_vnops.c        (=E7=89=88=E6=9C=AC 274059)
+++ fuse_vnops.c        (=E5=B7=A5=E4=BD=9C=E5=89=AF=E6=9C=AC)
@@ -336,7 +336,8 @@
        /* XXX: Will we ever want devices ? */
        if ((vap->va_type !=3D VREG)) {
                MPASS(vap->va_type !=3D VFIFO);
-               goto bringup;
+               printf("unsupported vatype: %d\n", vap->va_type);
+               return EINVAL;
        }
        debug_printf("parent nid =3D %ju, mode =3D %x\n", (uintmax_t)parent=
nid,
            mode);
@@ -364,7 +365,7 @@
                debug_printf("create: got err=3D%d from daemon\n", err);
                goto out;
        }
-bringup:
+
        feo =3D fdip->answ;

        if ((err =3D fuse_internal_checkentry(feo, VREG))) {

But I think that fuse filesystems may support file types other than VREG,
so maybe we should remove that check completely?

--=20
Cheers,
Henry



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAEJt7ha96XDg%2Bxr-gOMXAVNMC-1DDCSjxa1JcE8r_KbrruVMeQ>