Re: UFS s_maxbytes bogosity

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Jun 04, 2017 at 06:32:49PM -0400, Theodore Ts'o wrote:
> On Sun, Jun 04, 2017 at 10:58:38PM +0100, Al Viro wrote:
> > 
> > ought to calculate the right thing for modern UFS variants; I would
> > leave the anything other than UFS_MOUNT_UFSTYPE_44BSD and
> > UFS_MOUNT_UFSTYPE_UFS2 alone.
> 
> If anyone wants to spend time worrying about ancient UFS
> incompatilities, or wants to find someone who might care, there's the
> The Unix Heritage Society mailing list[1].  (Don't bother trying to
> post the list without subscribing first, the list is run even more
> strictly than DaveM, and postings from people who aren't subscribers
> get unceremoniously dropped on the floor.)
> 
> [1] http://minnie.tuhs.org/mailman/listinfo/tuhs
> 
> Among other things, recents discussion on this list discuss security
> vulnerabilities (stack buffer overruns, et.al) on V6 and V7 Unix, and
> there are people on that list who will bring up historical versions of
> Unix on emulators, et. al.
> 
> More seriously, many of UFS variants don't have any way of
> distinguishing between what version they are, or are safe to mount on
> which version of Unix.  There's a reason why ext2/3/4 has rather
> feature compatibility masks; UFS demonstrated the joys of what happens
> when you don't bother with that kind of compatibility markers in file
> systems.  So focusing just on what FreeBSD and other modern BSD
> implementation use is a completely fair thing to do.  The enthusiasts
> on TUHS are perfectly capable of sending patches if they care about V6
> Unix <-> Linux compatibility.  :-)

FFS and derivatives postdate v7, let alone v6, as you bloody well know ;-)
Anyway, there are two issues - access on Linux not getting unhappy and
*BSD kernels being OK with created huge files.

After rereading that code, for UFS2 the function I'd posted would do the
right thing; for UFS1 there's an additional complication - on-disk
ui_blocks (in units of 512 bytes) being only 32bit.  So for UFS1 we need
to make sure we won't overflow that thing, making for hard limit a bit
below 2^41 bytes, in addition to the limit imposed by the tree structure.

How about this:

diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 131b2b77c818..eefa48499a6e 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -746,6 +746,23 @@ static void ufs_put_super(struct super_block *sb)
 	return;
 }
 
+static u64 ufs_max_bytes(struct super_block *sb)
+{
+	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
+	int bits = uspi->s_apbshift;
+	u64 res;
+
+	if (bits > 21)
+		res = ~0ULL;
+	else
+		res = UFS_NDADDR + (1LL << bits) + (1LL << (2*bits)) +
+			(1LL << (3*bits));
+
+	if (res >= (MAX_LFS_FILESIZE >> uspi->s_bshift))
+		return MAX_LFS_FILESIZE;
+	return res << uspi->s_bshift;
+}
+
 static int ufs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct ufs_sb_info * sbi;
@@ -823,6 +840,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
 		uspi->s_fshift = 9;
 		uspi->s_sbsize = super_block_size = 1536;
 		uspi->s_sbbase = 0;
+		sb->s_maxbytes = min(ufs_max_bytes(sb),1ULL<<40);
 		flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
 		break;
 	case UFS_MOUNT_UFSTYPE_UFS2:
@@ -833,6 +851,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
 		uspi->s_fshift = 9;
 		uspi->s_sbsize = super_block_size = 1536;
 		uspi->s_sbbase =  0;
+		sb->s_maxbytes = ufs_max_bytes(sb);
 		flags |= UFS_TYPE_UFS2 | UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
 		break;
 		



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux