DF-3027 / fix.diff
--- a/sys/vfs/fuse/fuse_vnops.c +++ b/sys/vfs/fuse/fuse_vnops.c @@ -309,11 +309,21 @@ struct fuse_attr_out *fao; int error; - if (fuse_test_dead(fmp)) + /* + * DF-3027: always fill in *a_vap on success; callers (vn_stat) + * use an uninitialized vattr and copy it to userland otherwise. + */ + if (fuse_test_dead(fmp)) { + memset(vap, 0, sizeof(*vap)); + vap->va_type = vp->v_type; return 0; - - if (fuse_test_nosys(fmp, FUSE_GETATTR)) + } + + if (fuse_test_nosys(fmp, FUSE_GETATTR)) { + memset(vap, 0, sizeof(*vap)); + vap->va_type = vp->v_type; return 0; + } if (fnp->attrgood == 0) { /* @@ -328,8 +338,12 @@ #endif error = fuse_ipc_tx(fip); if (error) { - if (error == ENOSYS) + if (error == ENOSYS) { + /* DF-3027: no success with uninit vattr */ + memset(vap, 0, sizeof(*vap)); + vap->va_type = vp->v_type; error = 0; + } if (error == ENOTCONN && (vp->v_flag & VROOT)) { memset(vap, 0, sizeof(*vap)); vap->va_type = vp->v_type; |